commit f1406d4eec8fc6c614d02aaee5609c27025bf335 Author: Moe Date: Thu Jun 7 23:21:38 2018 -0700 Shinobi CE officially lands on Gitlab diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..74b6b65 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules +videos +events +frames +web.old +.DS_Store +.vagrant +conf.json +super.json +dbdata +npm-debug.log +shinobi.sqlite \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..5af8981 --- /dev/null +++ b/.npmignore @@ -0,0 +1,2 @@ +node_modules +conf.json \ No newline at end of file diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..20d40b6 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/INSTALL/.gitignore b/INSTALL/.gitignore new file mode 100644 index 0000000..bc56e1f --- /dev/null +++ b/INSTALL/.gitignore @@ -0,0 +1 @@ +installed.txt \ No newline at end of file diff --git a/INSTALL/README.md b/INSTALL/README.md new file mode 100644 index 0000000..d59d017 --- /dev/null +++ b/INSTALL/README.md @@ -0,0 +1,17 @@ +#### Fast Install (The Ninja Way) + +1. Become `root` to use the installer and run Shinobi. Use one of the following to do so. + + - Ubuntu 17.04, 17.10 + - `sudo su` + - CentOS 7 + - `su` + - MacOS 10.7(+) + - `su` +2. Download and run the installer. + +``` +bash <(curl -s https://raw.githubusercontent.com/ShinobiCCTV/Shinobi-Installer/master/shinobi-install.sh) +``` + +More info can be found here. https://shinobi.video/docs/start \ No newline at end of file diff --git a/INSTALL/autoinstall-ubuntu-latest.sh b/INSTALL/autoinstall-ubuntu-latest.sh new file mode 100644 index 0000000..0ae4853 --- /dev/null +++ b/INSTALL/autoinstall-ubuntu-latest.sh @@ -0,0 +1,5 @@ +apt install git -y +git clone https://github.com/ShinobiCCTV/Shinobi.git -b dev Shinobi-dev +cd Shinobi-dev +chmod +x INSTALL/ubuntu-easyinstall.sh && INSTALL/ubuntu-easyinstall.sh +bash INSTALL/ubuntu-easyinstall.sh \ No newline at end of file diff --git a/INSTALL/autoinstall-ubuntu-stable.sh b/INSTALL/autoinstall-ubuntu-stable.sh new file mode 100644 index 0000000..6dc12bd --- /dev/null +++ b/INSTALL/autoinstall-ubuntu-stable.sh @@ -0,0 +1,5 @@ +apt install git -y +git clone https://github.com/ShinobiCCTV/Shinobi.git Shinobi +cd Shinobi +chmod +x INSTALL/ubuntu-easyinstall.sh && INSTALL/ubuntu-easyinstall.sh +bash INSTALL/ubuntu-easyinstall.sh \ No newline at end of file diff --git a/INSTALL/centos.sh b/INSTALL/centos.sh new file mode 100644 index 0000000..d122554 --- /dev/null +++ b/INSTALL/centos.sh @@ -0,0 +1,188 @@ +#!/bin/bash +echo "=========================================================" +echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!==" +echo "=========================================================" +echo "To answer yes type the letter (y) in lowercase and press ENTER." +echo "Default is no (N). Skip any components you already have or don't need." +echo "=============" +if [ ! -e "./conf.json" ]; then + cp conf.sample.json conf.json +fi +if [ ! -e "./super.json" ]; then + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + sudo cp super.sample.json super.json + echo "Shinobi - Do you want to enable superuser access?" + echo "This may be useful if passwords are forgotten or" + echo "if you would like to limit accessibility of an" + echo "account for business scenarios." + echo "(y)es or (N)o" + read createSuperJson + if [ "$createSuperJson" = "y" ] || [ "$createSuperJson" = "Y" ]; then + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + echo "* You can edit these settings in \"super.json\" located in the Shinobi directory." + sudo cp super.sample.json super.json + fi +fi +echo "Shinobi - Run yum update" +sudo yum update -y +echo "=============" +echo "Shinobi - Do you want to Install FFMPEG?" +echo "(y)es or (N)o" +read ffmpeginstall +if [ "$ffmpeginstall" = "y" ] || [ "$ffmpeginstall" = "Y" ]; then + echo "Shinobi - Do you want to Install FFMPEG with `apt` or download a static version provided with `npm`?" + echo "(a)pt or (N)pm" + echo "Press [ENTER] for default (npm)" + read ffmpegstaticinstall + if [ "$ffmpegstaticinstall" = "a" ] || [ "$ffmpegstaticinstall" = "A" ]; then + #Install EPEL Repo + sudo yum install epel-release -y + #Enable Nux Dextop repo for FFMPEG + sudo rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro + sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-1.el7.nux.noarch.rpm + sudo yum install ffmpeg ffmpeg-devel -y + else + sudo npm install ffmpeg-static + fi +fi +echo "Shinobi - Do you want to Install Node.js?" +echo "(y)es or (N)o" +read nodejsinstall +if [ "$nodejsinstall" = "y" ] || [ "$nodejsinstall" = "Y" ]; then + sudo wget https://rpm.nodesource.com/setup_8.x + sudo chmod +x setup_8.x + ./setup_8.x + sudo yum install nodejs -y +fi +echo "=============" +echo "Shinobi - Do you want to use MariaDB or SQLite3?" +echo "SQLite3 is better for small installs" +echo "MariaDB (MySQL) is better for large installs" +echo "(S)QLite3 or (M)ariaDB?" +echo "Press [ENTER] for default (MariaDB)" +read sqliteormariadb +if [ "$sqliteormariadb" = "S" ] || [ "$sqliteormariadb" = "s" ]; then + sudo npm install jsonfile + sudo yum install -y sqlite sqlite-devel -y + sudo npm install sqlite3 + node ./tools/modifyConfiguration.js databaseType=sqlite3 + if [ ! -e "./shinobi.sqlite" ]; then + echo "Creating shinobi.sqlite for SQLite3..." + sudo cp sql/shinobi.sample.sqlite shinobi.sqlite + else + echo "shinobi.sqlite already exists. Continuing..." + fi +else + echo "=============" + echo "Shinobi - Do you want to Install MariaDB?" + echo "(y)es or (N)o" + read mysqlagree + if [ "$mysqlagree" = "y" ] || [ "$mysqlagree" = "Y" ]; then + sudo yum install mariadb mariadb-server -y + #Start mysql and enable on boot + sudo systemctl start mariadb + sudo systemctl enable mariadb + #Run mysql install + sudo mysql_secure_installation + fi + echo "=============" + echo "Shinobi - Database Installation" + echo "(y)es or (N)o" + read mysqlagreeData + if [ "$mysqlagreeData" = "y" ] || [ "$mysqlagreeData" = "Y" ]; then + echo "What is your SQL Username?" + read sqluser + echo "What is your SQL Password?" + read sqlpass + sudo mysql -u $sqluser -p$sqlpass -e "source sql/user.sql" || true + sudo mysql -u $sqluser -p$sqlpass -e "source sql/framework.sql" || true + echo "Shinobi - Do you want to create a new user for viewing and managing cameras in Shinobi? You can do this later in the Superuser panel." + echo "(y)es or (N)o" + read mysqlDefaultData + if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then + escapeReplaceQuote='\\"' + groupKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1) + userID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userEmail=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)"@"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)".com" + userPasswordPlain=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userPasswordMD5=$(echo -n "$userPasswordPlain" | md5sum | awk '{print $1}') + userDetails='{"days":"10"}' + userDetails=$(echo "$userDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + echo $userDetailsNew + apiIP='0.0.0.0' + apiKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) + apiDetails='{"auth_socket":"1","get_monitors":"1","control_monitors":"1","get_logs":"1","watch_stream":"1","watch_snapshot":"1","watch_videos":"1","delete_videos":"1"}' + apiDetails=$(echo "$apiDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + rm sql/default_user.sql || true + echo "USE ccio;INSERT INTO Users (\`ke\`,\`uid\`,\`auth\`,\`mail\`,\`pass\`,\`details\`) VALUES (\"$groupKey\",\"$userID\",\"$apiKey\",\"$userEmail\",\"$userPasswordMD5\",\"$userDetails\");INSERT INTO API (\`code\`,\`ke\`,\`uid\`,\`ip\`,\`details\`) VALUES (\"$apiKey\",\"$groupKey\",\"$userID\",\"$apiIP\",\"$apiDetails\");" > "sql/default_user.sql" + sudo mysql -u $sqluser -p$sqlpass --database ccio -e "source sql/default_user.sql" > "INSTALL/log.txt" + echo "The following details will be shown again at the end of the installation." + echo "=====================================" + echo "======= Login Credentials =======" + echo "|| Username : $userEmail" + echo "|| Password : $userPasswordPlain" + echo "|| API Key : $apiKey" + echo "=====================================" + echo "=====================================" + echo "** To change these settings login to either to the Superuser panel or login to the dashboard as the user that was just created and open the Settings window. **" + fi + fi +fi +echo "=============" +echo "Shinobi - Install NPM Libraries" +sudo npm install +echo "=============" +echo "Shinobi - Install PM2" +sudo npm install pm2 -g +echo "Shinobi - Finished" +sudo chmod -R 755 . +touch INSTALL/installed.txt +if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then + echo "=====================================" > INSTALL/installed.txt + echo "======= Login Credentials =======" >> INSTALL/installed.txt + echo "|| Username : $userEmail" >> INSTALL/installed.txt + echo "|| Password : $userPasswordPlain" >> INSTALL/installed.txt + echo "|| API Key : $apiKey" >> INSTALL/installed.txt + echo "=====================================" >> INSTALL/installed.txt + echo "=====================================" >> INSTALL/installed.txt +fi +echo "Shinobi - Start Shinobi and set to start on boot?" +echo "(y)es or (N)o" +read startShinobi +if [ "$startShinobi" = "y" ] || [ "$startShinobi" = "Y" ]; then + sudo pm2 start camera.js + sudo pm2 start cron.js + sudo pm2 startup + sudo pm2 save + sudo pm2 list +fi +if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then + echo "details written to INSTALL/installed.txt" + echo "=====================================" + echo "======= Login Credentials =======" + echo "|| Username : $userEmail" + echo "|| Password : $userPasswordPlain" + echo "|| API Key : $apiKey" + echo "=====================================" + echo "=====================================" +fi +if [ ! "$sqliteormariadb" = "M" ] && [ ! "$sqliteormariadb" = "m" ]; then + echo "=====================================" + echo "||===== Install Completed =====||" + echo "=====================================" + echo "|| Login with the Superuser and create a new user!!" + echo "||===================================" + echo "|| Open http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080/super in your web browser." + echo "||===================================" + echo "|| Default Superuser : admin@shinobi.video" + echo "|| Default Password : admin" + echo "=====================================" + echo "=====================================" +else + echo "+=================================+" + echo "||===== Install Completed =====||" + echo "|| Access the main Shinobi panel at http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080 in your web browser." + echo "+=================================+" +fi \ No newline at end of file diff --git a/INSTALL/cuda4-part1.sh b/INSTALL/cuda4-part1.sh new file mode 100644 index 0000000..286f10b --- /dev/null +++ b/INSTALL/cuda4-part1.sh @@ -0,0 +1,15 @@ +#https://devtalk.nvidia.com/default/topic/1000340/cuda-setup-and-installation/-quot-nvidia-smi-has-failed-because-it-couldn-t-communicate-with-the-nvidia-driver-quot-ubuntu-16-04/4 +sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub +sudo echo "# NVIDIA Graphics Driver Repo (Added by Shinobi installer)" | sudo tee -a /etc/apt/sources.list +sudo echo "# Public Key : sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub" | sudo tee -a /etc/apt/sources.list +sudo echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 /" | sudo tee -a /etc/apt/sources.list +apt update +sudo apt -y install nvidia-340 nvidia-340-dev nvidia-modprobe libcuda1-340 libcuda1-340-updates nvidia-prime + +echo "After rebooting you need to run part 2. The file is named `cuda9-part2-after-reboot.sh`." +echo "Reboot is required. Do it now?" +echo "(y)es or (N)o" +read rebootTheMachineHomie +if [ "$rebootTheMachineHomie" = "y" ] || [ "$rebootTheMachineHomie" = "Y" ]; then + sudo reboot +fi \ No newline at end of file diff --git a/INSTALL/cuda9-part1.sh b/INSTALL/cuda9-part1.sh new file mode 100644 index 0000000..cc09bf7 --- /dev/null +++ b/INSTALL/cuda9-part1.sh @@ -0,0 +1,15 @@ +#https://devtalk.nvidia.com/default/topic/1000340/cuda-setup-and-installation/-quot-nvidia-smi-has-failed-because-it-couldn-t-communicate-with-the-nvidia-driver-quot-ubuntu-16-04/4 +sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub +sudo echo "# NVIDIA Graphics Driver Repo (Added by Shinobi installer)" | sudo tee -a /etc/apt/sources.list +sudo echo "# Public Key : sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub" | sudo tee -a /etc/apt/sources.list +sudo echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 /" | sudo tee -a /etc/apt/sources.list +apt update +sudo apt -y install cuda-drivers + +echo "After rebooting you need to run part 2. The file is named `cuda9-part2-after-reboot.sh`." +echo "Reboot is required. Do it now?" +echo "(y)es or (N)o" +read rebootTheMachineHomie +if [ "$rebootTheMachineHomie" = "y" ] || [ "$rebootTheMachineHomie" = "Y" ]; then + sudo reboot +fi \ No newline at end of file diff --git a/INSTALL/cuda9-part2-after-reboot.sh b/INSTALL/cuda9-part2-after-reboot.sh new file mode 100644 index 0000000..0335161 --- /dev/null +++ b/INSTALL/cuda9-part2-after-reboot.sh @@ -0,0 +1,2 @@ +sudo apt-get -y install cuda-toolkit-9-1 +nvidia-smi \ No newline at end of file diff --git a/INSTALL/ffmpeg.sh b/INSTALL/ffmpeg.sh new file mode 100644 index 0000000..31f8e18 --- /dev/null +++ b/INSTALL/ffmpeg.sh @@ -0,0 +1,22 @@ +#!/bin/bash +echo "=============" +echo "Install FFMPEG" +echo "What build of FFMPEG do you require?" +echo "If you don't know check your CPU specs for a hint." +echo "- 32bit" +echo "- 64bit" +echo "- armel-32bit" +echo "- armhf-32bit" +read ffmpegbuild +wget "https://s3.amazonaws.com/cloudcamio/ffmpeg-release-$ffmpegbuild-static.tar.xz" +tar xf "ffmpeg-release-$ffmpegbuild-static.tar.xz" +mv "ffmpeg-3.3-$ffmpegbuild-static/ffmpeg" "/usr/bin/ffmpeg" +mv "ffmpeg-3.3-$ffmpegbuild-static/ffmpeg-10bit" "/usr/bin/ffmpeg-10bit" +mv "ffmpeg-3.3-$ffmpegbuild-static/ffprobe" "/usr/bin/ffprobe" +mv "ffmpeg-3.3-$ffmpegbuild-static/ffserver" "/usr/bin/ffserver" +chmod +x /usr/bin/ffmpeg +chmod +x /usr/bin/ffmpeg-10bit +chmod +x /usr/bin/ffprobe +chmod +x /usr/bin/ffserver +rm -rf "ffmpeg-3.3-$ffmpegbuild-static" +rm -rf "ffmpeg-release-$ffmpegbuild-static.tar.xz" diff --git a/INSTALL/freebsd.sh b/INSTALL/freebsd.sh new file mode 100644 index 0000000..12da305 --- /dev/null +++ b/INSTALL/freebsd.sh @@ -0,0 +1,73 @@ +#!/bin/tcsh +echo "=========================================================" +echo "==== Shinobi : The Open Source CCTV and NVR Solution ====" +echo "=========================================================" +echo "This script should run as root inside your jail from the root" +echo "of the cloned git repository." +echo "To answer yes type the letter (y) in lowercase and press ENTER." +echo "Default is no (N). Skip any components you already have or don't need." +echo "=============" +echo "Shinobi - Do you want to Install Node.js?" +echo "(y)es or (N)o" +set nodejsinstall = $< +if ( $nodejsinstall == "y" ) then + pkg install -y node npm +endif +echo "=============" +echo "Shinobi - Do you want to Install FFMPEG?" +echo "(y)es or (N)o" +set ffmpeginstall = $< +if ( $ffmpeginstall == "y" ) then + pkg install -y ffmpeg libav x264 x265 +endif +echo "=============" +echo "Shinobi - Database Installation" +echo "WARNING - This requires an existing and running mariadb service." +echo "(y)es or (N)o" +set mysqlagreeData = $< +if ( $mysqlagreeData == "y" ) then + echo "What is your SQL Username?" + set sqluser = $< + echo "What is your SQL Password?" + set sqlpass = $< + echo "What is your SQL Host?" + set sqlhost = $< + echo "Installing mariadb client..." + pkg install -y mariadb102-client + echo "Installing database schema..." + mysql -h $sqlhost -u $sqluser -p$sqlpass -e "source sql/user.sql" || true + mysql -h $sqlhost -u $sqluser -p$sqlpass -e "source sql/framework.sql" || true + echo "Shinobi - Use the /super endpoint to create your super user." +endif +echo "=============" +echo "Shinobi - Install NPM Libraries" +npm install +echo "=============" +echo "Shinobi - Install PM2" +npm install pm2 -g +if (! -e "./conf.json" ) then + cp conf.sample.json conf.json +endif +if (! -e "./super.json" ) then + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + cp super.sample.json super.json +endif +echo "Shinobi - Start Shinobi?" +echo "(y)es or (N)o" +set startShinobi = $< +if ( $startShinobi == "y" ) then + set PM2BIN="$PWD/node_modules/pm2/bin" + $PM2BIN/pm2 start camera.js + $PM2BIN/pm2 start cron.js + $PM2BIN/pm2 save + $PM2BIN/pm2 list +endif +echo "Shinobi - Start on boot?" +echo "(y)es or (N)o" +set startupShinobi = $< +if ( $startupShinobi == "y" ) then + set PM2BIN="$PWD/node_modules/pm2/bin" + $PM2BIN/pm2 startup rcd +endif +echo "Shinobi - Finished" diff --git a/INSTALL/installDatabase.js b/INSTALL/installDatabase.js new file mode 100644 index 0000000..fc6e016 --- /dev/null +++ b/INSTALL/installDatabase.js @@ -0,0 +1,37 @@ +var knex = require('knex'); +if(config.databaseType===undefined){config.databaseType='mysql'} + +var databaseOptions = { + client: config.databaseType, + connection: config.db, +} +if(databaseOptions.client.indexOf('sqlite')>-1){ + databaseOptions.client = 'sqlite3'; + databaseOptions.useNullAsDefault = true; +} +if(databaseOptions.client === 'sqlite3' && databaseOptions.connection.filename === undefined){ + databaseOptions.connection.filename = __dirname+"/shinobi.sqlite" +} +s.databaseEngine = knex(databaseOptions) +s.sqlQuery = function(query,values,onMoveOn,hideLog){ + if(!values){values=[]} + if(typeof values === 'function'){ + var onMoveOn = values; + var values = []; + } + if(!onMoveOn){onMoveOn=function(){}} + return s.databaseEngine.raw(query,values) + .asCallback(function(err,r){ + if(err&&config.databaseLogs){ + s.systemLog('s.sqlQuery QUERY',query) + s.systemLog('s.sqlQuery ERROR',err) + } + if(onMoveOn) + if(typeof onMoveOn === 'function'){ + if(!r)r=[] + onMoveOn(err,r) + }else{ + console.log(onMoveOn) + } + }) +} \ No newline at end of file diff --git a/INSTALL/macos-part2.sh b/INSTALL/macos-part2.sh new file mode 100644 index 0000000..82d20fd --- /dev/null +++ b/INSTALL/macos-part2.sh @@ -0,0 +1,90 @@ + +#!/bin/bash +echo "=========================================================" +echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!==" +echo "=================== Mac OS Install Part 2 ===============" +echo "=========================================================" +echo "Shinobi - Database Installation" +echo "(y)es or (N)o" +read mysqlagreeData +if [ "$mysqlagreeData" = "y" ]; then + echo "Shinobi will now use root for database installation..." + echo "What is your SQL Username?" + read sqluser + echo "What is your SQL Password?" + read sqlpass + echo "You may now be asked for your Administator (root for Mac OS, not MySQL) password" + sudo mysql -u $sqluser -p$sqlpass -e "source sql/user.sql" || true + sudo mysql -u $sqluser -p$sqlpass -e "source sql/framework.sql" || true + echo "Shinobi - Do you want to create a new user for viewing and managing cameras in Shinobi? You can do this later in the Superuser panel." + echo "(y)es or (N)o" + read mysqlDefaultData + if [ "$mysqlDefaultData" = "y" ]; then + escapeReplaceQuote='\\"' + groupKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1) + userID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userEmail=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)"@"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)".com" + userPasswordPlain=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userPasswordMD5=$(echo -n "$userPasswordPlain" | md5sum | awk '{print $1}') + userDetails='{"days":"10"}' + userDetails=$(echo "$userDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + echo $userDetailsNew + apiIP='0.0.0.0' + apiKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) + apiDetails='{"auth_socket":"1","get_monitors":"1","control_monitors":"1","get_logs":"1","watch_stream":"1","watch_snapshot":"1","watch_videos":"1","delete_videos":"1"}' + apiDetails=$(echo "$apiDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + rm sql/default_user.sql || true + echo "USE ccio;INSERT INTO Users (\`ke\`,\`uid\`,\`auth\`,\`mail\`,\`pass\`,\`details\`) VALUES (\"$groupKey\",\"$userID\",\"$apiKey\",\"$userEmail\",\"$userPasswordMD5\",\"$userDetails\");INSERT INTO API (\`code\`,\`ke\`,\`uid\`,\`ip\`,\`details\`) VALUES (\"$apiKey\",\"$groupKey\",\"$userID\",\"$apiIP\",\"$apiDetails\");" > "sql/default_user.sql" + sudo mysql -u $sqluser -p$sqlpass --database ccio -e "source sql/default_user.sql" > "INSTALL/log.txt" + echo "The following details will be shown again at the end of the installation." + echo "=====================================" + echo "======= Login Credentials =======" + echo "|| Username : $userEmail" + echo "|| Password : $userPasswordPlain" + echo "|| API Key : $apiKey" + echo "=====================================" + echo "=====================================" + echo "** To change these settings login to either to the Superuser panel or login to the dashboard as the user that was just created and open the Settings window. **" + fi +fi +echo "=============" +echo "Shinobi - Install NPM Libraries" +sudo npm install +echo "=============" +echo "Shinobi - Install PM2" +sudo npm install pm2 -g +if [ ! -e "./conf.json" ]; then + sudo cp conf.sample.json conf.json +fi +if [ ! -e "./super.json" ]; then + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + sudo cp super.sample.json super.json +fi +echo "Shinobi - Finished" +touch INSTALL/installed.txt +sudo chmod -R 755 . +echo "=====================================" > INSTALL/installed.txt +echo "======= Login Credentials =======" >> INSTALL/installed.txt +echo "|| Username : $userEmail" >> INSTALL/installed.txt +echo "|| Password : $userPasswordPlain" >> INSTALL/installed.txt +echo "|| API Key : $apiKey" >> INSTALL/installed.txt +echo "=====================================" >> INSTALL/installed.txt +echo "=====================================" >> INSTALL/installed.txt +echo "Shinobi - Start Shinobi and set to start on boot?" +echo "(y)es or (N)o" +read startShinobi +if [ "$startShinobi" = "y" ]; then + sudo pm2 start camera.js + sudo pm2 startup + sudo pm2 save + sudo pm2 list +fi +echo "details written to INSTALL/installed.txt" +echo "=====================================" +echo "======= Login Credentials =======" +echo "|| Username : $userEmail" +echo "|| Password : $userPasswordPlain" +echo "|| API Key : $apiKey" +echo "=====================================" +echo "=====================================" diff --git a/INSTALL/macos.sh b/INSTALL/macos.sh new file mode 100644 index 0000000..0bf226e --- /dev/null +++ b/INSTALL/macos.sh @@ -0,0 +1,50 @@ +#!/bin/bash +echo "=========================================================" +echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!==" +echo "=================== Mac OS Install Part 1 ===============" +echo "=========================================================" +echo "To answer yes type the letter (y) in lowercase and press ENTER." +echo "Default is no (N). Skip any components you already have or don't need." +echo "=============" +echo "Shinobi - Do you want to Install Node.js?" +echo "(y)es or (N)o" +read nodejsinstall +if [ "$nodejsinstall" = "y" ]; then + curl -o node-v8.9.3.pkg https://nodejs.org/dist/v8.9.3/node-v8.9.3.pkg + sudo installer -pkg node-v8.9.3.pkg -target / + rm node-v8.9.3.pkg + sudo ln -s /usr/local/bin/node /usr/bin/nodejs +fi +echo "=============" +echo "Shinobi - Do you want to Install FFmpeg?" +echo "(y)es or (N)o" +read ffmpeginstall +if [ "$ffmpeginstall" = "y" ]; then + echo "Shinobi - Installing FFmpeg" + curl -o ffmpeg.zip https://cdn.shinobi.video/installers/ffmpeg-3.4.1-macos.zip + sudo unzip ffmpeg.zip + sudo rm ffmpeg.zip + sudo mv ffmpeg-3.4.1-macos/ffmpeg /usr/bin/ffmpeg + sudo mv ffmpeg-3.4.1-macos/ffplay /usr/bin/ffplay + sudo mv ffmpeg-3.4.1-macos/ffprobe /usr/bin/ffprobe + sudo mv ffmpeg-3.4.1-macos/ffserver /usr/bin/ffserver + sudo chmod +x /usr/local/bin/ffmpeg + sudo chmod +x /usr/local/bin/ffplay + sudo chmod +x /usr/local/bin/ffprobe + sudo chmod +x /usr/local/bin/ffserver +fi +echo "=============" +echo "Shinobi - Do you want to Install MySQL? Choose No if you have MySQL or MySQL already." +echo "(y)es or (N)o" +read mysqlagree +if [ "$mysqlagree" = "y" ]; then + echo "Shinobi - Installing MySQL" + bash <(curl -Ls http://git.io/eUx7rg) +fi +echo "=============" +echo "=============" +echo "You must now close this terminal window and reopen it." +echo "Reopen the Shinobi folder and run" +echo "sudo sh INSTALL/macos-part2.sh" +echo "=============" +echo "=============" \ No newline at end of file diff --git a/INSTALL/now.sh b/INSTALL/now.sh new file mode 100644 index 0000000..55ee23f --- /dev/null +++ b/INSTALL/now.sh @@ -0,0 +1,33 @@ +#!/bin/bash +echo "Shinobi Installer" +echo "========" +echo "Select your OS" +echo "If your OS is not on the list please refer to the docs." +echo "========" +echo "1. Ubuntu" +echo "2. CentOS" +echo "3. MacOS" +echo "4. FreeBSD" +echo "========" +read oschoicee +case $oschoicee in +"1") +chmod +x INSTALL/ubuntu.sh +sh INSTALL/ubuntu.sh + ;; +"2") +chmod +x INSTALL/centos.sh +INSTALL/centos.sh + ;; +"3") +chmod +x INSTALL/macos.sh +INSTALL/macos.sh + ;; +"4") +chmod +x INSTALL/freebsd.sh +INSTALL/freebsd.sh + ;; +*) + echo "Choice not found." + ;; +esac \ No newline at end of file diff --git a/INSTALL/openalpr-gpu-easy.sh b/INSTALL/openalpr-gpu-easy.sh new file mode 100644 index 0000000..0949629 --- /dev/null +++ b/INSTALL/openalpr-gpu-easy.sh @@ -0,0 +1,31 @@ +# Install prerequisites +# this includes all the ones missing from OpenALPR's guide. +sudo apt install libtesseract-dev git cmake build-essential libleptonica-dev -y +sudo apt install liblog4cplus-dev libcurl3-dev -y +sudo apt install libleptonica-dev -y +sudo apt install libcurl4-openssl-dev -y +sudo apt install liblog4cplus-dev -y +sudo apt install beanstalkd -y +sudo apt install openjdk-8-jdk -y + +# Clone the latest code from GitHub +git clone https://github.com/openalpr/openalpr.git + +# Setup the build directory +cd openalpr/src +mkdir build +cd build + +# setup the compile environment +cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_INSTALL_SYSCONFDIR:PATH=/etc –DCOMPILE_GPU=1 -D WITH_GPU_DETECTOR=ON .. + +# compile the library +make + +# Install the binaries/libraries to your local system (prefix is /usr) +sudo make install + +# Test the library +wget http://plates.openalpr.com/h786poj.jpg -O lp.jpg +alpr lp.jpg +rm lp.jpg \ No newline at end of file diff --git a/INSTALL/openalpr-opencl.sh b/INSTALL/openalpr-opencl.sh new file mode 100644 index 0000000..20ca09d --- /dev/null +++ b/INSTALL/openalpr-opencl.sh @@ -0,0 +1,3 @@ +sudo apt-get update && sudo apt install -y openalpr openalpr-daemon openalpr-utils libopenalpr-dev + +git clone https://github.com/openalpr/openalpr.git \ No newline at end of file diff --git a/INSTALL/opencv-cuda.sh b/INSTALL/opencv-cuda.sh new file mode 100644 index 0000000..c9f1045 --- /dev/null +++ b/INSTALL/opencv-cuda.sh @@ -0,0 +1,101 @@ +#!/bin/bash +#dlib +echo "=================" +echo "Installing OpenCV" +echo "=================" +if [ $(dpkg-query -W -f='${Status}' git 2>/dev/null | grep -c "ok installed") -eq 0 ]; then + echo "Installing Git..." + apt install git -y; +fi +sudo apt-get install libopenblas-dev -y +if [ ! -e "./opencv" ]; then + echo "Downloading OpenCV..." + git clone https://github.com/opencv/opencv.git + cd opencv + git checkout 3.4.0 + cd .. +fi +if [ ! -e "./opencv_contrib" ]; then + echo "Downloading OpenCV Modules..." + git clone https://github.com/opencv/opencv_contrib.git + cd opencv_contrib + git checkout 3.4.0 + cd .. +fi +echo "Opening OpenCV Directory..." +cd opencv +if [ ! -e "./build" ]; then + echo "Creating OpenCV Build Directory..." + mkdir build +fi +echo "Entering OpenCV Build Directory..." +cd build +echo "*****************" +if [ -f /etc/lsb-release ]; then + flavor=$(cat /var/log/installer/media-info) + echo "$flavor" + echo "*****************" + echo "Adding Additional Repository" + echo "http://security.ubuntu.com/ubuntu" + if [ "$flavor" = *"Artful"* ]; then + sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu artful-security main" + fi + if [ "$flavor" = *"Zesty"* ]; then + sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu zesty-security main" + fi + if [ "$flavor" = *"Xenial"* ]; then + sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main" + fi + if [ "$flavor" = *"Trusty"* ]; then + sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu trusty-security main" + fi + echo "Downloading Libraries" + sudo apt-get install libjpeg-dev libpango1.0-dev libgif-dev build-essential gcc-6 g++-6 -y; + sudo apt-get install libxvidcore-dev libx264-dev -y; + sudo apt-get install libatlas-base-dev gfortran -y; + + sudo apt install build-essential cmake pkg-config unzip ffmpeg qtbase5-dev python-dev python3-dev python-numpy python3-numpy libhdf5-dev libgtk-3-dev libdc1394-22 libdc1394-22-dev libjpeg-dev libtiff5-dev libtesseract-dev -y; + + sudo apt install libavcodec-dev libavformat-dev libswscale-dev libxine2-dev libgstreamer-plugins-base1.0-0 libgstreamer-plugins-base1.0-dev libpng16-16 libpng-dev libv4l-dev libtbb-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev v4l-utils libleptonica-dev -y + + echo "Setting CUDA Paths" + export LD_LIBRARY_PATH=/usr/local/cuda/lib + export PATH=$PATH:/usr/local/cuda/bin + echo "Configure OpenCV Build" + + cmake -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_NVCUVID=ON -D FORCE_VTK=ON -D WITH_XINE=ON -D WITH_CUDA=ON -D WITH_OPENGL=ON -D WITH_TBB=ON -D WITH_OPENCL=ON -D CMAKE_BUILD_TYPE=RELEASE -D CUDA_NVCC_FLAGS="-D_FORCE_INLINES --expt-relaxed-constexpr" -D WITH_GDAL=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules/ -D ENABLE_FAST_MATH=1 -D CUDA_FAST_MATH=1 -D WITH_CUBLAS=1 -D CXXFLAGS="-std=c++11" -DCMAKE_CXX_COMPILER=g++-6 -DCMAKE_C_COMPILER=gcc-6 .. + + echo "Start OpenCV Build" + make -j "$(nproc)" + echo "Install OpenCV Build" + sudo make install + sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf' + sudo ldconfig + sudo apt-get update +fi +if [ -f /etc/redhat-release ]; then + yum install -y \ + protobuf-devel \ + leveldb-devel \ + snappy-devel \ + opencv-devel \ + boost-devel \ + hdf5-devel \ + gflags-devel \ + glog-devel \ + lmdb-devel \ + cmake +fi +echo "Leaving OpenCV Directory" +cd ../.. + +echo "=============" +echo "Done installing OpenCV!" +echo "=============" +echo "Delete OpenCV source files? This will save a lot of space but it will be more tedious to uninstall OpenCV later." +echo "(y)es or (N)o" +read opencvuninstall +if [ "$opencvuninstall" = "y" ] || [ "$opencvuninstall" = "Y" ]; then + rm -rf opencv + rm -rf opencv_contrib +fi \ No newline at end of file diff --git a/INSTALL/shinobi b/INSTALL/shinobi new file mode 100644 index 0000000..3dd519b --- /dev/null +++ b/INSTALL/shinobi @@ -0,0 +1,10 @@ +#!/bin/bash +installationDirectory="/home/Shinobi" +if [ -e "$installationDirectory/INSTALL/installed.txt" ]; then + echo "Starting Shinobi" + pm2 start $installationDirectory/camera.js + pm2 start $installationDirectory/cron.js +fi +if [ ! -e "$installationDirectory/INSTALL/installed.txt" ]; then + chmod +x $installationDirectory/INSTALL/now.sh&&INSTALL/now.sh +fi \ No newline at end of file diff --git a/INSTALL/shinobi.service b/INSTALL/shinobi.service new file mode 100644 index 0000000..73138e2 --- /dev/null +++ b/INSTALL/shinobi.service @@ -0,0 +1,11 @@ +[Unit] +Description=ShinobiCCTV + +[Service] +WorkingDirectory=/home/Shinobi +Type=forking +ExecStart=/bin/bash INSTALL/start.sh +KillMode=process + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/INSTALL/start.sh b/INSTALL/start.sh new file mode 100644 index 0000000..a2439f7 --- /dev/null +++ b/INSTALL/start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +if [ -e "INSTALL/installed.txt" ]; then + echo "Starting Shinobi" + pm2 start camera.js + pm2 start cron.js +fi +if [ ! -e "INSTALL/installed.txt" ]; then + chmod +x INSTALL/now.sh&&INSTALL/now.sh +fi \ No newline at end of file diff --git a/INSTALL/ubuntu-easyinstall.sh b/INSTALL/ubuntu-easyinstall.sh new file mode 100644 index 0000000..075e2be --- /dev/null +++ b/INSTALL/ubuntu-easyinstall.sh @@ -0,0 +1,175 @@ +#!/bin/bash +echo "Shinobi - Do you want to Install Node.js?" +echo "(y)es or (N)o" +read nodejsinstall +if [ "$nodejsinstall" = "y" ]; then + wget https://deb.nodesource.com/setup_8.x + chmod +x setup_8.x + ./setup_8.x + sudo apt install nodejs -y + rm setup_8.x +fi + +#Detect Ubuntu Version +echo "=============" +echo " Detecting Ubuntu Version" +echo "=============" +declare -i getubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1) +echo "=============" +echo " Ubuntu Version: $getubuntuversion" +echo "=============" +if [[ "$getubuntuversion" == "16" || "$getubuntuversion" < "16" ]]; then + echo "=============" + echo "Shinobi - Get FFMPEG 3.x from ppa:jonathonf/ffmpeg-3" + sudo add-apt-repository ppa:jonathonf/ffmpeg-3 -y + sudo apt update -y && sudo apt install ffmpeg libav-tools x264 x265 -y + echo "=============" +else + echo "=============" + echo "Shinobi - Installing FFMPEG" + sudo apt install ffmpeg libav-tools x264 x265 -y + echo "=============" +fi + +# Install MariaDB +echo "Shinobi - Do you want to Install MariaDB? Choose No if you have MySQL." +echo "(y)es or (N)o" +read mysqlagree +if [ "$mysqlagree" = "y" ]; then + echo "Shinobi - Installing MariaDB" + echo "Password for root SQL user, If you are installing SQL now then you may put anything:" + read sqlpass + echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections + echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections + apt install mariadb-server -y + service mysql start +fi + +# Make sure files have correct perms +chmod -R 755 . + +# Database Installation +#Check If Mysql-Server is already installed + +echo "=============" +echo "Checking for mysql-server" +echo "=============" +dpkg -s mysql-server &> /dev/null +if [ $? -eq 0 ]; then + echo "+====================================+" + echo "| Warning MYSQL SERVER IS INSTALLED! |" + echo "+====================================+" + echo "| DO YOU WANT TO INSTALL MariaDB? |" + echo "| This will remove MYSQL-Server! |" + echo "+====================================+" + echo "Shinobi - Do you want to Install MariaDB?" + echo "(y)es or (N)o" + read installmariadb + if [ "$installmariadb" = "y" ]; then + echo "+=============================================+" + echo "| This will DESTORY ALL DATA ON MYSQL SERVER! |" + echo "+=============================================+" + echo "Please type the following to continue" + echo "DESTORY!" + read mysqlagree + if [ "$mysqlagree" = "DESTORY!" ]; then + echo "Shinobi - Installing MariaDB" + echo "Password for root SQL user, If you are installing SQL now then you may put anything:" + read sqlpass + echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections + echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections + #Create my.cnf file + echo "[client]" >> ~/.my.cnf + echo "user=root" >> ~/.my.cnf + echo "password=$sqlpass" >> ~/.my.cnf + chmod 755 ~/.my.cnf + apt install mariadb-server + service mysql start + fi + fi +else + echo "Shinobi - Do you want to Install MariaDB?" + echo "(y)es or (N)o" + read mysqlagree + if [ "$mysqlagree" = "y" ]; then + echo "Shinobi - Installing MariaDB" + echo "Password for root SQL user, If you are installing SQL now then you may put anything:" + read sqlpass + echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections + echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections + echo "[client]" >> ~/.my.cnf + echo "user=root" >> ~/.my.cnf + echo "password=$sqlpass" >> ~/.my.cnf + chmod 755 ~/.my.cnf + apt install mariadb-server -y + service mysql start + fi +fi + +chmod -R 755 . +echo "Shinobi - Database Installation" +echo "(y)es or (N)o" +read mysqlagreeData +if [ "$mysqlagreeData" = "y" ]; then + mysql -e "source sql/user.sql" || true + mysql -e "source sql/framework.sql" || true + echo "Shinobi - Do you want to Install Default Data (default_data.sql)?" + echo "(y)es or (N)o" + read mysqlDefaultData + if [ "$mysqlDefaultData" = "y" ]; then + escapeReplaceQuote='\\"' + groupKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1) + userID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userEmail=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)"@"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)".com" + userPasswordPlain=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userPasswordMD5=$(echo -n "$userPasswordPlain" | md5sum | awk '{print $1}') + userDetails='{"days":"10"}' + userDetails=$(echo "$userDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + echo $userDetailsNew + apiIP='0.0.0.0' + apiKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) + apiDetails='{"auth_socket":"1","get_monitors":"1","control_monitors":"1","get_logs":"1","watch_stream":"1","watch_snapshot":"1","watch_videos":"1","delete_videos":"1"}' + apiDetails=$(echo "$apiDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + rm sql/default_user.sql || true + echo "USE ccio;INSERT INTO Users (\`ke\`,\`uid\`,\`auth\`,\`mail\`,\`pass\`,\`details\`) VALUES (\"$groupKey\",\"$userID\",\"$apiKey\",\"$userEmail\",\"$userPasswordMD5\",\"$userDetails\");INSERT INTO API (\`code\`,\`ke\`,\`uid\`,\`ip\`,\`details\`) VALUES (\"$apiKey\",\"$groupKey\",\"$userID\",\"$apiIP\",\"$apiDetails\");" > "sql/default_user.sql" + mysql -u $sqluser -p$sqlpass --database ccio -e "source sql/default_user.sql" > "INSTALL/log.txt" + echo "=====================================" + echo "=======!! Login Credentials !!=======" + echo "|| Username : $userEmail" + echo "|| Password : $userPasswordPlain" + echo "|| API Key : $apiKey" + echo "=====================================" + echo "=====================================" + echo "** To change these settings login to either to the Superuser panel or login to the dashboard as the user that was just created and open the Settings window. **" + fi +fi + +# Install NPM Libraries +echo "=============" +echo "Shinobi - Install NPM Libraries" +npm install +echo "=============" + +#Install PM2 +echo "Shinobi - Install PM2" +sudo npm install pm2 -g +if [ ! -e "./conf.json" ]; then + cp conf.sample.json conf.json +fi +if [ ! -e "./super.json" ]; then + getip=$(ip route get 8.8.8.8 | awk '{print $NF; exit}') + echo "Admin panel default url: http://$getip:8080/super" + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + cp super.sample.json super.json +fi +echo "Shinobi - Finished" +touch INSTALL/installed.txt +echo "Shinobi - Start Shinobi?" +echo "(y)es or (N)o" +read startShinobi +if [ "$startShinobi" = "y" ]; then + pm2 start camera.js + pm2 start cron.js + pm2 list +fi \ No newline at end of file diff --git a/INSTALL/ubuntu.sh b/INSTALL/ubuntu.sh new file mode 100644 index 0000000..2e1ef46 --- /dev/null +++ b/INSTALL/ubuntu.sh @@ -0,0 +1,202 @@ +#!/bin/bash +echo "=========================================================" +echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!==" +echo "=========================================================" +echo "To answer yes type the letter (y) in lowercase and press ENTER." +echo "Default is no (N). Skip any components you already have or don't need." +echo "=============" +if [ ! -e "./conf.json" ]; then + sudo cp conf.sample.json conf.json +fi +if [ ! -e "./super.json" ]; then + echo "Shinobi - Do you want to enable superuser access?" + echo "This may be useful if passwords are forgotten or" + echo "if you would like to limit accessibility of an" + echo "account for business scenarios." + echo "(y)es or (N)o" + read createSuperJson + if [ "$createSuperJson" = "y" ] || [ "$createSuperJson" = "Y" ]; then + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + echo "* You can edit these settings in \"super.json\" located in the Shinobi directory." + sudo cp super.sample.json super.json + fi +fi +echo "Shinobi - Do you want to Install Node.js?" +echo "(y)es or (N)o" +read nodejsinstall +if [ "$nodejsinstall" = "y" ] || [ "$nodejsinstall" = "Y" ]; then + wget https://deb.nodesource.com/setup_8.x + chmod +x setup_8.x + ./setup_8.x + sudo apt install nodejs -y +fi +echo "=============" +echo "Shinobi - Do you want to Install FFMPEG?" +echo "(y)es or (N)o" +read ffmpeginstall +if [ "$ffmpeginstall" = "y" ] || [ "$ffmpeginstall" = "Y" ]; then + echo "Shinobi - Do you want to Install FFMPEG with `apt` or download a static version provided with `npm`?" + echo "(a)pt or (N)pm" + echo "Press [ENTER] for default (npm)" + read ffmpegstaticinstall + if [ "$ffmpegstaticinstall" = "a" ] || [ "$ffmpegstaticinstall" = "A" ]; then + #Detect Ubuntu Version + echo "=============" + echo " Detecting Ubuntu Version" + echo "=============" + declare -i getubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1) + echo "=============" + echo " Ubuntu Version: $getubuntuversion" + echo "=============" + if [[ "$getubuntuversion" == "16" || "$getubuntuversion" < "16" ]]; then + echo "=============" + echo "Shinobi - Get FFMPEG 3.x from ppa:jonathonf/ffmpeg-3" + sudo add-apt-repository ppa:jonathonf/ffmpeg-3 -y + sudo apt update -y && sudo apt install ffmpeg libav-tools x264 x265 -y + echo "=============" + else + echo "=============" + echo "Shinobi - Installing FFMPEG" + sudo apt install ffmpeg -y + echo "=============" + fi + else + sudo npm install ffmpeg-static + fi +fi +echo "=============" +echo "Shinobi - Do you want to use MariaDB or SQLite3?" +echo "SQLite3 is better for small installs" +echo "MariaDB (MySQL) is better for large installs" +echo "(S)QLite3 or (M)ariaDB?" +echo "Press [ENTER] for default (MariaDB)" +read sqliteormariadb +if [ "$sqliteormariadb" = "S" ] || [ "$sqliteormariadb" = "s" ]; then + sudo npm install jsonfile + sudo apt-get install sqlite3 libsqlite3-dev -y + sudo npm install sqlite3 + node ./tools/modifyConfiguration.js databaseType=sqlite3 + if [ ! -e "./shinobi.sqlite" ]; then + echo "Creating shinobi.sqlite for SQLite3..." + sudo cp sql/shinobi.sample.sqlite shinobi.sqlite + else + echo "shinobi.sqlite already exists. Continuing..." + fi +else + echo "Shinobi - Do you want to Install MariaDB? Choose No if you already have it." + echo "(y)es or (N)o" + read mysqlagree + if [ "$mysqlagree" = "y" ] || [ "$mysqlagree" = "Y" ]; then + echo "Shinobi - Installing MariaDB" + echo "Password for root SQL user, If you are installing SQL now then you may put anything:" + read sqlpass + echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections + echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections + sudo apt install mariadb-server -y + sudo service mysql start + fi + echo "=============" + echo "Shinobi - Database Installation" + echo "(y)es or (N)o" + read mysqlagreeData + if [ "$mysqlagreeData" = "y" ] || [ "$mysqlagreeData" = "Y" ]; then + if [ "$mysqlagree" = "y" ] || [ "$mysqlagree" = "Y" ]; then + sqluser="root" + fi + if [ ! "$mysqlagree" = "y" ]; then + echo "What is your SQL Username?" + read sqluser + echo "What is your SQL Password?" + read sqlpass + fi + sudo mysql -u $sqluser -p$sqlpass -e "source sql/user.sql" || true + sudo mysql -u $sqluser -p$sqlpass -e "source sql/framework.sql" || true + echo "Shinobi - Do you want to create a new user for viewing and managing cameras in Shinobi? You can do this later in the Superuser panel." + echo "(y)es or (N)o" + read mysqlDefaultData + if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then + escapeReplaceQuote='\\"' + groupKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1) + userID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userEmail=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)"@"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)".com" + userPasswordPlain=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userPasswordMD5=$(echo -n "$userPasswordPlain" | md5sum | awk '{print $1}') + userDetails='{"days":"10"}' + userDetails=$(echo "$userDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + echo $userDetailsNew + apiIP='0.0.0.0' + apiKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) + apiDetails='{"auth_socket":"1","get_monitors":"1","control_monitors":"1","get_logs":"1","watch_stream":"1","watch_snapshot":"1","watch_videos":"1","delete_videos":"1"}' + apiDetails=$(echo "$apiDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + rm sql/default_user.sql || true + echo "USE ccio;INSERT INTO Users (\`ke\`,\`uid\`,\`auth\`,\`mail\`,\`pass\`,\`details\`) VALUES (\"$groupKey\",\"$userID\",\"$apiKey\",\"$userEmail\",\"$userPasswordMD5\",\"$userDetails\");INSERT INTO API (\`code\`,\`ke\`,\`uid\`,\`ip\`,\`details\`) VALUES (\"$apiKey\",\"$groupKey\",\"$userID\",\"$apiIP\",\"$apiDetails\");" > "sql/default_user.sql" + sudo mysql -u $sqluser -p$sqlpass --database ccio -e "source sql/default_user.sql" > "INSTALL/log.txt" + echo "The following details will be shown again at the end of the installation." + echo "=====================================" + echo "======= Login Credentials =======" + echo "|| Username : $userEmail" + echo "|| Password : $userPasswordPlain" + echo "|| API Key : $apiKey" + echo "=====================================" + echo "=====================================" + echo "** To change these settings login to either to the Superuser panel or login to the dashboard as the user that was just created and open the Settings window. **" + fi + fi +fi +echo "=============" +echo "Shinobi - Install NPM Libraries" +sudo npm install +echo "=============" +echo "Shinobi - Install PM2" +sudo npm install pm2 -g +echo "Shinobi - Finished" +sudo chmod -R 755 . +touch INSTALL/installed.txt +if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then + echo "=====================================" > INSTALL/installed.txt + echo "======= Login Credentials =======" >> INSTALL/installed.txt + echo "|| Username : $userEmail" >> INSTALL/installed.txt + echo "|| Password : $userPasswordPlain" >> INSTALL/installed.txt + echo "|| API Key : $apiKey" >> INSTALL/installed.txt + echo "=====================================" >> INSTALL/installed.txt + echo "=====================================" >> INSTALL/installed.txt +fi +echo "Shinobi - Start Shinobi and set to start on boot?" +echo "(y)es or (N)o" +read startShinobi +if [ "$startShinobi" = "y" ] || [ "$startShinobi" = "y" ]; then + sudo pm2 start camera.js + sudo pm2 start cron.js + sudo pm2 startup + sudo pm2 save + sudo pm2 list +fi +if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then + echo "details written to INSTALL/installed.txt" + echo "=====================================" + echo "======= Login Credentials =======" + echo "|| Username : $userEmail" + echo "|| Password : $userPasswordPlain" + echo "|| API Key : $apiKey" + echo "=====================================" + echo "=====================================" +fi +if [ ! "$sqliteormariadb" = "M" ] && [ ! "$sqliteormariadb" = "m" ]; then + echo "=====================================" + echo "||===== Install Completed =====||" + echo "=====================================" + echo "|| Login with the Superuser and create a new user!!" + echo "||===================================" + echo "|| Open http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080/super in your web browser." + echo "||===================================" + echo "|| Default Superuser : admin@shinobi.video" + echo "|| Default Password : admin" + echo "=====================================" + echo "=====================================" +else + echo "+=================================+" + echo "||===== Install Completed =====||" + echo "|| Access the main Shinobi panel at http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080 in your web browser." + echo "+=================================+" +fi \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..20d40b6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..03c1f9f --- /dev/null +++ b/README.md @@ -0,0 +1,146 @@ +# Shinobi Pro +### (Creative Commons v4.0) + +Shinobi is the Open Source CCTV Solution written in Node.JS. Designed with multiple account system, Streams by WebSocket, and Save to WebM. Shinobi can record IP Cameras and Local Cameras. + + + +# Key Aspects + +For an updated list of features visit the official website. http://shinobi.video/features + +- Time-lapse Viewer (Watch a hours worth of footage in a few minutes) +- 2-Factor Authentication +- Defeats stream limit imposed by browsers + - With Base64 (Stream Type) and JPEG Mode (Option) +- Records IP Cameras and Local Cameras +- Streams by WebSocket, HLS (includes audio), and MJPEG +- Save to WebM and MP4 + - Can save Audio +- Push Events - When a video is finished it will appear in the dashboard without a refresh +- Region Motion Detection (Similar to ZoneMinder Zone Detection) + - Represented by a Motion Guage on each monitor +- "No Motion" Notifications +- 1 Process for Each Camera to do both, Recording and Streaming +- Timeline for viewing Motion Events and Videos +- Sub-Accounts with permissions + - Monitor Viewing + - Monitor Editing + - Video Deleting + - Separate API keys for sub account +- Cron Filters can be set based on master account +- Stream Analyzer built-in (FFprobe GUI) +- Monitor Groups +- Can snapshot images from stream directly +- Lower Bandwith Mode (JPEG Mode) + - Snapshot (cgi-bin) must be enabled in Monitor Settings +- Control Cameras from Interface +- API + - Get videos + - Get monitors + - Change monitor modes : Disabled, Watch, Record + - Embedding streams +- Dashboard Framework made with Google Material Design Lite, jQuery, and Bootstrap + +## Asking for help + +Before asking questions it would nice if you read the docs :) http://shinobi.video + +After doing so please head on over to the Discord community chat for support. https://discordapp.com/invite/mdhmvuH + +The Issues section is only for bugs with the software. Comments and feature requests may be closed without comment. http://shinobi.video/docs/contribute + +Please be considerate of developer efforts. If you have simple questions, like "what does this button do?", please be sure to have read the docs entirely before asking. If you would like to skip reading the docs and ask away you can order a support package :) http://shinobi.video/support + +## Making Suggestions or Feature Requests + +You can post suggestions on the Forum in the Suggestions category. Please do not treat this channel like a "demands" window. Developer efforts are limited. Much more than many alternatives. + +when you have a suggestion please try and make the changes yourself then post a pull request to the `dev` branch. Then we can decide if it's a good change for Shinobi. If you don't know how to go about it and want to have me put it higher on my priority list you can order a support package :) Pretty Ferengi of me... but until we live in a world without money please support Shinobi :) Cheers! + +http://shinobi.video/support + +## Help make Shinobi the best Open Source CCTV Solution. +Donate - http://shinobi.video/docs/donate + +Ordering a License, Paid Support, or anything from here will allow a lot more time to be spent on Shinobi. + +Order Support - http://shinobi.video/support + +# Why make this? + +http://shinobi.video/why + +# What others say + +> "After trying zoneminder without success (heavy unstable and slow) I passed to Shinobi that despite being young spins a thousand times better (I have a setup with 16 cameras recording in FHD to ~ 10fps on a pentium of ~ 2009 and I turn with load below 1.5)." + +> *A Reddit user, /r/ItalyInformatica* + +  + +> "I would suggest Shinobi as a NVR. It's still in the early days but works a lot better than ZoneMinder for me. I'm able to record 16 cams at 1080p 15fps continously whith no load on server (Pentium E5500 3GB RAM) where zm crashed with 6 cams at 720p. Not to mention the better interface." + +> *A Reddit user, /r/HomeNetworking* + +# How to Install and Run + +> FOR DOCKER USERS : Docker is not officially supported and is not recommended. The kitematic method is provided for those who wish to quickly test Shinobi. The Docker files included in the master and dev branches are maintained by the community. If you would like support with Docker please find a community member who maintains the Docker files or please refer to Docker's forum. + +#### Fast Install (The Ninja Way) + +1. Become `root` to use the installer and run Shinobi. Use one of the following to do so. + + - Ubuntu 17.04, 17.10 + - `sudo su` + - CentOS 7 + - `su` + - MacOS 10.7(+) + - `su` +2. Download and run the installer. + +``` +bash <(curl -s https://raw.githubusercontent.com/ShinobiCCTV/Shinobi-Installer/master/shinobi-install.sh) +``` + +#### Elaborate Installs + +Installation Tutorials - http://shinobi.video/docs/start + +Troubleshooting Guide - http://shinobi.video/docs/start#trouble-section + +# Author + +Moe Alam + +Follow Shinobi on Twitter https://twitter.com/ShinobiCCTV + +Join the Community Chat + + + +# Support the Development + +Ordering a certificate or support package greatly boosts development. Please consider contributing :) + +http://shinobi.video/support + +# Links + +Documentation - http://shinobi.video/docs + +Donate - https://shinobi.video/docs/donate + +Tested Cameras and Systems - http://shinobi.video/docs/supported + +Features - http://shinobi.video/features + +Reddit (Forum) - https://www.reddit.com/r/ShinobiCCTV/ + +YouTube (Tutorials) - https://www.youtube.com/channel/UCbgbBLTK-koTyjOmOxA9msQ + +Discord (Community Chat) - https://discordapp.com/invite/mdhmvuH + +Twitter (News) - https://twitter.com/ShinobiCCTV + +Facebook (News) - https://www.facebook.com/Shinobi-1223193167773738/?ref=bookmarks \ No newline at end of file diff --git a/UPDATE.sh b/UPDATE.sh new file mode 100644 index 0000000..04b7a30 --- /dev/null +++ b/UPDATE.sh @@ -0,0 +1,24 @@ +#!/bin/bash +distro=$1 +repo=$2 +if [ -z "$distro" ]; then + distro='master' +fi +if [ -z "$repo" ]; then + repo='ShinobiCCTV' +fi +if [ "$repo" = "ShinobiCCTV" ]; then + productName="Shinobi Professional (Pro)" +else + productName="Shinobi Community Editon (CE)" +fi +git reset --hard +git pull +gitURL="https://github.com/$repo/Shinobi" +gitVersionNumber=$(git rev-parse HEAD) +theDateRightNow=$(date) +rm version.json +touch version.json +chmod 755 version.json +echo '{"Product" : "'"$productName"'" , "Branch" : "'"$distro"'" , "Version" : "'"$gitVersionNumber"'" , "Date" : "'"$theDateRightNow"'" , "Repository" : "'"$gitURL"'"}' > version.json +echo "Restart Shinobi for updates to take effect." \ No newline at end of file diff --git a/camera.js b/camera.js new file mode 100644 index 0000000..1e4e029 --- /dev/null +++ b/camera.js @@ -0,0 +1,6795 @@ +// +// Shinobi +// Copyright (C) 2016 Moe Alam, moeiscool +// +// +// # Donate +// +// If you like what I am doing here and want me to continue please consider donating :) +// PayPal : paypal@m03.ca +// +var fs = require('fs'); +process.on('uncaughtException', function (err) { + console.error('Uncaught Exception occured!'); + console.error(err.stack); +}); +var staticFFmpeg = false; +try{ + staticFFmpeg = require('ffmpeg-static').path; + if (!fs.existsSync(staticFFmpeg)) { + staticFFmpeg = false + console.log('"ffmpeg-static" from NPM has failed to provide a compatible library or has been corrupted.') + console.log('You may need to install FFmpeg manually or you can try running "npm uninstall ffmpeg-static && npm install ffmpeg-static".') + } +}catch(err){ + staticFFmpeg = false; + console.log('No Static FFmpeg. Continuing.') + //no static ffmpeg +} +var os = require('os'); +var URL = require('url'); +var path = require('path'); +var mysql = require('mysql'); +var moment = require('moment'); +var request = require("request"); +var express = require('express'); +var app = express(); +var http = require('http'); +var https = require('https'); +var server = http.createServer(app); +var bodyParser = require('body-parser'); +var CircularJSON = require('circular-json'); +var ejs = require('ejs'); +var io = new (require('socket.io'))(); +var execSync = require('child_process').execSync; +var exec = require('child_process').exec; +var spawn = require('child_process').spawn; +var socketIOclient = require('socket.io-client'); +var crypto = require('crypto'); +var webdav = require("webdav"); +var jsonfile = require("jsonfile"); +var connectionTester = require('connection-tester'); +var events = require('events'); +var onvif = require('node-onvif'); +var knex = require('knex'); +var Mp4Frag = require('mp4frag'); +var P2P = require('pipe2pam'); +var PamDiff = require('pam-diff'); +var httpProxy = require('http-proxy'); +var proxy = httpProxy.createProxyServer({}) +var location = {} +location.super = __dirname+'/super.json' +location.config = __dirname+'/conf.json' +location.languages = __dirname+'/languages' +location.definitions = __dirname+'/definitions' +var config = require(location.config); +if(!config.productType){ + config.productType='CE' +} +if(config.productType==='Pro'){ + var LdapAuth = require('ldapauth-fork'); +} +if(!config.language){ + config.language='en_CA' +} +try{ + var lang = require(location.languages+'/'+config.language+'.json'); +}catch(er){ + console.error(er) + console.log('There was an error loading your language file.') + var lang = require(location.languages+'/en_CA.json'); +} +try{ + var definitions = require(location.definitions+'/'+config.language+'.json'); +}catch(er){ + console.error(er) + console.log('There was an error loading your language file.') + var definitions = require(location.definitions+'/en_CA.json'); +} +process.send = process.send || function () {}; +if(config.mail){ + var nodemailer = require('nodemailer').createTransport(config.mail); +} +//config defaults +if(config.cpuUsageMarker===undefined){config.cpuUsageMarker='%Cpu'} +if(config.customCpuCommand===undefined){config.customCpuCommand=null} +if(config.autoDropCache===undefined){config.autoDropCache=true} +if(config.doSnapshot===undefined){config.doSnapshot=true} +if(config.restart===undefined){config.restart={}} +if(config.systemLog===undefined){config.systemLog=true} +if(config.deleteCorruptFiles===undefined){config.deleteCorruptFiles=true} +if(config.restart.onVideoNotExist===undefined){config.restart.onVideoNotExist=true} +if(config.ip===undefined||config.ip===''||config.ip.indexOf('0.0.0.0')>-1){config.ip='localhost'}else{config.bindip=config.ip}; +if(config.cron===undefined)config.cron={}; +if(config.cron.enabled===undefined)config.cron.enabled=true; +if(config.cron.deleteOld===undefined)config.cron.deleteOld=true; +if(config.cron.deleteOrphans===undefined)config.cron.deleteOrphans=false; +if(config.cron.deleteNoVideo===undefined)config.cron.deleteNoVideo=true; +if(config.cron.deleteNoVideoRecursion===undefined)config.cron.deleteNoVideoRecursion=false; +if(config.cron.deleteOverMax===undefined)config.cron.deleteOverMax=true; +if(config.cron.deleteOverMaxOffset===undefined)config.cron.deleteOverMaxOffset=0.9; +if(config.cron.deleteLogs===undefined)config.cron.deleteLogs=true; +if(config.cron.deleteEvents===undefined)config.cron.deleteEvents=true; +if(config.cron.deleteFileBins===undefined)config.cron.deleteFileBins=true; +if(config.cron.interval===undefined)config.cron.interval=1; +if(config.databaseType===undefined){config.databaseType='mysql'} +if(config.pluginKeys===undefined)config.pluginKeys={}; +if(config.databaseLogs===undefined){config.databaseLogs=false} +if(config.useUTC===undefined){config.useUTC=false} +if(config.pipeAddition===undefined){config.pipeAddition=7}else{config.pipeAddition=parseInt(config.pipeAddition)} +//Web Paths +if(config.webPaths===undefined){config.webPaths={}} + //main access URI + if(config.webPaths.home===undefined){config.webPaths.index='/'} + //Super User URI + if(config.webPaths.super===undefined){config.webPaths.super='/super'} + //Admin URI + if(config.webPaths.admin===undefined){config.webPaths.admin='/admin'} +//Page Rander Paths +if(config.renderPaths===undefined){config.renderPaths={}} + //login page + if(config.renderPaths.index===undefined){config.renderPaths.index='pages/index'} + //dashboard page + if(config.renderPaths.home===undefined){config.renderPaths.home='pages/home'} + //sub-account administration page + if(config.renderPaths.admin===undefined){config.renderPaths.admin='pages/admin'} + //superuser page + if(config.renderPaths.super===undefined){config.renderPaths.super='pages/super'} + //2-Factor Auth page + if(config.renderPaths.factorAuth===undefined){config.renderPaths.factorAuth='pages/factor'} + //Streamer (Dashbcam Prototype) page + if(config.renderPaths.streamer===undefined){config.renderPaths.streamer='pages/streamer'} + //Streamer v2 (Dashbcam) page + if(config.renderPaths.dashcam===undefined){config.renderPaths.dashcam='pages/dashcam'} + //embeddable widget page + if(config.renderPaths.embed===undefined){config.renderPaths.embed='pages/embed'} + //mjpeg full screen page + if(config.renderPaths.mjpeg===undefined){config.renderPaths.mjpeg='pages/mjpeg'} + //gridstack only page + if(config.renderPaths.grid===undefined){config.renderPaths.grid='pages/grid'} +//Child Nodes +if(config.childNodes===undefined)config.childNodes = {}; + //enabled + if(config.childNodes.enabled===undefined)config.childNodes.enabled = false; + //mode, set value as `child` for all other machines in the cluster + if(config.childNodes.mode===undefined)config.childNodes.mode = 'master'; + //child node connection port + if(config.childNodes.port===undefined)config.childNodes.port = 8288; + //child node connection key + if(config.childNodes.key===undefined)config.childNodes.key = [ + '3123asdasdf1dtj1hjk23sdfaasd12asdasddfdbtnkkfgvesra3asdsd3123afdsfqw345' + ]; + + +s={ + factorAuth : {}, + totalmem : os.totalmem(), + platform : os.platform(), + s : JSON.stringify, + isWin : (process.platform==='win32'), + utcOffset : moment().utcOffset() +}; +//load languages dynamically +s.loadedLanguages={} +s.loadedLanguages[config.language]=lang; +s.getLanguageFile=function(rule){ + if(rule&&rule!==''){ + var file=s.loadedLanguages[file] + if(!file){ + try{ + s.loadedLanguages[rule]=require(location.languages+'/'+rule+'.json') + file=s.loadedLanguages[rule] + }catch(err){ + file=lang + } + } + }else{ + file=lang + } + return file +} +//load defintions dynamically +s.loadedDefinitons={} +s.loadedDefinitons[config.language]=definitions; +s.getDefinitonFile=function(rule){ + if(rule&&rule!==''){ + var file=s.loadedDefinitons[file] + if(!file){ + try{ + s.loadedDefinitons[rule]=require(location.definitions+'/'+rule+'.json') + file=s.loadedDefinitons[rule] + }catch(err){ + file=definitions + } + } + }else{ + file=definitions + } + return file +} +var databaseOptions = { + client: config.databaseType, + connection: config.db, +} +if(databaseOptions.client.indexOf('sqlite')>-1){ + databaseOptions.client = 'sqlite3'; + databaseOptions.useNullAsDefault = true; +} +if(databaseOptions.client === 'sqlite3' && databaseOptions.connection.filename === undefined){ + databaseOptions.connection.filename = __dirname+"/shinobi.sqlite" +} +s.databaseEngine = knex(databaseOptions) +s.sqlDate = function(value){ + var dateQueryFunction = '' + if(databaseOptions.client === 'sqlite3'){ + value = value.toLowerCase() + if (value.slice(-1) !== 's') { + value = value+'s' + } + dateQueryFunction = "datetime('now', '-"+value+"')" + }else{ + value = value.toUpperCase() + if (value.slice(-1) === 'S') { + value = value.slice(0, -1); + } + dateQueryFunction = "DATE_SUB(NOW(), INTERVAL "+value+")" + } + return dateQueryFunction +} +s.mergeQueryValues = function(query,values){ + if(!values){values=[]} + var valuesNotFunction = true; + if(typeof values === 'function'){ + var onMoveOn = values; + var values = []; + valuesNotFunction = false; + } + if(!onMoveOn){onMoveOn=function(){}} + if(values&&valuesNotFunction){ + var splitQuery = query.split('?') + var newQuery = '' + splitQuery.forEach(function(v,n){ + newQuery += v + if(values[n]){ + if(isNaN(values[n])){ + newQuery += "'"+values[n]+"'" + }else{ + newQuery += values[n] + } + } + }) + }else{ + newQuery = query + } + return newQuery +} +s.sqlQuery = function(query,values,onMoveOn,hideLog){ + if(!values){values=[]} + if(typeof values === 'function'){ + var onMoveOn = values; + var values = []; + } + if(!onMoveOn){onMoveOn=function(){}} + var mergedQuery = s.mergeQueryValues(query,values) + return s.databaseEngine.raw(query,values) + .asCallback(function(err,r){ + if(err&&config.databaseLogs){ + s.systemLog('s.sqlQuery QUERY',query) + s.systemLog('s.sqlQuery ERROR',err) + } + if(onMoveOn && typeof onMoveOn === 'function'){ + switch(databaseOptions.client){ + case'sqlite3': + if(!r)r=[] + break; + default: + if(r)r=r[0] + break; + } + onMoveOn(err,r) + } + }) +} +//kill any ffmpeg running +s.ffmpegKill=function(){ + var cmd='' + if(s.isWin===true){ + cmd="Taskkill /IM ffmpeg.exe /F" + }else{ + cmd="ps aux | grep -ie ffmpeg | awk '{print $2}' | xargs kill -9" + } + exec(cmd,{detached: true}) +}; +process.on('exit',s.ffmpegKill.bind(null,{cleanup:true})); +process.on('SIGINT',s.ffmpegKill.bind(null, {exit:true})); +s.checkRelativePath=function(x){ + if(x.charAt(0)!=='/'){ + x=__dirname+'/'+x + } + return x +} +s.checkCorrectPathEnding=function(x){ + var length=x.length + if(x.charAt(length-1)!=='/'){ + x=x+'/' + } + return x.replace('__DIR__',__dirname) +} +s.md5=function(x){return crypto.createHash('md5').update(x).digest("hex");} +//send data to detector plugin +s.ocvTx=function(data){ + if(!s.ocv){return} + if(s.ocv.isClientPlugin===true){ + s.tx(data,s.ocv.id) + }else{ + s.connectedPlugins[s.ocv.plug].tx(data) + } +} +//send data to socket client function +s.tx=function(z,y,x){if(x){return x.broadcast.to(y).emit('f',z)};io.to(y).emit('f',z);} +s.txWithSubPermissions=function(z,y,permissionChoices){ + if(typeof permissionChoices==='string'){ + permissionChoices=[permissionChoices] + } + if(s.group[z.ke]){ + Object.keys(s.group[z.ke].users).forEach(function(v){ + var user = s.group[z.ke].users[v] + if(user.details.sub){ + if(user.details.allmonitors!=='1'){ + var valid=0 + var checked=permissionChoices.length + permissionChoices.forEach(function(b){ + if(user.details[b].indexOf(z.mid)!==-1){ + ++valid + } + }) + if(valid===checked){ + s.tx(z,user.cnid) + } + }else{ + s.tx(z,user.cnid) + } + }else{ + s.tx(z,user.cnid) + } + }) + } +} +//load camera controller vars +s.nameToTime=function(x){x=x.split('.')[0].split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;} +s.ratio=function(width,height,ratio){ratio = width / height;return ( Math.abs( ratio - 4 / 3 ) < Math.abs( ratio - 16 / 9 ) ) ? '4:3' : '16:9';} +s.randomNumber=function(x){ + if(!x){x=10}; + return Math.floor((Math.random() * x) + 1); +}; +s.gid=function(x){ + if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.nid=function(x){ + if(!x){x=6};var t = "";var p = "0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.formattedTime_withOffset=function(e,x){ + if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'}; + e=s.timeObject(e);if(config.utcOffset){e=e.utcOffset(config.utcOffset)} + return e.format(x); +} +s.formattedTime=function(e,x){ + if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'}; + return s.timeObject(e).format(x); +} +s.utcToLocal = function(time){ + return moment.utc(time).utcOffset(s.utcOffset).format() +} +s.localTimeObject = function(e,x){ + return moment(e) +} +if(config.useUTC === true){ + s.timeObject = function(time){ + return moment(time).utc() + } +}else{ + s.timeObject = moment +} +console.log('config.useUTC',config.useUTC) +s.ipRange=function(start_ip, end_ip) { + var start_long = s.toLong(start_ip); + var end_long = s.toLong(end_ip); + if (start_long > end_long) { + var tmp=start_long; + start_long=end_long + end_long=tmp; + } + var range_array = []; + var i; + for (i=start_long; i<=end_long;i++) { + range_array.push(s.fromLong(i)); + } + return range_array; +} +s.portRange=function(lowEnd,highEnd){ + var list = []; + for (var i = lowEnd; i <= highEnd; i++) { + list.push(i); + } + return list; +} +//toLong taken from NPM package 'ip' +s.toLong=function(ip) { + var ipl = 0; + ip.split('.').forEach(function(octet) { + ipl <<= 8; + ipl += parseInt(octet); + }); + return(ipl >>> 0); +}; + +//fromLong taken from NPM package 'ip' +s.fromLong=function(ipl) { + return ((ipl >>> 24) + '.' + + (ipl >> 16 & 255) + '.' + + (ipl >> 8 & 255) + '.' + + (ipl & 255) ); +}; +s.getFunctionParamNames = function(func) { + var fnStr = func.toString().replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, ''); + var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(/([^\s,]+)/g); + if(result === null) + result = []; + return result; +} +s.createPamDiffRegionArray = function(regions,globalSensitivity,fullFrame){ + var pamDiffCompliantArray = [], + arrayForOtherStuff = [], + json + try{ + json = JSON.parse(regions) + }catch(err){ + json = regions + } + if(fullFrame){ + json[fullFrame.name]=fullFrame; + } + Object.values(json).forEach(function(region){ + region.polygon = []; + region.points.forEach(function(points){ + region.polygon.push({x:parseFloat(points[0]),y:parseFloat(points[1])}) + }) + if(region.sensitivity===''){ + region.sensitivity = globalSensitivity + }else{ + region.sensitivity = parseInt(region.sensitivity) + } + pamDiffCompliantArray.push({name: region.name, difference: 9, percent: region.sensitivity, polygon:region.polygon}) + arrayForOtherStuff[region.name] = region; + }) + if(pamDiffCompliantArray.length===0){pamDiffCompliantArray = null} + return {forPam:pamDiffCompliantArray,notForPam:arrayForOtherStuff}; +} +s.getRequest = function(url,callback){ + return http.get(url, function(res){ + var body = ''; + res.on('data', function(chunk){ + body += chunk; + }); + res.on('end',function(){ + try{body = JSON.parse(body)}catch(err){} + callback(body) + }); + }).on('error', function(e){ +// s.systemLog("Get Snapshot Error", e); + }); +} +s.kill=function(x,e,p){ + if(s.group[e.ke]&&s.group[e.ke].mon[e.id]&&s.group[e.ke].mon[e.id].spawn !== undefined){ + if(s.group[e.ke].mon[e.id].spawn){ + s.group[e.ke].mon[e.id].spawn.stdio[3].unpipe(); +// if(s.group[e.ke].mon[e.id].p2pStream){s.group[e.ke].mon[e.id].p2pStream.unpipe();} + if(s.group[e.ke].mon[e.id].p2p){s.group[e.ke].mon[e.id].p2p.unpipe();} + delete(s.group[e.ke].mon[e.id].p2pStream) + delete(s.group[e.ke].mon[e.id].p2p) + delete(s.group[e.ke].mon[e.id].pamDiff) + try{ + s.group[e.ke].mon[e.id].spawn.removeListener('end',s.group[e.ke].mon[e.id].spawn_exit); + s.group[e.ke].mon[e.id].spawn.removeListener('exit',s.group[e.ke].mon[e.id].spawn_exit); + delete(s.group[e.ke].mon[e.id].spawn_exit); + }catch(er){} + } + clearTimeout(s.group[e.ke].mon[e.id].checker); + delete(s.group[e.ke].mon[e.id].checker); + clearTimeout(s.group[e.ke].mon[e.id].checkStream); + delete(s.group[e.ke].mon[e.id].checkStream); + clearTimeout(s.group[e.ke].mon[e.id].watchdog_stop); + delete(s.group[e.ke].mon[e.id].watchdog_stop); + delete(s.group[e.ke].mon[e.id].lastJpegDetectorFrame); + if(e&&s.group[e.ke].mon[e.id].record){ + clearTimeout(s.group[e.ke].mon[e.id].record.capturing); +// if(s.group[e.ke].mon[e.id].record.request){s.group[e.ke].mon[e.id].record.request.abort();delete(s.group[e.ke].mon[e.id].record.request);} + }; + if(s.group[e.ke].mon[e.id].childNode){ + s.cx({f:'kill',d:s.init('noReference',e)},s.group[e.ke].mon[e.id].childNodeId) + }else{ + if(!x||x===1){return}; + p=x.pid; + if(s.group[e.ke].mon_conf[e.id].type===('dashcam'||'socket'||'jpeg'||'pipe')){ + x.stdin.pause();setTimeout(function(){x.kill('SIGTERM');delete(x);},500) + }else{ + try{ + x.stdin.setEncoding('utf8');x.stdin.write('q'); + }catch(er){} + } + setTimeout(function(){exec('kill -9 '+p,{detached: true})},1000) + } + } +} +//user log +s.log=function(e,x){ + if(!x||!e.mid){return} + if((e.details&&e.details.sqllog==='1')||e.mid.indexOf('$')>-1){ + s.sqlQuery('INSERT INTO Logs (ke,mid,info) VALUES (?,?,?)',[e.ke,e.mid,s.s(x)]); + } + s.tx({f:'log',ke:e.ke,mid:e.mid,log:x,time:s.timeObject()},'GRPLOG_'+e.ke); +// s.systemLog('s.log : ',{f:'log',ke:e.ke,mid:e.mid,log:x,time:s.timeObject()},'GRP_'+e.ke) +} +//system log +s.systemLog=function(q,w,e){ + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + if(typeof q==='string'&&s.databaseEngine){ + s.sqlQuery('INSERT INTO Logs (ke,mid,info) VALUES (?,?,?)',['$','$SYSTEM',s.s({type:q,msg:w})]); + s.tx({f:'log',log:{time:s.timeObject(),ke:'$',mid:'$SYSTEM',time:s.timeObject(),info:s.s({type:q,msg:w})}},'$'); + } + return console.log(s.timeObject().format(),q,w,e) + } +} +//SSL options +if(config.ssl&&config.ssl.key&&config.ssl.cert){ + config.ssl.key=fs.readFileSync(s.checkRelativePath(config.ssl.key),'utf8') + config.ssl.cert=fs.readFileSync(s.checkRelativePath(config.ssl.cert),'utf8') + if(config.ssl.port===undefined){ + config.ssl.port=443 + } + if(config.ssl.bindip===undefined){ + config.ssl.bindip=config.bindip + } + if(config.ssl.ca&&config.ssl.ca instanceof Array){ + config.ssl.ca.forEach(function(v,n){ + config.ssl.ca[n]=fs.readFileSync(s.checkRelativePath(v),'utf8') + }) + } + var serverHTTPS = https.createServer(config.ssl,app); + serverHTTPS.listen(config.ssl.port,config.bindip,function(){ + console.log('SSL '+lang.Shinobi+' - SSL PORT : '+config.ssl.port); + }); + io.attach(serverHTTPS); +} +//start HTTP +server.listen(config.port,config.bindip,function(){ + console.log(lang.Shinobi+' - PORT : '+config.port); +}); +io.attach(server); +console.log('NODE.JS version : '+execSync("node -v")) +//ffmpeg location +if(!config.ffmpegDir){ + if(staticFFmpeg !== false){ + config.ffmpegDir = staticFFmpeg + }else{ + if(s.isWin===true){ + config.ffmpegDir = __dirname+'/ffmpeg/ffmpeg.exe' + }else{ + config.ffmpegDir = 'ffmpeg' + } + } +} +//ffmpeg version +s.ffmpegVersion=execSync(config.ffmpegDir+" -version").toString().split('Copyright')[0].replace('ffmpeg version','').trim() +console.log('FFMPEG version : '+s.ffmpegVersion) +if(s.ffmpegVersion.indexOf(': 2.')>-1){ + s.systemLog('FFMPEG is too old : '+s.ffmpegVersion+', Needed : 3.2+',err) + return +} +//directories +s.group={}; +if(!config.windowsTempDir&&s.isWin===true){config.windowsTempDir='C:/Windows/Temp'} +if(!config.defaultMjpeg){config.defaultMjpeg=__dirname+'/web/libs/img/bg.jpg'} +//default stream folder check +if(!config.streamDir){ + if(s.isWin===false){ + config.streamDir='/dev/shm' + }else{ + config.streamDir=config.windowsTempDir + } + if(!fs.existsSync(config.streamDir)){ + config.streamDir=__dirname+'/streams/' + }else{ + config.streamDir+='/streams/' + } +} +if(!config.videosDir){config.videosDir=__dirname+'/videos/'} +if(!config.binDir){config.binDir=__dirname+'/fileBin/'} +if(!config.addStorage){config.addStorage=[]} +s.dir={ + videos:s.checkCorrectPathEnding(config.videosDir), + streams:s.checkCorrectPathEnding(config.streamDir), + fileBin:s.checkCorrectPathEnding(config.binDir), + addStorage:config.addStorage, + languages:location.languages+'/' +}; +//streams dir +if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); +} +//videos dir +if(!fs.existsSync(s.dir.videos)){ + fs.mkdirSync(s.dir.videos); +} +//fileBin dir +if(!fs.existsSync(s.dir.fileBin)){ + fs.mkdirSync(s.dir.fileBin); +} +//additional storage areas +s.dir.addStorage.forEach(function(v,n){ + v.path=s.checkCorrectPathEnding(v.path) + if(!fs.existsSync(v.path)){ + fs.mkdirSync(v.path); + } +}) +////Camera Controller +s.init=function(x,e,k,fn){ + if(!e){e={}} + if(!k){k={}} + switch(x){ + case 0://init camera + if(!s.group[e.ke]){s.group[e.ke]={}}; + if(!s.group[e.ke].fileBin){s.group[e.ke].fileBin={}}; + if(!s.group[e.ke].mon){s.group[e.ke].mon={}} + if(!s.group[e.ke].sizeChangeQueue){s.group[e.ke].sizeChangeQueue=[]} + if(!s.group[e.ke].sizePurgeQueue){s.group[e.ke].sizePurgeQueue=[]} + if(!s.group[e.ke].users){s.group[e.ke].users={}} + if(!s.group[e.ke].mon[e.mid]){s.group[e.ke].mon[e.mid]={}} + if(!s.group[e.ke].mon[e.mid].streamIn){s.group[e.ke].mon[e.mid].streamIn={}}; + if(!s.group[e.ke].mon[e.mid].emitterChannel){s.group[e.ke].mon[e.mid].emitterChannel={}}; + if(!s.group[e.ke].mon[e.mid].mp4frag){s.group[e.ke].mon[e.mid].mp4frag={}}; + if(!s.group[e.ke].mon[e.mid].firstStreamChunk){s.group[e.ke].mon[e.mid].firstStreamChunk={}}; + if(!s.group[e.ke].mon[e.mid].contentWriter){s.group[e.ke].mon[e.mid].contentWriter={}}; + if(!s.group[e.ke].mon[e.mid].childNodeStreamWriters){s.group[e.ke].mon[e.mid].childNodeStreamWriters={}}; + if(!s.group[e.ke].mon[e.mid].eventBasedRecording){s.group[e.ke].mon[e.mid].eventBasedRecording={}}; + if(!s.group[e.ke].mon[e.mid].watch){s.group[e.ke].mon[e.mid].watch={}}; + if(!s.group[e.ke].mon[e.mid].fixingVideos){s.group[e.ke].mon[e.mid].fixingVideos={}}; + if(!s.group[e.ke].mon[e.mid].record){s.group[e.ke].mon[e.mid].record={yes:e.record}}; + if(!s.group[e.ke].mon[e.mid].started){s.group[e.ke].mon[e.mid].started=0}; + if(s.group[e.ke].mon[e.mid].delete){clearTimeout(s.group[e.ke].mon[e.mid].delete)} + if(!s.group[e.ke].mon_conf){s.group[e.ke].mon_conf={}} + s.init('apps',e) + break; + case'group': + if(!s.group[e.ke]){ + s.group[e.ke]={} + } + if(!s.group[e.ke].init){ + s.group[e.ke].init={} + } + if(!e.limit||e.limit===''){e.limit=10000}else{e.limit=parseFloat(e.limit)} + //save global space limit for group key (mb) + s.group[e.ke].sizeLimit=e.limit; + //save global used space as megabyte value + s.group[e.ke].usedSpace=e.size/1000000; + //emit the changes to connected users + s.init('diskUsedEmit',e) + break; + case'apps': + if(!s.group[e.ke].init){ + s.group[e.ke].init={}; + } + if(!s.group[e.ke].webdav||!s.group[e.ke].sizeLimit){ + s.sqlQuery('SELECT * FROM Users WHERE ke=? AND details NOT LIKE ?',[e.ke,'%"sub"%'],function(ar,r){ + if(r&&r[0]){ + r=r[0]; + ar=JSON.parse(r.details); + //owncloud/webdav + if(ar.webdav_user&& + ar.webdav_user!==''&& + ar.webdav_pass&& + ar.webdav_pass!==''&& + ar.webdav_url&& + ar.webdav_url!=='' + ){ + if(!ar.webdav_dir||ar.webdav_dir===''){ + ar.webdav_dir='/'; + if(ar.webdav_dir.slice(-1)!=='/'){ar.webdav_dir+='/';} + } + s.group[e.ke].webdav = webdav( + ar.webdav_url, + ar.webdav_user, + ar.webdav_pass + ); + } + Object.keys(ar).forEach(function(v){ + s.group[e.ke].init[v]=ar[v] + }) + } + }); + } + break; + case'sync': + e.cn=Object.keys(s.childNodes); + e.cn.forEach(function(v){ + if(s.group[e.ke]){ + s.cx({f:'sync',sync:s.init('noReference',s.group[e.ke].mon_conf[e.mid]),ke:e.ke,mid:e.mid},s.childNodes[v].cnid); + } + }); + break; + case'noReference': + x={keys:Object.keys(e),ar:{}}; + x.keys.forEach(function(v){ + if(v!=='last_frame'&&v!=='record'&&v!=='spawn'&&v!=='running'&&(v!=='time'&&typeof e[v]!=='function')){x.ar[v]=e[v];} + }); + return x.ar; + break; + case'url': + //build a complete url from pieces + e.authd=''; + if(e.details.muser&&e.details.muser!==''&&e.host.indexOf('@')===-1) { + e.authd=e.details.muser+':'+e.details.mpass+'@'; + } + if(e.port==80&&e.details.port_force!=='1'){e.porty=''}else{e.porty=':'+e.port} + e.url=e.protocol+'://'+e.authd+e.host+e.porty+e.path;return e.url; + break; + case'url_no_path': + e.authd=''; + if(!e.details.muser){e.details.muser=''} + if(!e.details.mpass){e.details.mpass=''} + if(e.details.muser!==''&&e.host.indexOf('@')===-1) { + e.authd=e.details.muser+':'+e.details.mpass+'@'; + } + if(e.port==80&&e.details.port_force!=='1'){e.porty=''}else{e.porty=':'+e.port} + e.url=e.protocol+'://'+e.authd+e.host+e.porty;return e.url; + break; + case'diskUsedEmit': + //send the amount used disk space to connected users + if(s.group[e.ke]&&s.group[e.ke].init){ + s.tx({f:'diskUsed',size:s.group[e.ke].usedSpace,limit:s.group[e.ke].sizeLimit},'GRP_'+e.ke); + } + break; + case'diskUsedSet': + //`k` will be used as the value to add or substract + s.group[e.ke].sizeChangeQueue.push(k) + if(s.group[e.ke].sizeChanging!==true){ + //lock this function + s.group[e.ke].sizeChanging=true + //validate current values + if(!s.group[e.ke].usedSpace){ + s.group[e.ke].usedSpace=0 + }else{ + s.group[e.ke].usedSpace=parseFloat(s.group[e.ke].usedSpace) + } + if(s.group[e.ke].usedSpace<0||isNaN(s.group[e.ke].usedSpace)){ + s.group[e.ke].usedSpace=0 + } + //set queue processor + var checkQueue=function(){ + //get first in queue + var currentChange = s.group[e.ke].sizeChangeQueue[0] + //change global size value + s.group[e.ke].usedSpace=s.group[e.ke].usedSpace+currentChange + //remove value just used from queue + s.group[e.ke].sizeChangeQueue = s.group[e.ke].sizeChangeQueue.splice(1,s.group[e.ke].sizeChangeQueue.length+10) + //do next one + if(s.group[e.ke].sizeChangeQueue.length>0){ + checkQueue() + }else{ + s.group[e.ke].sizeChanging=false + s.init('diskUsedEmit',e) + } + } + checkQueue() + } + break; + } + if(typeof e.callback==='function'){setTimeout(function(){e.callback()},500);} +} +s.filterEvents=function(x,d){ + switch(x){ + case'archive': + d.videos.forEach(function(v,n){ + s.video('archive',v) + }) + break; + case'email': + if(d.videos&&d.videos.length>0){ + d.videos.forEach(function(v,n){ + + }) + d.mailOptions = { + from: '"ShinobiCCTV" ', // sender address + to: d.mail, // list of receivers + subject: lang['Filter Matches']+' : '+d.name, // Subject line + html: lang.FilterMatchesText1+' '+d.videos.length+' '+lang.FilterMatchesText2, + }; + if(d.execute&&d.execute!==''){ + d.mailOptions.html+='
'+lang.Executed+' : '+d.execute+'
' + } + if(d.delete==='1'){ + d.mailOptions.html+='
'+lang.Deleted+' : '+lang.Yes+'
' + } + d.mailOptions.html+='
'+lang.Query+' : '+d.query+'
' + d.mailOptions.html+='
'+lang['Filter ID']+' : '+d.id+'
' + nodemailer.sendMail(d.mailOptions, (error, info) => { + if (error) { + s.tx({f:'error',ff:'filter_mail',ke:d.ke,error:error},'GRP_'+d.ke); + return ; + } + s.tx({f:'filter_mail',ke:d.ke,info:info},'GRP_'+d.ke); + }); + } + break; + case'delete': + d.videos.forEach(function(v,n){ + s.video('delete',v) + }) + break; + case'execute': + exec(d.execute,{detached: true}) + break; + } +} +s.video=function(x,e,k){ + if(!e){e={}}; + switch(x){ + case'getDir': + if(e.mid&&!e.id){e.id=e.mid}; + if(e.details&&(e.details instanceof Object)===false){ + try{e.details=JSON.parse(e.details)}catch(err){} + } + if(e.details&&e.details.dir&&e.details.dir!==''){ + return s.checkCorrectPathEnding(e.details.dir)+e.ke+'/'+e.id+'/' + }else{ + return s.dir.videos+e.ke+'/'+e.id+'/'; + } + break; + } + if(!k)k={}; + if(x!=='getDir'){e.dir=s.video('getDir',e)} + switch(x){ + case'fix': + e.sdir=s.dir.streams+e.ke+'/'+e.id+'/'; + if(!e.filename&&e.time){e.filename=s.formattedTime(e.time)} + if(e.filename.indexOf('.')===-1){ + e.filename=e.filename+'.'+e.ext + } + s.tx({f:'video_fix_start',mid:e.mid,ke:e.ke,filename:e.filename},'GRP_'+e.ke) + s.group[e.ke].mon[e.id].fixingVideos[e.filename]={} + switch(e.ext){ + case'mp4': + e.fixFlags='-vcodec libx264 -acodec aac -strict -2'; + break; + case'webm': + e.fixFlags='-vcodec libvpx -acodec libvorbis'; + break; + } + e.spawn=spawn(config.ffmpegDir,('-i '+e.dir+e.filename+' '+e.fixFlags+' '+e.sdir+e.filename).split(' '),{detached: true}) + e.spawn.stdout.on('data',function(data){ + s.tx({f:'video_fix_data',mid:e.mid,ke:e.ke,filename:e.filename},'GRP_'+e.ke) + }); + e.spawn.on('close',function(data){ + exec('mv '+e.dir+e.filename+' '+e.sdir+e.filename,{detached: true}).on('exit',function(){ + s.tx({f:'video_fix_success',mid:e.mid,ke:e.ke,filename:e.filename},'GRP_'+e.ke) + delete(s.group[e.ke].mon[e.id].fixingVideos[e.filename]); + }) + }); + break; + case'archive': + if(!e.filename&&e.time){e.filename=s.formattedTime(e.time)} + if(!e.status){e.status=0} + e.details.archived="1" + e.save=[JSON.stringify(e.details),e.id,e.ke,s.nameToTime(e.filename)]; + s.sqlQuery('UPDATE Videos SET details=? WHERE `mid`=? AND `ke`=? AND `time`=?',e.save,function(err,r){ + s.tx({f:'video_edit',status:3,filename:e.filename+'.'+e.ext,mid:e.mid,ke:e.ke,time:s.nameToTime(e.filename)},'GRP_'+e.ke); + }); + break; + case'delete': + if(!e.filename&&e.time){e.filename=s.formattedTime(e.time)} + var filename + if(e.filename.indexOf('.')>-1){ + filename = e.filename + }else{ + filename = e.filename+'.'+e.ext + } + if(!e.status){e.status=0} + e.save=[e.id,e.ke,s.nameToTime(filename)]; + s.sqlQuery('SELECT * FROM Videos WHERE `mid`=? AND `ke`=? AND `time`=?',e.save,function(err,r){ + if(r&&r[0]){ + r=r[0] + var dir=s.video('getDir',r) + s.sqlQuery('DELETE FROM Videos WHERE `mid`=? AND `ke`=? AND `time`=?',e.save,function(){ + fs.stat(dir+filename,function(err,file){ + if(err){ + s.systemLog('File Delete Error : '+e.ke+' : '+' : '+e.mid,err) + } + s.init('diskUsedSet',e,-(r.size/1000000)) + }) + s.tx({f:'video_delete',filename:filename,mid:e.mid,ke:e.ke,time:s.nameToTime(filename),end:s.formattedTime(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke); + s.file('delete',dir+filename) + }) + } + }) + break; +// case'open': +// //on video open +// e.save=[e.id,e.ke,s.nameToTime(e.filename),e.ext]; +// if(!e.status){e.save.push(0)}else{e.save.push(e.status)} +// k.details={} +// if(e.details&&e.details.dir&&e.details.dir!==''){ +// k.details.dir=e.details.dir +// } +// e.save.push(s.s(k.details)) +// s.sqlQuery('INSERT INTO Videos (mid,ke,time,ext,status,details) VALUES (?,?,?,?,?,?)',e.save) +// s.tx({f:'video_build_start',filename:e.filename+'.'+e.ext,mid:e.id,ke:e.ke,time:s.nameToTime(e.filename),end:s.formattedTime(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke); +// break; +// case'close': +// //video function : close +// if(s.group[e.ke]&&s.group[e.ke].mon[e.id]){ +// if(s.group[e.ke].mon[e.id].open&&!e.filename){ +// e.filename=s.group[e.ke].mon[e.id].open; +// e.ext=s.group[e.ke].mon[e.id].open_ext +// } +// if(s.group[e.ke].mon[e.id].childNode){ +// s.cx({f:'close',d:s.init('noReference',e)},s.group[e.ke].mon[e.id].childNodeId); +// }else{ +// k.file = e.filename+'.'+e.ext +// k.dir = e.dir.toString() +// //get file directory +// k.fileExists = fs.existsSync(k.dir+k.file) +// if(k.fileExists!==true){ +// k.dir=s.dir.videos+'/'+e.ke+'/'+e.id+'/' +// k.fileExists=fs.existsSync(k.dir+k.file) +// if(k.fileExists!==true){ +// s.dir.addStorage.forEach(function(v){ +// if(k.fileExists!==true){ +// k.dir=s.checkCorrectPathEnding(v.path)+e.ke+'/'+e.id+'/' +// k.fileExists=fs.existsSync(k.dir+k.file) +// } +// }) +// } +// } +// if(k.fileExists===true){ +// //close video row +// k.stat = fs.statSync(k.dir+k.file) +// e.filesize = k.stat.size +// e.filesizeMB = parseFloat((e.filesize/1000000).toFixed(2)) +// e.end_time = s.formattedTime(k.stat.mtime,'YYYY-MM-DD HH:mm:ss') +// var save = [ +// e.filesize, +// 1, +// e.end_time, +// e.id, +// e.ke, +// s.nameToTime(e.filename) +// ] +// if(!e.status){ +// save.push(0) +// }else{ +// save.push(e.status) +// } +// s.sqlQuery('UPDATE Videos SET `size`=?,`status`=?,`end`=? WHERE `mid`=? AND `ke`=? AND `time`=? AND `status`=?',save) +// //send event for completed recording +// s.txWithSubPermissions({ +// f:'video_build_success', +// hrefNoAuth:'/videos/'+e.ke+'/'+e.mid+'/'+k.file, +// filename:k.file, +// mid:e.id, +// ke:e.ke, +// time:s.timeObject(s.nameToTime(e.filename)).format(), +// size:e.filesize, +// end:s.timeObject(e.end_time).format() +// },'GRP_'+e.ke,'video_view'); +// //send new diskUsage values +// s.video('diskUseUpdate',e,k) +// }else{ +// s.video('delete',e); +// s.log(e,{type:lang['File Not Exist'],msg:lang.FileNotExistText,ffmpeg:s.group[e.ke].mon[e.id].ffmpeg}) +// if(e.mode && config.restart.onVideoNotExist === true){ +// delete(s.group[e.ke].mon[e.id].open); +// s.log(e,{ +// type : lang['Camera is not recording'], +// msg : { +// msg : lang.CameraNotRecordingText +// } +// }); +// if(s.group[e.ke].mon[e.id].started===1){ +// s.camera('restart',e) +// } +// } +// } +// } +// } +// delete(s.group[e.ke].mon[e.id].open); +// break; + case'linkBuild': + //e = video rows + //k = auth key + e.forEach(function(v){ + var details = JSON.parse(v.details) + var queryString = [] + if(details.isUTC === true){ + queryString.push('isUTC=true') + }else{ + v.time = s.utcToLocal(v.time) + v.end = s.utcToLocal(v.end) + } + if(queryString.length > 0){ + queryString = '?'+queryString.join('&') + }else{ + queryString = '' + } + v.href = '/'+k+'/videos/'+v.ke+'/'+v.mid+'/'+s.formattedTime(v.time)+'.'+v.ext; + v.links = { + deleteVideo : v.href+'/delete' + queryString, + changeToUnread : v.href+'/status/1' + queryString, + changeToRead : v.href+'/status/2' + queryString + } + v.href = v.href + queryString + v.details = details + }) + break; + case'diskUseUpdate': + if(s.group[e.ke].init){ + s.init('diskUsedSet',e,e.filesizeMB) + if(config.cron.deleteOverMax===true){ + //check space + s.group[e.ke].sizePurgeQueue.push(1) + if(s.group[e.ke].sizePurging!==true){ + //lock this function + s.group[e.ke].sizePurging=true + //set queue processor + var finish=function(){ + //remove value just used from queue + s.group[e.ke].sizePurgeQueue = s.group[e.ke].sizePurgeQueue.splice(1,s.group[e.ke].sizePurgeQueue.length+10) + //do next one + if(s.group[e.ke].sizePurgeQueue.length>0){ + checkQueue() + }else{ + s.group[e.ke].sizePurging=false + s.init('diskUsedEmit',e) + } + } + var checkQueue=function(){ + //get first in queue + var currentPurge = s.group[e.ke].sizePurgeQueue[0] + var deleteVideos = function(){ + //run purge command + if(s.group[e.ke].usedSpace>(s.group[e.ke].sizeLimit*config.cron.deleteOverMaxOffset)){ + s.sqlQuery('SELECT * FROM Videos WHERE status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND ke=? ORDER BY `time` ASC LIMIT 2',[e.ke],function(err,evs){ + k.del=[];k.ar=[e.ke]; + if(!evs)return console.log(err) + evs.forEach(function(ev){ + ev.dir=s.video('getDir',ev)+s.formattedTime(ev.time)+'.'+ev.ext; + k.del.push('(mid=? AND time=?)'); + k.ar.push(ev.mid),k.ar.push(ev.time); + s.file('delete',ev.dir); + s.init('diskUsedSet',e,-(ev.size/1000000)) + s.tx({f:'video_delete',ff:'over_max',filename:s.formattedTime(ev.time)+'.'+ev.ext,mid:ev.mid,ke:ev.ke,time:ev.time,end:s.formattedTime(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke); + }); + if(k.del.length>0){ + k.qu=k.del.join(' OR '); + s.sqlQuery('DELETE FROM Videos WHERE ke =? AND ('+k.qu+')',k.ar,function(){ + deleteVideos() + }) + }else{ + finish() + } + }) + }else{ + finish() + } + } + deleteVideos() + } + checkQueue() + } + }else{ + s.init('diskUsedEmit',e) + } + } + break; + case'insertCompleted': + k.dir = e.dir.toString() + if(s.group[e.ke].mon[e.id].childNode){ + s.cx({f:'insertCompleted',d:s.group[e.ke].mon_conf[e.id],k:k},s.group[e.ke].mon[e.id].childNodeId); + }else{ + //get file directory + k.fileExists = fs.existsSync(k.dir+k.file) + if(k.fileExists!==true){ + k.dir = s.dir.videos+'/'+e.ke+'/'+e.id+'/' + k.fileExists = fs.existsSync(k.dir+k.file) + if(k.fileExists !== true){ + s.dir.addStorage.forEach(function(v){ + if(k.fileExists !== true){ + k.dir = s.checkCorrectPathEnding(v.path)+e.ke+'/'+e.id+'/' + k.fileExists = fs.existsSync(k.dir+k.file) + } + }) + } + } + if(k.fileExists===true){ + //close video row + k.stat = fs.statSync(k.dir+k.file) + e.filesize = k.stat.size + e.filesizeMB = parseFloat((e.filesize/1000000).toFixed(2)) + + e.startTime = new Date(s.nameToTime(k.file)) + e.endTime = new Date(k.stat.mtime) + if(config.useUTC === true){ + fs.rename(k.dir+k.file, k.dir+s.formattedTime(e.startTime)+'.'+e.ext, (err) => { + if (err) return console.error(err); + }); + k.filename = s.formattedTime(e.startTime)+'.'+e.ext + }else{ + e.startTime = s.utcToLocal(e.startTime) + e.endTime = s.utcToLocal(e.endTime) + k.filename = k.file + } + if(!e.ext){e.ext = k.filename.split('.')[1]} + //send event for completed recording + if(config.childNodes.enabled === true && config.childNodes.mode === 'child' && config.childNodes.host){ + fs.createReadStream(k.dir+k.filename) + .on('data',function(data){ + s.cx({ + f:'created_file_chunk', + mid:e.id, + ke:e.ke, + chunk:data, + filename:k.filename, + d:s.init('noReference',e), + filesize:e.filesize, + time:s.timeObject(e.startTime).format(), + end:s.timeObject(e.endTime).format() + }) + }) + .on('close',function(){ + clearTimeout(s.group[e.ke].mon[e.id].checker) + clearTimeout(s.group[e.ke].mon[e.id].checkStream) + s.cx({ + f:'created_file', + mid:e.id, + ke:e.ke, + filename:k.filename, + d:s.init('noReference',e), + filesize:e.filesize, + time:s.timeObject(e.startTime).format(), + end:s.timeObject(e.endTime).format() + }) + }); + }else{ + var href = '/videos/'+e.ke+'/'+e.mid+'/'+k.filename + if(config.useUTC === true)href += '?isUTC=true'; + s.txWithSubPermissions({ + f:'video_build_success', + hrefNoAuth:href, + filename:k.filename, + mid:e.mid, + ke:e.ke, + time:s.timeObject(e.startTime).format(), + size:e.filesize, + end:s.timeObject(e.endTime).format() + },'GRP_'+e.ke,'video_view'); + } + //cloud auto savers + //webdav + // var webDAV = s.group[e.ke].webdav + // if(webDAV&&s.group[e.ke].init.use_webdav!=='0'&&s.group[e.ke].init.webdav_save=="1"){ + // fs.readFile(k.dir+k.filename,function(err,data){ + // var webdavUploadDir = s.group[e.ke].init.webdav_dir+e.ke+'/'+e.mid+'/' + // fs.readFile(k.dir+k.filename,function(err,data){ + // webDAV.putFileContents(webdavUploadDir+k.filename,"binary",data).catch(function(err) { + // if(err){ + // webDAV.createDirectory(webdavUploadDir).catch(function(err) { + // s.log(e,{type:lang['Webdav Error'],msg:{msg:lang.WebdavErrorText+' /'+webdavUploadDir+'',info:err}}) + // }) + // webDAV.putFileContents(webdavUploadDir+k.filename,"binary",data).catch(function(err) { + // s.log(e,{type:lang['Webdav Error'],msg:{msg:lang.WebdavErrorText+' /'+webdavUploadDir+'',info:err}}) + // }) + // s.log(e,{type:lang['Webdav Error'],msg:{msg:lang.WebdavErrorText+' /'+webdavUploadDir+'',info:err}}) + // } + // }); + // }); + // }); + // } + if(s.group[e.ke].webdav&&s.group[e.ke].init.use_webdav!=='0'&&s.group[e.ke].init.webdav_save=="1"){ + fs.readFile(k.dir+k.filename,function(err,data){ + s.group[e.ke].webdav.putFileContents(s.group[e.ke].init.webdav_dir+e.ke+'/'+e.mid+'/'+k.filename,"binary",data) + .catch(function(err) { + s.log(e,{type:lang['Webdav Error'],msg:{msg:lang.WebdavErrorText+' /'+e.ke+'/'+e.id+'',info:err},ffmpeg:s.group[e.ke].mon[e.id].ffmpeg}) + console.error(err); + }); + }); + } + k.details = {} + if(e.details&&e.details.dir&&e.details.dir!==''){ + k.details.dir = e.details.dir + } + if(config.useUTC)k.details.isUTC = config.useUTC; + var save = [ + e.mid, + e.ke, + e.startTime, + e.ext, + 1, + s.s(k.details), + e.filesize, + e.endTime, + ] + s.sqlQuery('INSERT INTO Videos (mid,ke,time,ext,status,details,size,end) VALUES (?,?,?,?,?,?,?,?)',save) + //send new diskUsage values + s.video('diskUseUpdate',e,k) + } + } + break; + } +} +s.splitForFFPMEG = function (ffmpegCommandAsString) { + //this function ignores spaces inside quotes. + return ffmpegCommandAsString.match(/\\?.|^$/g).reduce((p, c) => { + if(c === '"'){ + p.quote ^= 1; + }else if(!p.quote && c === ' '){ + p.a.push(''); + }else{ + p.a[p.a.length-1] += c.replace(/\\(.)/,"$1"); + } + return p; + }, {a: ['']}).a +}; +s.ffmpeg=function(e){ + //create input map + var createFFmpegMap = function(arrayOfMaps){ + //e.details.input_map_choices.stream + var string = ''; + if(e.details.input_maps && e.details.input_maps.length > 0){ + if(arrayOfMaps && arrayOfMaps instanceof Array && arrayOfMaps.length>0){ + arrayOfMaps.forEach(function(v){ + if(v.map==='')v.map='0' + string += ' -map '+v.map + }) + }else{ + string += ' -map 0:0' + } + } + return string; + } + var createInputMap = function(number,input){ + //fulladdress - Full Input Path + //`x` is an object used to contain temporary values. + var x = {} + x.cust_input = '' + x.hwaccel = '' + if(input.cust_input&&input.cust_input!==''){x.cust_input+=' '+input.cust_input;} + //input - analyze duration + if(input.aduration&&input.aduration!==''){x.cust_input+=' -analyzeduration '+input.aduration}; + //input - probe size + if(input.probesize&&input.probesize!==''){x.cust_input+=' -probesize '+input.probesize}; + //input - stream loop (good for static files/lists) + if(input.stream_loop==='1'){x.cust_input+=' -stream_loop -1'}; + //input - fps + if(x.cust_input.indexOf('-r ')===-1&&input.sfps&&input.sfps!==''){ + input.sfps=parseFloat(input.sfps); + if(isNaN(input.sfps)){input.sfps=1} + x.cust_input+=' -r '+input.sfps + } + //input - is mjpeg + if(input.type==='mjpeg'){ + if(x.cust_input.indexOf('-f ')===-1){ + x.cust_input+=' -f mjpeg' + } + //input - frames per second + x.cust_input+=' -reconnect 1'; + }else + //input - is h264 has rtsp in address and transport method is chosen + if((input.type==='h264'||input.type==='mp4')&&input.fulladdress.indexOf('rtsp://')>-1&&input.rtsp_transport!==''&&input.rtsp_transport!=='no'){ + x.cust_input += ' -rtsp_transport '+input.rtsp_transport; + }else + if((input.type==='mp4'||input.type==='mjpeg')&&x.cust_input.indexOf('-re')===-1){ + x.cust_input += ' -re' + } + //hardware acceleration + if(input.accelerator&&input.accelerator==='1'){ + if(input.hwaccel&&input.hwaccel!==''){ + x.hwaccel+=' -hwaccel '+input.hwaccel; + } + if(input.hwaccel_vcodec&&input.hwaccel_vcodec!==''&&input.hwaccel_vcodec!=='auto'&&input.hwaccel_vcodec!=='no'){ + x.hwaccel+=' -c:v '+input.hwaccel_vcodec; + } + if(input.hwaccel_device&&input.hwaccel_device!==''){ + switch(input.hwaccel){ + case'vaapi': + x.hwaccel+=' -vaapi_device '+input.hwaccel_device+' -hwaccel_output_format vaapi'; + break; + default: + x.hwaccel+=' -hwaccel_device '+input.hwaccel_device; + break; + } + } + } + //custom - input flags + return x.hwaccel+x.cust_input+' -i "'+input.fulladdress+'"'; + } + //create sub stream channel + var createStreamChannel = function(number,channel){ + //`x` is an object used to contain temporary values. + var x = { + pipe:'' + } + if(!number||number==''){ + x.channel_sdir = e.sdir; + }else{ + x.channel_sdir = e.sdir+'channel'+number+'/'; + if (!fs.existsSync(x.channel_sdir)){ + fs.mkdirSync(x.channel_sdir); + } + } + x.stream_video_filters=[] + //stream - frames per second + if(channel.stream_vcodec!=='copy'){ + if(!channel.stream_fps||channel.stream_fps===''){ + switch(channel.stream_type){ + case'rtmp': + channel.stream_fps=30 + break; + default: +// channel.stream_fps=5 + break; + } + } + } + if(channel.stream_fps&&channel.stream_fps!==''){x.stream_fps=' -r '+channel.stream_fps}else{x.stream_fps=''} + + //stream - hls vcodec + if(channel.stream_vcodec&&channel.stream_vcodec!=='no'){ + if(channel.stream_vcodec!==''){x.stream_vcodec=' -c:v '+channel.stream_vcodec}else{x.stream_vcodec=' -c:v libx264'} + }else{ + x.stream_vcodec=''; + } + //stream - hls acodec + if(channel.stream_acodec!=='no'){ + if(channel.stream_acodec&&channel.stream_acodec!==''){x.stream_acodec=' -c:a '+channel.stream_acodec}else{x.stream_acodec=''} + }else{ + x.stream_acodec=' -an'; + } + //stream - resolution + if(channel.stream_scale_x&&channel.stream_scale_x!==''&&channel.stream_scale_y&&channel.stream_scale_y!==''){ + x.dimensions = channel.stream_scale_x+'x'+channel.stream_scale_y; + } + //stream - hls segment time + if(channel.hls_time&&channel.hls_time!==''){x.hls_time=channel.hls_time}else{x.hls_time="2"} + //hls list size + if(channel.hls_list_size&&channel.hls_list_size!==''){x.hls_list_size=channel.hls_list_size}else{x.hls_list_size=2} + //stream - custom flags + if(channel.cust_stream&&channel.cust_stream!==''){x.cust_stream=' '+channel.cust_stream}else{x.cust_stream=''} + //stream - preset + if(channel.preset_stream&&channel.preset_stream!==''){x.preset_stream=' -preset '+channel.preset_stream;}else{x.preset_stream=''} + //hardware acceleration + if(e.details.accelerator&&e.details.accelerator==='1'){ + if(e.details.hwaccel&&e.details.hwaccel!==''){ + x.hwaccel+=' -hwaccel '+e.details.hwaccel; + } + if(e.details.hwaccel_vcodec&&e.details.hwaccel_vcodec!==''){ + x.hwaccel+=' -c:v '+e.details.hwaccel_vcodec; + } + if(e.details.hwaccel_device&&e.details.hwaccel_device!==''){ + switch(e.details.hwaccel){ + case'vaapi': + x.hwaccel+=' -vaapi_device '+e.details.hwaccel_device+' -hwaccel_output_format vaapi'; + break; + default: + x.hwaccel+=' -hwaccel_device '+e.details.hwaccel_device; + break; + } + } + // else{ + // if(e.details.hwaccel==='vaapi'){ + // x.hwaccel+=' -hwaccel_device 0'; + // } + // } + } + + if(channel.rotate_stream&&channel.rotate_stream!==""&&channel.rotate_stream!=="no"){ + x.stream_video_filters.push('transpose='+channel.rotate_stream); + } + //stream - video filter + if(channel.svf&&channel.svf!==''){ + x.stream_video_filters.push(channel.svf) + } + if(x.stream_video_filters.length>0){ + var string = x.stream_video_filters.join(',').trim() + if(string===''){ + x.stream_video_filters='' + }else{ + x.stream_video_filters=' -vf '+string + } + }else{ + x.stream_video_filters='' + } + if(e.details.input_map_choices&&e.details.input_map_choices.record){ + //add input feed map + x.pipe += createFFmpegMap(e.details.input_map_choices['stream_channel-'+(number-config.pipeAddition)]) + } + if(channel.stream_vcodec!=='copy'){ + x.cust_stream+=x.stream_fps + } + switch(channel.stream_type){ + case'mp4': + x.cust_stream+=' -movflags +frag_keyframe+empty_moov+default_base_moof -metadata title="Poseidon Stream" -reset_timestamps 1' + if(channel.stream_vcodec!=='copy'){ + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + if(channel.stream_quality && channel.stream_quality !== '')x.cust_stream+=' -crf '+channel.stream_quality; + x.cust_stream+=x.preset_stream + x.cust_stream+=x.stream_video_filters + } + x.pipe+=' -f mp4'+x.stream_acodec+x.stream_vcodec+x.cust_stream+' pipe:'+number; + break; + case'rtmp': + x.rtmp_server_url=s.checkCorrectPathEnding(channel.rtmp_server_url); + if(channel.stream_vcodec!=='copy'){ + if(channel.stream_vcodec==='libx264'){ + channel.stream_vcodec = 'h264' + } + if(channel.stream_quality && channel.stream_quality !== '')x.cust_stream+=' -crf '+channel.stream_quality; + x.cust_stream+=x.preset_stream + if(channel.stream_v_br&&channel.stream_v_br!==''){x.cust_stream+=' -b:v '+channel.stream_v_br} + } + if(channel.stream_vcodec!=='no'&&channel.stream_vcodec!==''){ + x.cust_stream+=' -vcodec '+channel.stream_vcodec + } + if(channel.stream_acodec!=='copy'){ + if(!channel.stream_acodec||channel.stream_acodec===''||channel.stream_acodec==='no'){ + channel.stream_acodec = 'aac' + } + if(!channel.stream_a_br||channel.stream_a_br===''){channel.stream_a_br='128k'} + x.cust_stream+=' -ab '+channel.stream_a_br + } + if(channel.stream_acodec!==''){ + x.cust_stream+=' -acodec '+channel.stream_acodec + } + x.pipe+=' -f flv'+x.stream_video_filters+x.cust_stream+' "'+x.rtmp_server_url+channel.rtmp_stream_key+'"'; + break; + case'h264': + if(channel.stream_vcodec!=='copy'){ + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + if(channel.stream_quality && channel.stream_quality !== '')x.cust_stream+=' -crf '+channel.stream_quality; + x.cust_stream+=x.preset_stream + x.cust_stream+=x.stream_video_filters + } + x.pipe+=' -f mpegts'+x.stream_acodec+x.stream_vcodec+x.cust_stream+' pipe:'+number; + break; + case'flv': + if(channel.stream_vcodec!=='copy'){ + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + if(channel.stream_quality && channel.stream_quality !== '')x.cust_stream+=' -crf '+channel.stream_quality; + x.cust_stream+=x.preset_stream + x.cust_stream+=x.stream_video_filters + } + x.pipe+=' -f flv'+x.stream_acodec+x.stream_vcodec+x.cust_stream+' pipe:'+number; + break; + case'hls': + if(channel.stream_vcodec!=='h264_vaapi'&&channel.stream_vcodec!=='copy'){ + if(channel.stream_quality && channel.stream_quality !== '')x.cust_stream+=' -crf '+channel.stream_quality; + if(x.cust_stream.indexOf('-tune')===-1){x.cust_stream+=' -tune zerolatency'} + if(x.cust_stream.indexOf('-g ')===-1){x.cust_stream+=' -g 1'} + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + x.cust_stream+=x.stream_video_filters + } + x.pipe+=x.preset_stream+x.stream_acodec+x.stream_vcodec+' -f hls'+x.cust_stream+' -hls_time '+x.hls_time+' -hls_list_size '+x.hls_list_size+' -start_number 0 -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist "'+x.channel_sdir+'s.m3u8"'; + break; + case'mjpeg': + if(channel.stream_quality && channel.stream_quality !== '')x.cust_stream+=' -q:v '+channel.stream_quality; + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + x.pipe+=' -c:v mjpeg -f mpjpeg -boundary_tag shinobi'+x.cust_stream+x.stream_video_filters+' pipe:'+number; + break; + default: + x.pipe='' + break; + } + return x.pipe + } + //set X for temporary values so we don't break our main monitor object. + var x={tmp:''}; + //set some placeholding values to avoid "undefined" in ffmpeg string. + x.record_string='' + x.cust_input='' + x.cust_detect=' ' + x.record_video_filters=[] + x.stream_video_filters=[] + x.hwaccel='' + x.pipe='' + //input - frame rate (capture rate) + if(e.details.sfps && e.details.sfps!==''){x.input_fps=' -r '+e.details.sfps}else{x.input_fps=''} + //input - analyze duration + if(e.details.aduration&&e.details.aduration!==''){x.cust_input+=' -analyzeduration '+e.details.aduration}; + //input - probe size + if(e.details.probesize&&e.details.probesize!==''){x.cust_input+=' -probesize '+e.details.probesize}; + //input - stream loop (good for static files/lists) + if(e.details.stream_loop==='1'){x.cust_input+=' -stream_loop -1'}; + //input + switch(e.type){ + case'h264': + switch(e.protocol){ + case'rtsp': + if(e.details.cust_input.indexOf('-fflags') === -1){x.cust_input+=' -fflags +igndts'} + if(e.details.rtsp_transport&&e.details.rtsp_transport!==''&&e.details.rtsp_transport!=='no'){x.cust_input+=' -rtsp_transport '+e.details.rtsp_transport;} + break; + } + break; + } + //record - resolution + if(e.width!==''&&e.height!==''&&!isNaN(e.width)&&!isNaN(e.height)){ + x.record_dimensions=' -s '+e.width+'x'+e.height + }else{ + x.record_dimensions='' + } + if(e.details.stream_scale_x&&e.details.stream_scale_x!==''&&e.details.stream_scale_y&&e.details.stream_scale_y!==''){ + x.dimensions = e.details.stream_scale_x+'x'+e.details.stream_scale_y; + } + //record - segmenting + x.segment=' -f segment -segment_atclocktime 1 -reset_timestamps 1 -strftime 1 -segment_list pipe:2 -segment_time '+(60*e.cutoff)+' "'+e.dir+'%Y-%m-%dT%H-%M-%S.'+e.ext+'"'; + //record - set defaults for extension, video quality + switch(e.ext){ + case'mp4': + x.vcodec='libx264';x.acodec='aac'; + if(e.details.crf&&e.details.crf!==''){x.vcodec+=' -crf '+e.details.crf} + break; + case'webm': + x.acodec='libvorbis',x.vcodec='libvpx'; + if(e.details.crf&&e.details.crf!==''){x.vcodec+=' -q:v '+e.details.crf}else{x.vcodec+=' -q:v 1';} + break; + } + if(e.details.vcodec==='h264_vaapi'){ + x.record_video_filters.push('format=nv12,hwupload'); + } + //record - use custom video codec + if(e.details.vcodec&&e.details.vcodec!==''&&e.details.vcodec!=='default'){x.vcodec=e.details.vcodec} + //record - use custom audio codec + if(e.details.acodec&&e.details.acodec!==''&&e.details.acodec!=='default'){x.acodec=e.details.acodec} + if(e.details.cust_record){ + if(x.acodec=='aac'&&e.details.cust_record.indexOf('-strict -2')===-1){e.details.cust_record+=' -strict -2';} + if(e.details.cust_record.indexOf('-threads')===-1){e.details.cust_record+=' -threads 1';} + } +// if(e.details.cust_input&&(e.details.cust_input.indexOf('-use_wallclock_as_timestamps 1')>-1)===false){e.details.cust_input+=' -use_wallclock_as_timestamps 1';} + //record - ready or reset codecs + if(x.acodec!=='no'){ + if(x.acodec.indexOf('none')>-1){x.acodec=''}else{x.acodec=' -acodec '+x.acodec} + }else{ + x.acodec=' -an' + } + if(x.vcodec.indexOf('none')>-1){x.vcodec=''}else{x.vcodec=' -vcodec '+x.vcodec} + //record - frames per second (fps) + if(e.fps&&e.fps!==''&&e.details.vcodec!=='copy'){x.record_fps=' -r '+e.fps}else{x.record_fps=''} + //stream - frames per second (fps) + if(e.details.stream_fps&&e.details.stream_fps!==''){x.stream_fps=' -r '+e.details.stream_fps}else{x.stream_fps=''} + //record - timestamp options for -vf + if(e.details.timestamp&&e.details.timestamp=="1"&&e.details.vcodec!=='copy'){ + //font + if(e.details.timestamp_font&&e.details.timestamp_font!==''){x.time_font=e.details.timestamp_font}else{x.time_font='/usr/share/fonts/truetype/freefont/FreeSans.ttf'} + //position x + if(e.details.timestamp_x&&e.details.timestamp_x!==''){x.timex=e.details.timestamp_x}else{x.timex='(w-tw)/2'} + //position y + if(e.details.timestamp_y&&e.details.timestamp_y!==''){x.timey=e.details.timestamp_y}else{x.timey='0'} + //text color + if(e.details.timestamp_color&&e.details.timestamp_color!==''){x.time_color=e.details.timestamp_color}else{x.time_color='white'} + //box color + if(e.details.timestamp_box_color&&e.details.timestamp_box_color!==''){x.time_box_color=e.details.timestamp_box_color}else{x.time_box_color='0x00000000@1'} + //text size + if(e.details.timestamp_font_size&&e.details.timestamp_font_size!==''){x.time_font_size=e.details.timestamp_font_size}else{x.time_font_size='10'} + + x.record_video_filters.push('drawtext=fontfile='+x.time_font+':text=\'%{localtime}\':x='+x.timex+':y='+x.timey+':fontcolor='+x.time_color+':box=1:boxcolor='+x.time_box_color+':fontsize='+x.time_font_size); + } + //record - watermark for -vf + if(e.details.watermark&&e.details.watermark=="1"&&e.details.watermark_location&&e.details.watermark_location!==''){ + switch(e.details.watermark_position){ + case'tl'://top left + x.watermark_position='10:10' + break; + case'tr'://top right + x.watermark_position='main_w-overlay_w-10:10' + break; + case'bl'://bottom left + x.watermark_position='10:main_h-overlay_h-10' + break; + default://bottom right + x.watermark_position='(main_w-overlay_w-10)/2:(main_h-overlay_h-10)/2' + break; + } + x.record_video_filters.push('movie='+e.details.watermark_location+'[watermark],[in][watermark]overlay='+x.watermark_position+'[out]'); + } + //record - rotation + if(e.details.rotate_record&&e.details.rotate_record!==""&&e.details.rotate_record!=="no"&&e.details.stream_vcodec!=="copy"){ + x.record_video_filters.push('transpose='+e.details.rotate_record); + } + //check custom record filters for -vf + if(e.details.vf&&e.details.vf!==''){ + x.record_video_filters.push(e.details.vf) + } + //compile filter string for -vf + if(x.record_video_filters.length>0){ + x.record_video_filters=' -vf '+x.record_video_filters.join(',') + }else{ + x.record_video_filters='' + } + //stream - timestamp + if(e.details.stream_timestamp&&e.details.stream_timestamp=="1"&&e.details.vcodec!=='copy'){ + //font + if(e.details.stream_timestamp_font&&e.details.stream_timestamp_font!==''){x.stream_timestamp_font=e.details.stream_timestamp_font}else{x.stream_timestamp_font='/usr/share/fonts/truetype/freefont/FreeSans.ttf'} + //position x + if(e.details.stream_timestamp_x&&e.details.stream_timestamp_x!==''){x.stream_timestamp_x=e.details.stream_timestamp_x}else{x.stream_timestamp_x='(w-tw)/2'} + //position y + if(e.details.stream_timestamp_y&&e.details.stream_timestamp_y!==''){x.stream_timestamp_y=e.details.stream_timestamp_y}else{x.stream_timestamp_y='0'} + //text color + if(e.details.stream_timestamp_color&&e.details.stream_timestamp_color!==''){x.stream_timestamp_color=e.details.stream_timestamp_color}else{x.stream_timestamp_color='white'} + //box color + if(e.details.stream_timestamp_box_color&&e.details.stream_timestamp_box_color!==''){x.stream_timestamp_box_color=e.details.stream_timestamp_box_color}else{x.stream_timestamp_box_color='0x00000000@1'} + //text size + if(e.details.stream_timestamp_font_size&&e.details.stream_timestamp_font_size!==''){x.stream_timestamp_font_size=e.details.stream_timestamp_font_size}else{x.stream_timestamp_font_size='10'} + + x.stream_video_filters.push('drawtext=fontfile='+x.stream_timestamp_font+':text=\'%{localtime}\':x='+x.stream_timestamp_x+':y='+x.stream_timestamp_y+':fontcolor='+x.stream_timestamp_color+':box=1:boxcolor='+x.stream_timestamp_box_color+':fontsize='+x.stream_timestamp_font_size); + } + //stream - watermark for -vf + if(e.details.stream_watermark&&e.details.stream_watermark=="1"&&e.details.stream_watermark_location&&e.details.stream_watermark_location!==''){ + switch(e.details.stream_watermark_position){ + case'tl'://top left + x.stream_watermark_position='10:10' + break; + case'tr'://top right + x.stream_watermark_position='main_w-overlay_w-10:10' + break; + case'bl'://bottom left + x.stream_watermark_position='10:main_h-overlay_h-10' + break; + default://bottom right + x.stream_watermark_position='(main_w-overlay_w-10)/2:(main_h-overlay_h-10)/2' + break; + } + x.stream_video_filters.push('movie='+e.details.stream_watermark_location+'[watermark],[in][watermark]overlay='+x.stream_watermark_position+'[out]'); + } + //stream - rotation + if(e.details.rotate_stream&&e.details.rotate_stream!==""&&e.details.rotate_stream!=="no"&&e.details.stream_vcodec!=='copy'){ + x.stream_video_filters.push('transpose='+e.details.rotate_stream); + } + //stream - hls vcodec + if(e.details.stream_vcodec&&e.details.stream_vcodec!=='no'){ + if(e.details.stream_vcodec!==''){x.stream_vcodec=' -c:v '+e.details.stream_vcodec}else{x.stream_vcodec=' -c:v libx264'} + }else{ + x.stream_vcodec=''; + } + //stream - hls acodec + if(e.details.stream_acodec!=='no'){ + if(e.details.stream_acodec&&e.details.stream_acodec!==''){x.stream_acodec=' -c:a '+e.details.stream_acodec}else{x.stream_acodec=''} + }else{ + x.stream_acodec=' -an'; + } + //stream - hls segment time + if(e.details.hls_time&&e.details.hls_time!==''){x.hls_time=e.details.hls_time}else{x.hls_time="2"} //hls list size + if(e.details.hls_list_size&&e.details.hls_list_size!==''){x.hls_list_size=e.details.hls_list_size}else{x.hls_list_size=2} + //stream - custom flags + if(e.details.cust_stream&&e.details.cust_stream!==''){x.cust_stream=' '+e.details.cust_stream}else{x.cust_stream=''} + //stream - preset + if(e.details.preset_stream&&e.details.preset_stream!==''){x.preset_stream=' -preset '+e.details.preset_stream;}else{x.preset_stream=''} + //stream - quality + //hardware acceleration + if(e.details.accelerator&&e.details.accelerator==='1'){ + if(e.details.hwaccel&&e.details.hwaccel!==''){ + x.hwaccel+=' -hwaccel '+e.details.hwaccel; + } + if(e.details.hwaccel_vcodec&&e.details.hwaccel_vcodec!==''){ + x.hwaccel+=' -c:v '+e.details.hwaccel_vcodec; + } + if(e.details.hwaccel_device&&e.details.hwaccel_device!==''){ + switch(e.details.hwaccel){ + case'vaapi': + x.hwaccel+=' -vaapi_device '+e.details.hwaccel_device; + break; + default: + x.hwaccel+=' -hwaccel_device '+e.details.hwaccel_device; + break; + } + } +// else{ +// if(e.details.hwaccel==='vaapi'){ +// x.hwaccel+=' -hwaccel_device 0'; +// } +// } + } + if(e.details.stream_vcodec==='h264_vaapi'){ + x.stream_video_filters=[] + x.stream_video_filters.push('format=nv12,hwupload'); + if(e.details.stream_scale_x&&e.details.stream_scale_x!==''&&e.details.stream_scale_y&&e.details.stream_scale_y!==''){ + x.stream_video_filters.push('scale_vaapi=w='+e.details.stream_scale_x+':h='+e.details.stream_scale_y) + } + } + //stream - video filter + if(e.details.svf&&e.details.svf!==''){ + x.stream_video_filters.push(e.details.svf) + } + if(x.stream_video_filters.length>0){ + x.stream_video_filters=' -vf '+x.stream_video_filters.join(',') + }else{ + x.stream_video_filters='' + } + //stream - pipe build + if(e.details.input_map_choices&&e.details.input_map_choices.stream){ + //add input feed map + x.pipe += createFFmpegMap(e.details.input_map_choices.stream) + } + if(e.details.stream_vcodec!=='copy'){ + x.cust_stream+=x.stream_fps + } + switch(e.details.stream_type){ + case'mp4': + x.cust_stream+=' -movflags +frag_keyframe+empty_moov+default_base_moof -metadata title="Poseidon Stream" -reset_timestamps 1' + if(e.details.stream_vcodec!=='copy'){ + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -crf '+e.details.stream_quality; + x.cust_stream+=x.preset_stream + x.cust_stream+=x.stream_video_filters + } + x.pipe+=' -f mp4'+x.stream_acodec+x.stream_vcodec+x.cust_stream+' pipe:1'; + break; + case'flv': + if(e.details.stream_vcodec!=='copy'){ + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -crf '+e.details.stream_quality; + x.cust_stream+=x.preset_stream + x.cust_stream+=x.stream_video_filters + } + x.pipe+=' -f flv'+x.stream_acodec+x.stream_vcodec+x.cust_stream+' pipe:1'; + break; + case'hls': + if(e.details.stream_vcodec!=='h264_vaapi'&&e.details.stream_vcodec!=='copy'){ + if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -crf '+e.details.stream_quality; + if(x.cust_stream.indexOf('-tune')===-1){x.cust_stream+=' -tune zerolatency'} + if(x.cust_stream.indexOf('-g ')===-1){x.cust_stream+=' -g 1'} + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + x.cust_stream+=x.stream_video_filters + } + x.pipe+=x.preset_stream+x.stream_acodec+x.stream_vcodec+' -f hls'+x.cust_stream+' -hls_time '+x.hls_time+' -hls_list_size '+x.hls_list_size+' -start_number 0 -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist "'+e.sdir+'s.m3u8"'; + break; + case'mjpeg': + if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -q:v '+e.details.stream_quality; + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + x.pipe+=' -an -c:v mjpeg -f mpjpeg -boundary_tag shinobi'+x.cust_stream+x.stream_video_filters+' pipe:1'; + break; + case'pam': + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -q:v '+e.details.stream_quality; + x.pipe+=' -an -c:v pam -pix_fmt rgba -f image2pipe'+x.cust_stream+x.stream_video_filters+' pipe:1'; + break; + case'b64':case'':case undefined:case null://base64 + if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -q:v '+e.details.stream_quality; + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + x.pipe+=' -an -c:v mjpeg -f image2pipe'+x.cust_stream+x.stream_video_filters+' pipe:1'; + break; + default: + x.pipe='' + break; + } + if(e.details.stream_channels){ + e.details.stream_channels.forEach(function(v,n){ + x.pipe+=createStreamChannel(n+config.pipeAddition,v) + }) + } + //detector - plugins, motion + if(e.details.detector==='1'&&e.details.detector_send_frames==='1'){ + if(e.details.input_map_choices&&e.details.input_map_choices.detector){ + //add input feed map + x.pipe += createFFmpegMap(e.details.input_map_choices.detector) + } + if(!e.details.detector_fps||e.details.detector_fps===''){e.details.detector_fps=2} + if(e.details.detector_scale_x&&e.details.detector_scale_x!==''&&e.details.detector_scale_y&&e.details.detector_scale_y!==''){x.dratio=' -s '+e.details.detector_scale_x+'x'+e.details.detector_scale_y}else{x.dratio=' -s 320x240'} + if(e.details.cust_detect&&e.details.cust_detect!==''){x.cust_detect+=e.details.cust_detect;} + if(e.details.detector_pam==='1'){ + x.pipe+=' -an -c:v pam -pix_fmt gray -f image2pipe -vf fps='+e.details.detector_fps+x.cust_detect+x.dratio+' pipe:3' + if(e.details.detector_use_detect_object === '1'){ + //for object detection + x.pipe += createFFmpegMap(e.details.input_map_choices.detector) + x.pipe += ' -f singlejpeg -vf fps='+e.details.detector_fps+x.cust_detect+x.dratio+' pipe:4'; + } + }else{ + x.pipe+=' -f singlejpeg -vf fps='+e.details.detector_fps+x.cust_detect+x.dratio+' pipe:3'; + } + } + //api - snapshot bin/ cgi.bin (JPEG Mode) + if(e.details.snap==='1'){ + if(e.details.input_map_choices&&e.details.input_map_choices.snap){ + //add input feed map + x.pipe += createFFmpegMap(e.details.input_map_choices.snap) + } + if(!e.details.snap_fps||e.details.snap_fps===''){e.details.snap_fps=1} + if(e.details.snap_vf&&e.details.snap_vf!==''){x.snap_vf=' -vf '+e.details.snap_vf}else{x.snap_vf=''} + if(e.details.snap_scale_x&&e.details.snap_scale_x!==''&&e.details.snap_scale_y&&e.details.snap_scale_y!==''){x.snap_ratio=' -s '+e.details.snap_scale_x+'x'+e.details.snap_scale_y}else{x.snap_ratio=''} + if(e.details.cust_snap&&e.details.cust_snap!==''){x.cust_snap=' '+e.details.cust_snap;}else{x.cust_snap=''} + x.pipe+=' -update 1 -r '+e.details.snap_fps+x.cust_snap+x.snap_ratio+x.snap_vf+' "'+e.sdir+'s.jpg" -y'; + } + //Traditional Recording Buffer + if(e.details.detector=='1'&&e.details.detector_trigger=='1'&&e.details.detector_record_method==='sip'){ + if(e.details.input_map_choices&&e.details.input_map_choices.detector_sip_buffer){ + //add input feed map + x.pipe += createFFmpegMap(e.details.input_map_choices.detector_sip_buffer) + } + x.detector_buffer_filters=[] + if(!e.details.detector_buffer_vcodec||e.details.detector_buffer_vcodec===''||e.details.detector_buffer_vcodec==='auto'){ + switch(e.type){ + case'h264':case'hls':case'mp4': + e.details.detector_buffer_vcodec = 'copy' + break; + default: + e.details.detector_buffer_vcodec = 'libx264' + break; + } + } + if(!e.details.detector_buffer_acodec||e.details.detector_buffer_acodec===''||e.details.detector_buffer_acodec==='auto'){ + switch(e.type){ + case'h264':case'hls':case'mp4': + e.details.detector_buffer_acodec = 'copy' + break; + default: + e.details.detector_buffer_acodec = 'aac' + break; + } + } + if(e.details.detector_buffer_acodec === 'no'){ + x.detector_buffer_acodec = ' -an' + }else{ + x.detector_buffer_acodec = ' -c:a '+e.details.detector_buffer_acodec + } + if(!e.details.detector_buffer_tune||e.details.detector_buffer_tune===''){e.details.detector_buffer_tune='zerolatency'} + if(!e.details.detector_buffer_g||e.details.detector_buffer_g===''){e.details.detector_buffer_g='1'} + if(!e.details.detector_buffer_hls_time||e.details.detector_buffer_hls_time===''){e.details.detector_buffer_hls_time='2'} + if(!e.details.detector_buffer_hls_list_size||e.details.detector_buffer_hls_list_size===''){e.details.detector_buffer_hls_list_size='4'} + if(!e.details.detector_buffer_start_number||e.details.detector_buffer_start_number===''){e.details.detector_buffer_start_number='0'} + if(!e.details.detector_buffer_live_start_index||e.details.detector_buffer_live_start_index===''){e.details.detector_buffer_live_start_index='-3'} + + if(e.details.detector_buffer_vcodec.indexOf('_vaapi')>-1){ + if(x.hwaccel.indexOf('-vaapi_device')>-1){ + x.detector_buffer_filters.push('format=nv12') + x.detector_buffer_filters.push('hwupload') + }else{ + e.details.detector_buffer_vcodec='libx264' + } + } + if(e.details.detector_buffer_vcodec!=='copy'){ + if(e.details.detector_buffer_fps&&e.details.detector_buffer_fps!==''){ + x.detector_buffer_fps=' -r '+e.details.detector_buffer_fps + }else{ + x.detector_buffer_fps=' -r 30' + } + }else{ + x.detector_buffer_fps='' + } + if(x.detector_buffer_filters.length>0){ + x.pipe+=' -vf '+x.detector_buffer_filters.join(',') + } + x.pipe+=x.detector_buffer_fps+x.detector_buffer_acodec+' -c:v '+e.details.detector_buffer_vcodec+' -f hls -tune '+e.details.detector_buffer_tune+' -g '+e.details.detector_buffer_g+' -hls_time '+e.details.detector_buffer_hls_time+' -hls_list_size '+e.details.detector_buffer_hls_list_size+' -start_number '+e.details.detector_buffer_start_number+' -live_start_index '+e.details.detector_buffer_live_start_index+' -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist "'+e.sdir+'detectorStream.m3u8"' + } + //custom - output + if(e.details.custom_output&&e.details.custom_output!==''){x.pipe+=' '+e.details.custom_output;} + //custom - input flags + if(e.details.cust_input&&e.details.cust_input!==''){x.cust_input+=' '+e.details.cust_input;} + //logging - level + if(e.details.loglevel&&e.details.loglevel!==''){x.loglevel='-loglevel '+e.details.loglevel;}else{x.loglevel='-loglevel error'} + //build record string. + if(e.mode==='record'){ + if(e.details.input_map_choices&&e.details.input_map_choices.record){ + //add input feed map + x.record_string += createFFmpegMap(e.details.input_map_choices.record) + } + //if h264, hls, mp4, or local add the audio codec flag + switch(e.type){ + case'h264':case'hls':case'mp4':case'local': + x.record_string+=x.acodec; + break; + } + //custom flags + if(e.details.cust_record&&e.details.cust_record!==''){x.record_string+=' '+e.details.cust_record;} + //preset flag + if(e.details.preset_record&&e.details.preset_record!==''){x.record_string+=' -preset '+e.details.preset_record;} + //main string write + x.record_string+=x.vcodec+x.record_fps+x.record_video_filters+x.record_dimensions+x.segment; + } + //create executeable FFMPEG command + x.ffmpegCommandString = x.loglevel+x.input_fps; + //progress pipe +// x.ffmpegCommandString += ' -progress pipe:5'; + //add main input + if((e.type==='mp4'||e.type==='mjpeg')&&x.cust_input.indexOf('-re')===-1){ + x.cust_input += ' -re' + } + switch(e.type){ + case'dashcam': + x.ffmpegCommandString += ' -i -'; + break; + case'socket':case'jpeg':case'pipe': + x.ffmpegCommandString += ' -pattern_type glob -f image2pipe'+x.record_fps+' -vcodec mjpeg'+x.cust_input+' -i -'; + break; + case'mjpeg': + x.ffmpegCommandString += ' -reconnect 1 -f mjpeg'+x.cust_input+' -i "'+e.url+'"'; + break; + case'h264':case'hls':case'mp4': + x.ffmpegCommandString += x.cust_input+x.hwaccel+' -i "'+e.url+'"'; + break; + case'local': + x.ffmpegCommandString += x.cust_input+' -i "'+e.path+'"'; + break; + } + //add extra input maps + if(e.details.input_maps){ + e.details.input_maps.forEach(function(v,n){ + x.ffmpegCommandString += createInputMap(n+1,v) + }) + } + //add recording and stream outputs + x.ffmpegCommandString += x.record_string+x.pipe + //hold ffmpeg command for log stream + s.group[e.ke].mon[e.mid].ffmpeg = x.ffmpegCommandString; + //create additional pipes from ffmpeg + x.stdioPipes = []; + var times = config.pipeAddition; + if(e.details.stream_channels){ + times+=e.details.stream_channels.length + } + for(var i=0; i < times; i++){ + x.stdioPipes.push('pipe') + } + x.ffmpegCommandString = s.splitForFFPMEG(x.ffmpegCommandString.replace(/\s+/g,' ').trim()) + return spawn(config.ffmpegDir,x.ffmpegCommandString,{detached: true,stdio:x.stdioPipes}); +} +s.file=function(x,e){ + if(!e){e={}}; + switch(x){ + case'size': + return fs.statSync(e.filename)["size"]; + break; + case'delete': + if(!e){return false;} + return exec('rm -f '+e,{detached: true}); + break; + case'delete_folder': + if(!e){return false;} + return exec('rm -rf '+e,{detached: true}); + break; + case'delete_files': + if(!e.age_type){e.age_type='min'};if(!e.age){e.age='1'}; + exec('find '+e.path+' -type f -c'+e.age_type+' +'+e.age+' -exec rm -f {} +',{detached: true}); + break; + } +} +s.camera=function(x,e,cn,tx){ + if(x!=='motion'){ + var ee=s.init('noReference',e); + if(!e){e={}};if(cn&&cn.ke&&!e.ke){e.ke=cn.ke}; + if(!e.mode){e.mode=x;} + if(!e.id&&e.mid){e.id=e.mid} + } + if(e.details&&(e.details instanceof Object)===false){ + try{e.details=JSON.parse(e.details)}catch(err){} + } + //parse Objects + (['detector_cascades','cords','input_map_choices']).forEach(function(v){ + if(e.details&&e.details[v]&&(e.details[v] instanceof Object)===false){ + try{ + if(e.details[v] === '') e.details[v] = '{}' + e.details[v]=JSON.parse(e.details[v]); + if(!e.details[v])e.details[v]={}; + }catch(err){ + + } + } + }); + //parse Arrays + (['stream_channels','input_maps']).forEach(function(v){ + if(e.details&&e.details[v]&&(e.details[v] instanceof Array)===false){ + try{ + e.details[v]=JSON.parse(e.details[v]); + if(!e.details[v])e.details[v]=[]; + }catch(err){ + e.details[v]=[]; + } + } + }); + s.init(0,{ke:e.ke,mid:e.id}) + switch(x){ + case'buildOptionsFromUrl': + var monitorConfig = cn + URLobject=URL.parse(e) + if(monitorConfig.details.control_url_method === 'ONVIF' && monitorConfig.details.control_base_url === ''){ + URLobject.port = 8000 + }else if(!URLobject.port){ + URLobject.port = 80 + } + options = { + host: URLobject.hostname, + port: URLobject.port, + method: monitorConfig.details.control_url_method, + path: URLobject.pathname, + }; + if(URLobject.query){ + options.path=options.path+'?'+URLobject.query + } + if(URLobject.username&&URLobject.password){ + options.username = URLobject.username + options.password = URLobject.password + options.auth=URLobject.username+':'+URLobject.password + }else if(URLobject.auth){ + var auth = URLobject.auth.split(':') + options.auth=URLobject.auth + options.username = auth[0] + options.password = auth[1] + } + return options + break; + case'control': + if(!s.group[e.ke]||!s.group[e.ke].mon[e.id]){return} + var monitorConfig = s.group[e.ke].mon_conf[e.id]; + if(monitorConfig.details.control!=="1"){s.log(e,{type:lang['Control Error'],msg:lang.ControlErrorText1});return} + if(!monitorConfig.details.control_base_url||monitorConfig.details.control_base_url===''){ + e.base=s.init('url_no_path',monitorConfig); + }else{ + e.base=monitorConfig.details.control_base_url; + } + if(!monitorConfig.details.control_url_stop_timeout || monitorConfig.details.control_url_stop_timeout === ''){ + monitorConfig.details.control_url_stop_timeout = 1000 + } + if(!monitorConfig.details.control_url_method||monitorConfig.details.control_url_method===''){monitorConfig.details.control_url_method="GET"} + var controlURL = e.base+monitorConfig.details['control_url_'+e.direction] + var controlURLOptions = s.camera('buildOptionsFromUrl',controlURL,monitorConfig) + if(monitorConfig.details.control_url_stop_timeout === '0' && monitorConfig.details.control_stop === '1' && s.group[e.ke].mon[e.id].ptzMoving === true){ + e.direction = 'stopMove' + s.group[e.ke].mon[e.id].ptzMoving = false + }else{ + s.group[e.ke].mon[e.id].ptzMoving = true + } + if(monitorConfig.details.control_url_method === 'ONVIF'){ + try{ + var move = function(device){ + var stopOptions = {ProfileToken : device.current_profile.token,'PanTilt': true,'Zoom': true} + switch(e.direction){ + case'center': +// device.services.ptz.gotoHomePosition() + msg = {type:'Center button inactive'} + s.log(e,msg) + cn(msg) + break; + case'stopMove': + msg = {type:'Control Trigger Ended'} + s.log(e,msg) + cn(msg) + device.services.ptz.stop(stopOptions).then((result) => { +// console.log(JSON.stringify(result['data'], null, ' ')); + }).catch((error) => { +// console.error(error); + }); + break; + default: + var controlOptions = { + ProfileToken : device.current_profile.token, + Velocity : {} + } + var onvifDirections = { + "left" : [-1.0,'x'], + "right" : [1.0,'x'], + "down" : [-1.0,'y'], + "up" : [1.0,'y'], + "zoom_in" : [1.0,'zoom'], + "zoom_out" : [-1.0,'zoom'] + } + var direction = onvifDirections[e.direction] + controlOptions.Velocity[direction[1]] = direction[0]; + (['x','y','z']).forEach(function(axis){ + if(!controlOptions.Velocity[axis]) + controlOptions.Velocity[axis] = 0 + }) + if(monitorConfig.details.control_stop=='1'){ + device.services.ptz.continuousMove(controlOptions).then(function(err){ + s.log(e,{type:'Control Trigger Started'}); + if(monitorConfig.details.control_url_stop_timeout !== '0'){ + setTimeout(function(){ + msg = {type:'Control Trigger Ended'} + s.log(e,msg) + cn(msg) + device.services.ptz.stop(stopOptions).then((result) => { +// console.log(JSON.stringify(result['data'], null, ' ')); + }).catch((error) => { + console.log(error); + }); + },monitorConfig.details.control_url_stop_timeout) + } + }).catch(function(err){ + console.log(err) + }); + }else{ + device.services.ptz.absoluteMove(controlOptions).then(function(err){ + msg = {type:'Control Triggered'} + s.log(e,msg); + cn(msg) + }).catch(function(err){ + console.log(err) + }); + } + break; + } + } + //create onvif connection + if(!s.group[e.ke].mon[e.id].onvifConnection){ + s.group[e.ke].mon[e.id].onvifConnection = new onvif.OnvifDevice({ + xaddr : 'http://' + controlURLOptions.host + ':' + controlURLOptions.port + '/onvif/device_service', + user : controlURLOptions.username, + pass : controlURLOptions.password + }) + s.group[e.ke].mon[e.id].onvifConnection.init().then((info) => { + move(s.group[e.ke].mon[e.id].onvifConnection) + }).catch(function(error){ + console.log(error) + s.log(e,{type:lang['Control Error'],msg:error}) + }) + }else{ + move(s.group[e.ke].mon[e.id].onvifConnection) + } + }catch(err){ + console.log(err) + msg = {type:lang['Control Error'],msg:{msg:lang.ControlErrorText2,error:err,options:controlURLOptions,direction:e.direction}} + s.log(e,msg) + cn(msg) + } + }else{ + var stopCamera = function(){ + var stopURL = e.base+monitorConfig.details['control_url_'+e.direction+'_stop'] + var options = s.camera('buildOptionsFromUrl',stopURL,monitorConfig) + var requestOptions = { + url : stopURL, + method : options.method, + auth : { + user : options.username, + pass : options.password + } + } + if(monitorConfig.details.control_digest_auth === '1'){ + requestOptions.sendImmediately = true + } + request(requestOptions,function(err,data){ + if(err){ + msg = {ok:false,type:'Control Error',msg:err} + }else{ + msg = {ok:true,type:'Control Trigger Ended'} + } + cn(msg) + s.log(e,msg); + }) + } + if(e.direction === 'stopMove'){ + stopCamera() + }else{ + var requestOptions = { + url : controlURL, + method : controlURLOptions.method, + auth : { + user : controlURLOptions.username, + pass : controlURLOptions.password + } + } + if(monitorConfig.details.control_digest_auth === '1'){ + requestOptions.sendImmediately = true + } + request(requestOptions,function(err,data){ + if(err){ + msg = {ok:false,type:'Control Error',msg:err}; + cn(msg) + s.log(e,msg); + return + } + if(monitorConfig.details.control_stop=='1'&&e.direction!=='center'){ + s.log(e,{type:'Control Triggered Started'}); + if(monitorConfig.details.control_url_stop_timeout > 0){ + setTimeout(function(){ + stopCamera() + },monitorConfig.details.control_url_stop_timeout) + } + }else{ + msg = {ok:true,type:'Control Triggered'}; + cn(msg) + s.log(e,msg); + } + }) + } + } + break; + case'snapshot'://get snapshot from monitor URL + if(config.doSnapshot===true){ + if(e.mon.mode!=='stop'){ + if(e.mon.details.snap==='1'){ + fs.readFile(s.dir.streams+e.ke+'/'+e.mid+'/s.jpg',function(err,data){ + if(err){s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke);return}; + s.tx({f:'monitor_snapshot',snapshot:data,snapshot_format:'ab',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + }) + }else{ + e.url=s.init('url',e.mon); + switch(e.mon.type){ + case'mjpeg':case'h264':case'local': + if(e.mon.type==='local'){e.url=e.mon.path;} + e.spawn=spawn(config.ffmpegDir,('-loglevel quiet -i '+e.url+' -s 400x400 -r 25 -ss 1.8 -frames:v 1 -f singlejpeg pipe:1').split(' '),{detached: true}) + e.spawn.stdout.on('data',function(data){ + e.snapshot_sent=true; s.tx({f:'monitor_snapshot',snapshot:data.toString('base64'),snapshot_format:'b64',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + e.spawn.kill(); + }); + e.spawn.on('close',function(data){ + if(!e.snapshot_sent){ + s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + } + delete(e.snapshot_sent); + }); + break; + case'jpeg': + request({url:e.url,method:'GET',encoding:null},function(err,data){ + if(err){s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke);return}; + s.tx({f:'monitor_snapshot',snapshot:data.body,snapshot_format:'ab',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + }) + break; + default: + s.tx({f:'monitor_snapshot',snapshot:'...',snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + break; + } + } + }else{ + s.tx({f:'monitor_snapshot',snapshot:'Disabled',snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + } + }else{ + s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + } + break; + case'record_off'://stop recording and start + if(!s.group[e.ke].mon[e.id].record){s.group[e.ke].mon[e.id].record={}} + s.group[e.ke].mon[e.id].record.yes=0; + s.camera('start',e); + break; + case'watch_on'://live streamers - join +// if(s.group[e.ke].mon[e.id].watch[cn.id]){s.camera('watch_off',e,cn,tx);return} + if(!cn.monitor_watching){cn.monitor_watching={}} + if(!cn.monitor_watching[e.id]){cn.monitor_watching[e.id]={ke:e.ke}} + s.group[e.ke].mon[e.id].watch[cn.id]={}; +// if(Object.keys(s.group[e.ke].mon[e.id].watch).length>0){ +// s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND mid=?',[e.ke,e.id],function(err,r) { +// if(r&&r[0]){ +// r=r[0]; +// r.url=s.init('url',r); +// s.group[e.ke].mon.type=r.type; +// } +// }) +// } + break; + case'watch_off'://live streamers - leave + if(cn.monitor_watching){delete(cn.monitor_watching[e.id])} + if(s.group[e.ke].mon[e.id]&&s.group[e.ke].mon[e.id].watch){ + delete(s.group[e.ke].mon[e.id].watch[cn.id]),e.ob=Object.keys(s.group[e.ke].mon[e.id].watch).length + if(e.ob===0){ + delete(s.group[e.ke].mon[e.id].watch) + } + }else{ + e.ob=0; + } + if(tx){tx({f:'monitor_watch_off',ke:e.ke,id:e.id,cnid:cn.id})}; + s.tx({viewers:e.ob,ke:e.ke,id:e.id},'MON_'+e.id); + break; + case'restart'://restart monitor + s.camera('stop',e) + setTimeout(function(){ + s.camera(e.mode,e) + },1300) + break; + case'idle':case'stop'://stop monitor + if(!s.group[e.ke]||!s.group[e.ke].mon[e.id]){return} + if(config.childNodes.enabled === true && config.childNodes.mode === 'master' && s.group[e.ke].mon[e.id].childNode && s.childNodes[s.group[e.ke].mon[e.id].childNode].activeCameras[e.ke+e.id]){ + s.group[e.ke].mon[e.id].started = 0 + s.cx({ + //function + f : 'cameraStop', + //data, options + d : s.group[e.ke].mon_conf[e.id] + },s.group[e.ke].mon[e.id].childNodeId) + s.cx({f:'sync',sync:s.group[e.ke].mon_conf[e.id],ke:e.ke,mid:e.id},s.group[e.ke].mon[e.id].childNodeId); + }else{ + if(s.group[e.ke].mon[e.id].eventBasedRecording.process){ + clearTimeout(s.group[e.ke].mon[e.id].eventBasedRecording.timeout) + s.group[e.ke].mon[e.id].eventBasedRecording.allowEnd=true; + s.group[e.ke].mon[e.id].eventBasedRecording.process.kill('SIGTERM'); + } + if(s.group[e.ke].mon[e.id].fswatch){s.group[e.ke].mon[e.id].fswatch.close();delete(s.group[e.ke].mon[e.id].fswatch)} + if(s.group[e.ke].mon[e.id].fswatchStream){s.group[e.ke].mon[e.id].fswatchStream.close();delete(s.group[e.ke].mon[e.id].fswatchStream)} + if(s.group[e.ke].mon[e.id].last_frame){delete(s.group[e.ke].mon[e.id].last_frame)} + if(s.group[e.ke].mon[e.id].started!==1){return} + s.kill(s.group[e.ke].mon[e.id].spawn,e); + if(e.neglectTriggerTimer===1){ + delete(e.neglectTriggerTimer); + }else{ + clearTimeout(s.group[e.ke].mon[e.id].trigger_timer) + delete(s.group[e.ke].mon[e.id].trigger_timer) + } + clearInterval(s.group[e.ke].mon[e.id].running); + clearInterval(s.group[e.ke].mon[e.id].detector_notrigger_timeout) + clearTimeout(s.group[e.ke].mon[e.id].err_fatal_timeout); + s.group[e.ke].mon[e.id].started=0; + if(s.group[e.ke].mon[e.id].record){s.group[e.ke].mon[e.id].record.yes=0} + s.tx({f:'monitor_stopping',mid:e.id,ke:e.ke,time:s.formattedTime()},'GRP_'+e.ke); + s.camera('snapshot',{mid:e.id,ke:e.ke,mon:e}) + if(x==='stop'){ + s.log(e,{type:lang['Monitor Stopped'],msg:lang.MonitorStoppedText}); + clearTimeout(s.group[e.ke].mon[e.id].delete) + if(e.delete===1){ + s.group[e.ke].mon[e.id].delete=setTimeout(function(){ + delete(s.group[e.ke].mon[e.id]); + delete(s.group[e.ke].mon_conf[e.id]); + },1000*60); + } + }else{ + s.tx({f:'monitor_idle',mid:e.id,ke:e.ke,time:s.formattedTime()},'GRP_'+e.ke); + s.log(e,{type:lang['Monitor Idling'],msg:lang.MonitorIdlingText}); + } + } + break; + case'start':case'record'://watch or record monitor url + s.init(0,{ke:e.ke,mid:e.id}) + if(!s.group[e.ke].mon_conf[e.id]){s.group[e.ke].mon_conf[e.id]=s.init('noReference',e);} + e.url = s.init('url',e); + if(s.group[e.ke].mon[e.id].started===1){ + //stop action, monitor already started or recording + return + } + //lock this function + s.group[e.ke].mon[e.id].started = 1; + //create host string without username and password + e.hosty = e.host.split('@'); + if(e.hosty[1]){ + //username and password found + e.hosty = e.hosty[1] + }else{ + //no username or password in `host` string + e.hosty = e.hosty[0] + } + //set recording status + if(x==='record'){ + s.group[e.ke].mon[e.id].record.yes=1; + }else{ + s.group[e.ke].mon[e.mid].record.yes=0; + } + //set the recording directory + if(e.details && e.details.dir && e.details.dir !== '' && config.childNodes.mode !== 'child'){ + //addStorage choice + e.dir=s.checkCorrectPathEnding(e.details.dir)+e.ke+'/'; + if (!fs.existsSync(e.dir)){ + fs.mkdirSync(e.dir); + } + e.dir=e.dir+e.id+'/'; + if (!fs.existsSync(e.dir)){ + fs.mkdirSync(e.dir); + } + }else{ + //MAIN videos dir + e.dir=s.dir.videos+e.ke+'/'; + if (!fs.existsSync(e.dir)){ + fs.mkdirSync(e.dir); + } + e.dir=s.dir.videos+e.ke+'/'+e.id+'/'; + if (!fs.existsSync(e.dir)){ + fs.mkdirSync(e.dir); + } + } + //set the temporary files directory + var setStreamDir = function(){ + //stream dir + e.sdir=s.dir.streams+e.ke+'/'; + if (!fs.existsSync(e.sdir)){ + fs.mkdirSync(e.sdir); + } + e.sdir=s.dir.streams+e.ke+'/'+e.id+'/'; + if (!fs.existsSync(e.sdir)){ + fs.mkdirSync(e.sdir); + }else{ + s.file('delete_folder',e.sdir+'*') + } + } + setStreamDir() + //set up fatal error handler + if(e.details.fatal_max===''){ + e.details.fatal_max = 10 + }else{ + e.details.fatal_max = parseFloat(e.details.fatal_max) + } + var errorFatal = function(errorMessage){ + if(config.debugSystem === true){ + console.log(errorMessage,(new Error()).stack) + } + clearTimeout(s.group[e.ke].mon[e.id].err_fatal_timeout); + ++errorFatalCount; + if(s.group[e.ke].mon[e.id].started===1){ + s.group[e.ke].mon[e.id].err_fatal_timeout=setTimeout(function(){ + if(e.details.fatal_max!==0&&errorFatalCount>e.details.fatal_max){ + s.camera('stop',{id:e.id,ke:e.ke}) + }else{ + launchMonitorProcesses() + }; + },5000); + }else{ + s.kill(s.group[e.ke].mon[e.id].spawn,e); + } + } + errorFatalCount = 0; + //set master based process launcher + launchMonitorProcesses = function(){ + if(e.details.detector_trigger=='1'){ + s.group[e.ke].mon[e.id].motion_lock=setTimeout(function(){ + clearTimeout(s.group[e.ke].mon[e.id].motion_lock); + delete(s.group[e.ke].mon[e.id].motion_lock); + },30000) + } + //cutoff time and recording check interval + if(!e.details.cutoff||e.details.cutoff===''){e.cutoff=15}else{e.cutoff=parseFloat(e.details.cutoff)}; + if(isNaN(e.cutoff)===true){e.cutoff=15} + //start "no motion" checker + if(e.details.detector=='1'&&e.details.detector_notrigger=='1'){ + if(!e.details.detector_notrigger_timeout||e.details.detector_notrigger_timeout===''){ + e.details.detector_notrigger_timeout=10 + } + e.detector_notrigger_timeout=parseFloat(e.details.detector_notrigger_timeout)*1000*60; + s.sqlQuery('SELECT mail FROM Users WHERE ke=? AND details NOT LIKE ?',[e.ke,'%"sub"%'],function(err,r){ + r=r[0]; + s.group[e.ke].mon[e.id].detector_notrigger_timeout_function=function(){ + if(config.mail&&e.details.detector_notrigger_mail=='1'){ + e.mailOptions = { + from: '"ShinobiCCTV" ', // sender address + to: r.mail, // list of receivers + subject: lang.NoMotionEmailText1+' '+e.name+' ('+e.id+')', // Subject line + html: ''+lang.NoMotionEmailText2+' '+e.details.detector_notrigger_timeout+' '+lang.minutes+'.', + }; + e.mailOptions.html+='
'+lang['Monitor Name']+' : '+e.name+'
' + e.mailOptions.html+='
'+lang['Monitor ID']+' : '+e.id+'
' + nodemailer.sendMail(e.mailOptions, (error, info) => { + if (error) { + s.systemLog('detector:notrigger:sendMail',error) + s.tx({f:'error',ff:'detector_notrigger_mail',id:e.id,ke:e.ke,error:error},'GRP_'+e.ke); + return ; + } + s.tx({f:'detector_notrigger_mail',id:e.id,ke:e.ke,info:info},'GRP_'+e.ke); + }); + } + } + clearInterval(s.group[e.ke].mon[e.id].detector_notrigger_timeout) + s.group[e.ke].mon[e.id].detector_notrigger_timeout=setInterval(s.group[e.ke].mon[e.id].detector_notrigger_timeout_function,s.group[e.ke].mon[e.id].detector_notrigger_timeout) + }) + } + var resetStreamCheck=function(){ + clearTimeout(s.group[e.ke].mon[e.id].checkStream) + s.group[e.ke].mon[e.id].checkStream=setTimeout(function(){ + if(s.group[e.ke].mon[e.id].started===1){ + launchMonitorProcesses(); + s.log(e,{type:lang['Camera is not streaming'],msg:{msg:lang['Restarting Process']}}); + } + },60000*1); + } + if(config.childNodes.mode !== 'child' && s.platform!=='darwin' && (x==='record' || (x==='start'&&e.details.detector_record_method==='sip'))){ + //check if ffmpeg is recording + s.group[e.ke].mon[e.id].fswatch = fs.watch(e.dir, {encoding : 'utf8'}, (event, filename) => { + switch(event){ + case'rename': + s.group[e.ke].mon[e.id].open = filename.split('.')[0] + break; + case'change': + clearTimeout(s.group[e.ke].mon[e.id].checker) + clearTimeout(s.group[e.ke].mon[e.id].checkStream) + s.group[e.ke].mon[e.id].checker=setTimeout(function(){ + if(s.group[e.ke].mon[e.id].started===1){ + launchMonitorProcesses(); + s.log(e,{type:lang['Camera is not recording'],msg:{msg:lang['Restarting Process']}}); + } + },60000 * e.cutoff * 1.1); + break; + } + }); + } + if( + //is MacOS + s.platform !== 'darwin' && + //is Watch-Only or Record + (x === 'start' || x === 'record') && + //if JPEG API enabled or Stream Type is HLS + (e.details.stream_type === 'jpeg' || e.details.stream_type === 'hls' || e.details.snap === '1') + ){ + s.group[e.ke].mon[e.id].fswatchStream = fs.watch(e.sdir, {encoding : 'utf8'}, () => { + resetStreamCheck() + }) + } + s.camera('snapshot',{mid:e.id,ke:e.ke,mon:e}) + //check host to see if has password and user in it + setStreamDir() + clearTimeout(s.group[e.ke].mon[e.id].checker) + if(s.group[e.ke].mon[e.id].started===1){ + e.error_count=0; + s.group[e.ke].mon[e.id].error_socket_timeout_count=0; + s.kill(s.group[e.ke].mon[e.id].spawn,e); + startVideoProcessor=function(err,o){ + if(o.success===true){ + e.frames=0; + if(!s.group[e.ke].mon[e.id].record){s.group[e.ke].mon[e.id].record={yes:1}}; + //launch ffmpeg (main) + s.group[e.ke].mon[e.id].spawn = s.ffmpeg(e); + //on unexpected exit restart + s.group[e.ke].mon[e.id].spawn_exit=function(){ + if(s.group[e.ke].mon[e.id].started===1){ + if(e.details.loglevel!=='quiet'){ + s.log(e,{type:lang['Process Unexpected Exit'],msg:{msg:lang['Process Crashed for Monitor']+' : '+e.id,cmd:s.group[e.ke].mon[e.id].ffmpeg}}); + } + errorFatal('Process Unexpected Exit'); + } + } + s.group[e.ke].mon[e.id].spawn.on('end',s.group[e.ke].mon[e.id].spawn_exit) + s.group[e.ke].mon[e.id].spawn.on('exit',s.group[e.ke].mon[e.id].spawn_exit) + // +// s.group[e.ke].mon[e.id].spawn.stdio[5].on('data',function(data){ +// data = data.toString(); +// console.log('---') +// var json = {} +// data.split('\n').forEach(function(v){ +// var vv = v.split('=') +// json[vv[0]] = vv[1] +// }) +// console.log(json) +// }) + //emitter for mjpeg + if(!e.details.stream_mjpeg_clients||e.details.stream_mjpeg_clients===''||isNaN(e.details.stream_mjpeg_clients)===false){e.details.stream_mjpeg_clients=20;}else{e.details.stream_mjpeg_clients=parseInt(e.details.stream_mjpeg_clients)} + s.group[e.ke].mon[e.id].emitter = new events.EventEmitter().setMaxListeners(e.details.stream_mjpeg_clients); + s.log(e,{type:'FFMPEG Process Started',msg:{cmd:s.group[e.ke].mon[e.id].ffmpeg}}); + s.tx({f:'monitor_starting',mode:x,mid:e.id,time:s.formattedTime()},'GRP_'+e.ke); + //start workers + if(e.type==='jpeg'){ + if(!e.details.sfps||e.details.sfps===''){ + var capture_fps=parseFloat(e.details.sfps); + if(isNaN(capture_fps)){capture_fps=1} + } + if(s.group[e.ke].mon[e.id].spawn){ + s.group[e.ke].mon[e.id].spawn.stdin.on('error',function(err){ + if(err&&e.details.loglevel!=='quiet'){ + s.log(e,{type:'STDIN ERROR',msg:err}); + } + }) + }else{ + if(x==='record'){ + s.log(e,{type:lang.FFmpegCantStart,msg:lang.FFmpegCantStartText}); + return + } + } + e.captureOne=function(f){ + s.group[e.ke].mon[e.id].record.request=request({url:e.url,method:'GET',encoding: null,timeout:15000},function(err,data){ + if(err){ + return; + } + }).on('data',function(d){ + if(!e.buffer0){ + e.buffer0=[d] + }else{ + e.buffer0.push(d); + } + if((d[d.length-2] === 0xFF && d[d.length-1] === 0xD9)){ + e.buffer0=Buffer.concat(e.buffer0); + ++e.frames; + if(s.group[e.ke].mon[e.id].spawn&&s.group[e.ke].mon[e.id].spawn.stdin){ + s.group[e.ke].mon[e.id].spawn.stdin.write(e.buffer0); + } + if(s.group[e.ke].mon[e.id].started===1){ + s.group[e.ke].mon[e.id].record.capturing=setTimeout(function(){ + e.captureOne() + },1000/capture_fps); + } + e.buffer0=null; + } + if(!e.timeOut){ + e.timeOut=setTimeout(function(){e.error_count=0;delete(e.timeOut);},3000); + } + + }).on('error', function(err){ + ++e.error_count; + clearTimeout(e.timeOut);delete(e.timeOut); + if(e.details.loglevel!=='quiet'){ + s.log(e,{type:lang['JPEG Error'],msg:{msg:lang.JPEGErrorText,info:err}}); + switch(err.code){ + case'ESOCKETTIMEDOUT': + case'ETIMEDOUT': + ++s.group[e.ke].mon[e.id].error_socket_timeout_count + if(e.details.fatal_max!==0&&s.group[e.ke].mon[e.id].error_socket_timeout_count>e.details.fatal_max){ + s.log(e,{type:lang['Fatal Maximum Reached'],msg:{code:'ESOCKETTIMEDOUT',msg:lang.FatalMaximumReachedText}}); + s.camera('stop',e) + }else{ + s.log(e,{type:lang['Restarting Process'],msg:{code:'ESOCKETTIMEDOUT',msg:lang.FatalMaximumReachedText}}); + s.camera('restart',e) + } + return; + break; + } + } + if(e.details.fatal_max!==0&&e.error_count>e.details.fatal_max){ + clearTimeout(s.group[e.ke].mon[e.id].record.capturing); + launchMonitorProcesses(); + } + }); + } + e.captureOne() + } + if(!s.group[e.ke]||!s.group[e.ke].mon[e.id]){s.init(0,e)} + s.group[e.ke].mon[e.id].spawn.on('error',function(er){ + s.log(e,{type:'Spawn Error',msg:er});errorFatal('Spawn Error') + }); + if(e.details.detector==='1'){ + s.ocvTx({f:'init_monitor',id:e.id,ke:e.ke}) + //frames from motion detect + if(e.details.detector_pam==='1'){ + var width, + height, + globalSensitivity, + fullFrame = false + if(s.group[e.ke].mon_conf[e.id].details.detector_scale_x===''||s.group[e.ke].mon_conf[e.id].details.detector_scale_y===''){ + width = s.group[e.ke].mon_conf[e.id].details.detector_scale_x; + height = s.group[e.ke].mon_conf[e.id].details.detector_scale_y; + }else{ + width = e.width + height = e.height + } + if(e.details.detector_sensitivity===''){ + globalSensitivity = 10 + }else{ + globalSensitivity = parseInt(e.details.detector_sensitivity) + } + if(e.details.detector_frame==='1'){ + fullFrame={ + name:'FULL_FRAME', + sensitivity:globalSensitivity, + points:[ + [0,0], + [0,height], + [width,height], + [width,0] + ] + }; + } + var regions = s.createPamDiffRegionArray(s.group[e.ke].mon_conf[e.id].details.cords,globalSensitivity,fullFrame); + if(!s.group[e.ke].mon[e.id].noiseFilterArray)s.group[e.ke].mon[e.id].noiseFilterArray = {} + var noiseFilterArray = s.group[e.ke].mon[e.id].noiseFilterArray + Object.keys(regions.notForPam).forEach(function(name){ + if(!noiseFilterArray[name])noiseFilterArray[name]=[]; + }) + s.group[e.ke].mon[e.id].pamDiff = new PamDiff({grayscale: 'luminosity', regions : regions.forPam}); + s.group[e.ke].mon[e.id].p2p = new P2P(); + var sendTrigger = function(trigger){ + var detectorObject = { + f:'trigger', + id:e.id, + ke:e.ke, + name:trigger.name, + details:{ + plug:'built-in', + name:trigger.name, + reason:'motion', + confidence:trigger.percent, + }, + plates:[], + imgHeight:height, + imgWidth:width + } + detectorObject.doObjectDetection = (s.ocv && e.details.detector_use_detect_object === '1') + s.camera('motion',detectorObject) + if(detectorObject.doObjectDetection === true){ + s.ocvTx({f:'frame',mon:s.group[e.ke].mon_conf[e.id].details,ke:e.ke,id:e.id,time:s.formattedTime(),frame:s.group[e.ke].mon[e.id].lastJpegDetectorFrame}); + } + } + var filterTheNoise = function(trigger){ + if(noiseFilterArray[trigger.name].length > 2){ + var thePreviousTriggerPercent = noiseFilterArray[trigger.name][noiseFilterArray[trigger.name].length - 1]; + var triggerDifference = trigger.percent - thePreviousTriggerPercent; + var noiseRange = e.details.detector_noise_filter_range + if(!noiseRange || noiseRange === ''){ + noiseRange = 6 + } + noiseRange = parseFloat(noiseRange) + if(((trigger.percent - thePreviousTriggerPercent) < noiseRange)||(thePreviousTriggerPercent - trigger.percent) > -noiseRange){ + noiseFilterArray[trigger.name].push(trigger.percent); + } + }else{ + noiseFilterArray[trigger.name].push(trigger.percent); + } + if(noiseFilterArray[trigger.name].length > 10){ + noiseFilterArray[trigger.name] = noiseFilterArray[trigger.name].splice(1,10) + } + var theNoise = 0; + noiseFilterArray[trigger.name].forEach(function(v,n){ + theNoise += v; + }) + theNoise = theNoise / noiseFilterArray[trigger.name].length; +// console.log(noiseFilterArray[trigger.name]) +// console.log(theNoise) + var triggerPercentWithoutNoise = trigger.percent - theNoise; + if(triggerPercentWithoutNoise > regions.notForPam[trigger.name].sensitivity){ + sendTrigger(trigger); + } + } + if(e.details.detector_noise_filter==='1'){ + s.group[e.ke].mon[e.id].pamDiff.on('diff', (data) => { + data.trigger.forEach(filterTheNoise) + }) + }else{ + s.group[e.ke].mon[e.id].pamDiff.on('diff', (data) => { + data.trigger.forEach(sendTrigger) + }) + } + + s.group[e.ke].mon[e.id].spawn.stdio[3].pipe(s.group[e.ke].mon[e.id].p2p).pipe(s.group[e.ke].mon[e.id].pamDiff) + if(e.details.detector_use_detect_object === '1'){ + s.group[e.ke].mon[e.id].spawn.stdio[4].on('data',function(d){ + s.group[e.ke].mon[e.id].lastJpegDetectorFrame = d + }) + } + }else{ + s.group[e.ke].mon[e.id].spawn.stdio[3].on('data',function(d){ + s.ocvTx({f:'frame',mon:s.group[e.ke].mon_conf[e.id].details,ke:e.ke,id:e.id,time:s.formattedTime(),frame:d}); + }) + } + } + //frames to stream + switch(e.details.stream_type){ + case'mp4': + s.group[e.ke].mon[e.id].mp4frag['MAIN'] = new Mp4Frag(); + s.group[e.ke].mon[e.id].spawn.stdio[1].pipe(s.group[e.ke].mon[e.id].mp4frag['MAIN']) + break; + case'flv': + e.frame_to_stream=function(d){ + if(!s.group[e.ke].mon[e.id].firstStreamChunk['MAIN'])s.group[e.ke].mon[e.id].firstStreamChunk['MAIN'] = d; + e.frame_to_stream=function(d){ + resetStreamCheck() + s.group[e.ke].mon[e.id].emitter.emit('data',d); + } + e.frame_to_stream(d) + } + break; + case'mjpeg': + e.frame_to_stream=function(d){ + resetStreamCheck() + s.group[e.ke].mon[e.id].emitter.emit('data',d); + } + break; +// case'pam': +// s.group[e.ke].mon[e.id].p2pStream = new P2P(); +// s.group[e.ke].mon[e.id].spawn.stdout.pipe(s.group[e.ke].mon[e.id].p2pStream) +// s.group[e.ke].mon[e.id].p2pStream.on('pam',function(d){ +// resetStreamCheck() +// s.tx({f:'pam_frame',ke:e.ke,id:e.id,imageData:{ +// data : d.pixels, +// height : d.height, +// width : d.width +// }},'MON_STREAM_'+e.id); +// }) +// break; + case'b64':case undefined:case null:case'': + var buffer + e.frame_to_stream=function(d){ + resetStreamCheck() + if(!buffer){ + buffer=[d] + }else{ + buffer.push(d); + } + if((d[d.length-2] === 0xFF && d[d.length-1] === 0xD9)){ + s.group[e.ke].mon[e.id].emitter.emit('data',Buffer.concat(buffer)); + buffer=null; + } + } + break; + } + if(e.frame_to_stream){ + s.group[e.ke].mon[e.id].spawn.stdout.on('data',e.frame_to_stream); + } + if(e.details.stream_channels&&e.details.stream_channels!==''){ + var createStreamEmitter = function(channel,number){ + var pipeNumber = number+config.pipeAddition; + if(!s.group[e.ke].mon[e.id].emitterChannel[pipeNumber]){ + s.group[e.ke].mon[e.id].emitterChannel[pipeNumber] = new events.EventEmitter().setMaxListeners(0); + } + var frame_to_stream + switch(channel.stream_type){ + case'mp4': + s.group[e.ke].mon[e.id].mp4frag[pipeNumber] = new Mp4Frag(); + s.group[e.ke].mon[e.id].spawn.stdio[pipeNumber].pipe(s.group[e.ke].mon[e.id].mp4frag[pipeNumber]) + break; + case'mjpeg': + frame_to_stream=function(d){ + s.group[e.ke].mon[e.id].emitterChannel[pipeNumber].emit('data',d); + } + break; + case'flv': + frame_to_stream=function(d){ + if(!s.group[e.ke].mon[e.id].firstStreamChunk[pipeNumber])s.group[e.ke].mon[e.id].firstStreamChunk[pipeNumber] = d; + frame_to_stream=function(d){ + s.group[e.ke].mon[e.id].emitterChannel[pipeNumber].emit('data',d); + } + frame_to_stream(d) + } + break; + case'h264': + frame_to_stream=function(d){ + s.group[e.ke].mon[e.id].emitterChannel[pipeNumber].emit('data',d); + } + break; + } + if(frame_to_stream){ + s.group[e.ke].mon[e.id].spawn.stdio[pipeNumber].on('data',frame_to_stream); + } + } + e.details.stream_channels.forEach(createStreamEmitter) + } + if(x==='record'||e.type==='mjpeg'||e.type==='h264'||e.type==='local'){ + s.group[e.ke].mon[e.id].spawn.stderr.on('data',function(d){ + d=d.toString(); + e.chk=function(x){return d.indexOf(x)>-1;} + switch(true){ + //mp4 output with webm encoder chosen + case e.chk('Could not find tag for vp8'): + case e.chk('Only VP8 or VP9 Video'): + case e.chk('Could not write header'): +// switch(e.ext){ +// case'mp4': +// e.details.vcodec='libx264' +// e.details.acodec='none' +// break; +// case'webm': +// e.details.vcodec='libvpx' +// e.details.acodec='none' +// break; +// } +// if(e.details.stream_type==='hls'){ +// e.details.stream_vcodec='libx264' +// e.details.stream_acodec='no' +// } +// s.camera('restart',e) + return s.log(e,{type:lang['Incorrect Settings Chosen'],msg:{msg:d}}) + break; + case e.chk('NULL @'): + case e.chk('RTP: missed'): + case e.chk('deprecated pixel format used, make sure you did set range correctly'): + return + break; +// case e.chk('av_interleaved_write_frame'): + case e.chk('Connection refused'): + case e.chk('Connection timed out'): + //restart + setTimeout(function(){ + s.log(e,{type:lang['Connection timed out'],msg:lang['Retrying...']}); + errorFatal('Connection timed out'); + },1000) + break; +// case e.chk('No such file or directory'): +// case e.chk('Unable to open RTSP for listening'): +// case e.chk('timed out'): +// case e.chk('Invalid data found when processing input'): +// case e.chk('Immediate exit requested'): +// case e.chk('reset by peer'): +// if(e.frames===0&&x==='record'){s.video('delete',e)}; +// setTimeout(function(){ +// if(!s.group[e.ke].mon[e.id].spawn){launchMonitorProcesses()} +// },2000) +// break; + case e.chk('mjpeg_decode_dc'): + case e.chk('bad vlc'): + case e.chk('error dc'): + launchMonitorProcesses() + break; + case /T[0-9][0-9]-[0-9][0-9]-[0-9][0-9]./.test(d): + var filename = d.split('.')[0]+'.'+e.ext + s.video('insertCompleted',e,{ + file : filename + }) + s.log(e,{type:lang['Video Finished'],msg:{filename:d}}) + if( + e.details.detector==='1'&& + s.group[e.ke].mon[e.id].started===1&& + e.details&& + e.details.detector_record_method==='del'&& + e.details.detector_delete_motionless_videos==='1'&& + s.group[e.ke].mon[e.id].detector_motion_count===0 + ){ + if(e.details.loglevel!=='quiet'){ + s.log(e,{type:lang['Delete Motionless Video'],msg:filename}); + } + s.video('delete',{ + filename : filename, + ke : e.ke, + id : e.id + }) + } + s.group[e.ke].mon[e.id].detector_motion_count = 0 + return; + break; + } + s.log(e,{type:"FFMPEG STDERR",msg:d}) + }); + } + }else{ + s.log(e,{type:lang["Ping Failed"],msg:lang.skipPingText1}); + errorFatal("Ping Failed");return; + } + } + if(e.type!=='socket'&&e.type!=='dashcam'&&e.protocol!=='udp'&&e.type!=='local'||e.details.skip_ping === '1'){ + connectionTester.test(e.hosty,e.port,2000,startVideoProcessor); + }else{ + startVideoProcessor(null,{success:true}) + } + }else{ + s.kill(s.group[e.ke].mon[e.id].spawn,e); + } + } + //start drawing files + delete(s.group[e.ke].mon[e.id].childNode) + if(config.childNodes.enabled === true && config.childNodes.mode === 'master'){ + var childNodeList = Object.keys(s.childNodes) + if(childNodeList.length>0){ + e.ch_stop = 0; + launchMonitorProcesses = function(){ + startVideoProcessor = function(){ + s.cx({ + //function + f : 'cameraStart', + //mode + mode : x, + //data, options + d : s.group[e.ke].mon_conf[e.id] + },s.group[e.ke].mon[e.id].childNodeId) + } + if(e.type!=='socket'&&e.type!=='dashcam'&&e.protocol!=='udp'&&e.type!=='local' && e.details.skip_ping !== '1'){ + console.log(e.hosty,e.port) + connectionTester.test(e.hosty,e.port,2000,function(err,o){ + if(o.success===true){ + startVideoProcessor() + }else{ + s.log(e,{type:lang["Ping Failed"],msg:lang.skipPingText1}); + errorFatal("Ping Failed");return; + } + }) + }else{ + startVideoProcessor() + } + } + childNodeList.forEach(function(ip){ + if(e.ch_stop===0&&s.childNodes[ip].cpu<80){ + e.ch_stop=1; + s.childNodes[ip].activeCameras[e.ke+e.id] = s.init('noReference',s.group[e.ke].mon_conf[e.id]); + s.group[e.ke].mon[e.id].childNode = ip; + s.group[e.ke].mon[e.id].childNodeId = s.childNodes[ip].cnid; + s.cx({f:'sync',sync:s.group[e.ke].mon_conf[e.id],ke:e.ke,mid:e.id},s.group[e.ke].mon[e.id].childNodeId); + launchMonitorProcesses(); + } + }) + }else{ + launchMonitorProcesses(); + } + }else{ + launchMonitorProcesses(); + } + break; + case'motion': + var d=e; + if(s.group[d.ke].mon[d.id].open){ + d.details.videoTime = s.group[d.ke].mon[d.id].open; + } + var detailString = JSON.stringify(d.details); + if(!s.group[d.ke]||!s.group[d.ke].mon[d.id]){ + return s.systemLog(lang['No Monitor Found, Ignoring Request']) + } + d.mon=s.group[d.ke].mon_conf[d.id]; + if(!s.group[d.ke].mon[d.id].detector_motion_count){ + s.group[d.ke].mon[d.id].detector_motion_count=0 + } + s.group[d.ke].mon[d.id].detector_motion_count+=1 + if(s.group[d.ke].mon[d.id].motion_lock){ + return + } + var detector_lock_timeout + if(!d.mon.details.detector_lock_timeout||d.mon.details.detector_lock_timeout===''){ + detector_lock_timeout = 2000 + } + detector_lock_timeout = parseFloat(d.mon.details.detector_lock_timeout); + if(!s.group[d.ke].mon[d.id].detector_lock_timeout){ + s.group[d.ke].mon[d.id].detector_lock_timeout=setTimeout(function(){ + clearTimeout(s.group[d.ke].mon[d.id].detector_lock_timeout) + delete(s.group[d.ke].mon[d.id].detector_lock_timeout) + },detector_lock_timeout) + }else{ + return + } + if(d.doObjectDetection !== true){ + //save this detection result in SQL, only coords. not image. + if(d.mon.details.detector_save==='1'){ + s.sqlQuery('INSERT INTO Events (ke,mid,details) VALUES (?,?,?)',[d.ke,d.id,detailString]) + } + if(d.mon.details.detector_notrigger=='1'){ + var detector_notrigger_timeout + if(!d.mon.details.detector_notrigger_timeout||d.mon.details.detector_notrigger_timeout===''){ + detector_notrigger_timeout = 10 + } + detector_notrigger_timeout = parseFloat(d.mon.details.detector_notrigger_timeout)*1000*60; + s.group[e.ke].mon[e.id].detector_notrigger_timeout = detector_notrigger_timeout; + clearInterval(s.group[d.ke].mon[d.id].detector_notrigger_timeout) + s.group[d.ke].mon[d.id].detector_notrigger_timeout = setInterval(s.group[d.ke].mon[d.id].detector_notrigger_timeout_function,detector_notrigger_timeout) + } + if(d.mon.details.detector_webhook=='1'){ + var detector_webhook_url = d.mon.details.detector_webhook_url + .replace(/{{TIME}}/g,s.timeObject(new Date).format()) + .replace(/{{MONITOR_ID}}/g,d.id) + .replace(/{{GROUP_KEY}}/g,d.ke) + .replace(/{{DETAILS}}/g,detailString) + http.get(detector_webhook_url, function(data) { + data.setEncoding('utf8'); + var chunks=''; + data.on('data', (chunk) => { + chunks+=chunk; + }); + data.on('end', () => { + + }); + + }).on('error', function(e) { + + }).end(); + } + var detector_timeout + if(!d.mon.details.detector_timeout||d.mon.details.detector_timeout===''){ + detector_timeout = 10 + }else{ + detector_timeout = parseFloat(d.mon.details.detector_timeout) + } + if(d.mon.mode=='start'&&d.mon.details.detector_trigger==='1'&&d.mon.details.detector_record_method==='sip'){ + //s.group[d.ke].mon[d.id].eventBasedRecording.timeout + // clearTimeout(s.group[d.ke].mon[d.id].eventBasedRecording.timeout) + s.group[d.ke].mon[d.id].eventBasedRecording.timeout = setTimeout(function(){ + s.group[d.ke].mon[d.id].eventBasedRecording.allowEnd=true; + },detector_timeout * 950 * 60) + if(!s.group[d.ke].mon[d.id].eventBasedRecording.process){ + if(!d.auth){ + d.auth=s.gid(); + } + if(!s.group[d.ke].users[d.auth]){ + s.group[d.ke].users[d.auth]={system:1,details:{},lang:lang} + } + s.group[d.ke].mon[d.id].eventBasedRecording.allowEnd = false; + var runRecord = function(){ + var filename = s.formattedTime()+'.mp4' + s.log(d,{type:"Traditional Recording",msg:"Started"}) + //-t 00:'+s.timeObject(new Date(detector_timeout * 1000 * 60)).format('mm:ss')+' + s.group[d.ke].mon[d.id].eventBasedRecording.process = spawn(config.ffmpegDir,s.splitForFFPMEG(('-loglevel warning -analyzeduration 1000000 -probesize 1000000 -re -i http://'+config.ip+':'+config.port+'/'+d.auth+'/hls/'+d.ke+'/'+d.id+'/detectorStream.m3u8 -t 00:'+s.timeObject(new Date(detector_timeout * 1000 * 60)).format('mm:ss')+' -c:v copy -strftime 1 "'+s.video('getDir',d.mon) + filename + '"').replace(/\s+/g,' ').trim())) + var ffmpegError=''; + var error + s.group[d.ke].mon[d.id].eventBasedRecording.process.stderr.on('data',function(data){ + s.log(d,{type:"Traditional Recording",msg:data.toString()}) + }) + s.group[d.ke].mon[d.id].eventBasedRecording.process.on('close',function(){ + if(!s.group[d.ke].mon[d.id].eventBasedRecording.allowEnd){ + s.log(d,{type:"Traditional Recording",msg:"Detector Recording Process Exited Prematurely. Restarting."}) + runRecord() + return + } + s.video('insertCompleted',d.mon,{ + file : filename + }) + s.log(d,{type:"Traditional Recording",msg:"Detector Recording Complete"}) + delete(s.group[d.ke].users[d.auth]) + s.log(d,{type:"Traditional Recording",msg:'Clear Recorder Process'}) + delete(s.group[d.ke].mon[d.id].eventBasedRecording.process) + delete(s.group[d.ke].mon[d.id].eventBasedRecording.timeout) + clearTimeout(s.group[d.ke].mon[d.id].checker) + }) + } + runRecord() + } + }else if(d.mon.mode!=='stop'&&d.mon.details.detector_trigger=='1'&&d.mon.details.detector_record_method==='hot'){ + if(!d.auth){ + d.auth=s.gid(); + } + if(!s.group[d.ke].users[d.auth]){ + s.group[d.ke].users[d.auth]={system:1,details:{},lang:lang} + } + d.urlQuery=[] + d.url='http://'+config.ip+':'+config.port+'/'+d.auth+'/monitor/'+d.ke+'/'+d.id+'/record/'+detector_timeout+'/min'; + if(d.mon.details.watchdog_reset!=='0'){ + d.urlQuery.push('reset=1') + } + if(d.mon.details.detector_trigger_record_fps&&d.mon.details.detector_trigger_record_fps!==''&&d.mon.details.detector_trigger_record_fps!=='0'){ + d.urlQuery.push('fps='+d.mon.details.detector_trigger_record_fps) + } + if(d.urlQuery.length>0){ + d.url+='?'+d.urlQuery.join('&') + } + http.get(d.url, function(data) { + data.setEncoding('utf8'); + var chunks=''; + data.on('data', (chunk) => { + chunks+=chunk; + }); + data.on('end', () => { + delete(s.group[d.ke].users[d.auth]) + d.cx.f='detector_record_engaged'; + d.cx.msg=JSON.parse(chunks); + s.tx(d.cx,'GRP_'+d.ke); + }); + + }).on('error', function(e) { + + }).end(); + } + //mailer + if(config.mail&&!s.group[d.ke].mon[d.id].detector_mail&&d.mon.details.detector_mail==='1'){ + s.sqlQuery('SELECT mail FROM Users WHERE ke=? AND details NOT LIKE ?',[d.ke,'%"sub"%'],function(err,r){ + r=r[0]; + var detector_mail_timeout + if(!d.mon.details.detector_mail_timeout||d.mon.details.detector_mail_timeout===''){ + detector_mail_timeout = 1000*60*10; + }else{ + detector_mail_timeout = parseFloat(d.mon.details.detector_mail_timeout)*1000*60; + } + //lock mailer so you don't get emailed on EVERY trigger event. + s.group[d.ke].mon[d.id].detector_mail=setTimeout(function(){ + //unlock so you can mail again. + clearTimeout(s.group[d.ke].mon[d.id].detector_mail); + delete(s.group[d.ke].mon[d.id].detector_mail); + },detector_mail_timeout); + d.frame_filename='Motion_'+(d.mon.name.replace(/[^\w\s]/gi, ''))+'_'+d.id+'_'+d.ke+'_'+s.formattedTime()+'.jpg'; + fs.readFile(s.dir.streams+'/'+d.ke+'/'+d.id+'/s.jpg',function(err, frame){ + d.mailOptions = { + from: '"ShinobiCCTV" ', // sender address + to: r.mail, // list of receivers + subject: lang.Event+' - '+d.frame_filename, // Subject line + html: ''+lang.EventText1+' '+s.timeObject(new Date).format()+'.', + }; + if(err){ + s.systemLog(lang.EventText2+' '+d.ke+' '+d.id,err) + }else{ + d.mailOptions.attachments=[ + { + filename: d.frame_filename, + content: frame + } + ] + d.mailOptions.html=''+lang.EventText3+'' + } + Object.keys(d.details).forEach(function(v,n){ + d.mailOptions.html+='
'+v+' : '+d.details[v]+'
' + }) + nodemailer.sendMail(d.mailOptions, (error, info) => { + if (error) { + s.systemLog(lang.MailError,error) + return ; + } + }); + }) + }); + } + if(d.mon.details.detector_command_enable==='1'&&!s.group[d.ke].mon[d.id].detector_command){ + var detector_command_timeout + if(!d.mon.details.detector_command_timeout||d.mon.details.detector_command_timeout===''){ + detector_command_timeout = 1000*60*10; + }else{ + detector_command_timeout = parseFloat(d.mon.details.detector_command_timeout)*1000*60; + } + s.group[d.ke].mon[d.id].detector_command=setTimeout(function(){ + clearTimeout(s.group[d.ke].mon[d.id].detector_command); + delete(s.group[d.ke].mon[d.id].detector_command); + + },detector_command_timeout); + var detector_command = d.mon.details.detector_command + .replace(/{{TIME}}/g,s.timeObject(new Date).format()) + .replace(/{{MONITOR_ID}}/g,d.id) + .replace(/{{GROUP_KEY}}/g,d.ke) + .replace(/{{DETAILS}}/g,detailString) + if(d.details.confidence){ + detector_command = detector_command + .replace(/{{CONFIDENCE}}/g,d.details.confidence) + } + exec(detector_command,{detached: true}) + } + } + //show client machines the event + d.cx={f:'detector_trigger',id:d.id,ke:d.ke,details:d.details,doObjectDetection:d.doObjectDetection}; + s.tx(d.cx,'DETECTOR_'+d.ke+d.id); + break; + } + if(typeof cn==='function'){setTimeout(function(){cn()},1000);} +} + +//function for receiving detector data +s.pluginEventController=function(d){ + switch(d.f){ + case'trigger': + s.camera('motion',d) + break; + case's.tx': + s.tx(d.data,d.to) + break; + case'sql': + sql.query(d.query,d.values); + break; + case'log': + s.systemLog('PLUGIN : '+d.plug+' : ',d) + break; + } +} +//multi plugin connections +s.connectedPlugins={} +s.pluginInitiatorSuccess=function(mode,d,cn){ + s.systemLog('pluginInitiatorSuccess',d) + if(mode==='client'){ + //is in client mode (camera.js is client) + cn.pluginEngine=d.plug + if(!s.connectedPlugins[d.plug]){ + s.connectedPlugins[d.plug]={plug:d.plug} + } + s.systemLog('Connected to plugin : Detector - '+d.plug+' - '+d.type) + switch(d.type){ + default:case'detector': + s.ocv={started:s.timeObject(),id:cn.id,plug:d.plug,notice:d.notice,isClientPlugin:true}; + cn.ocv=1; + s.tx({f:'detector_plugged',plug:d.plug,notice:d.notice},'CPU') + break; + } + }else{ + //is in host mode (camera.js is client) + switch(d.type){ + default:case'detector': + s.ocv={started:s.timeObject(),id:"host",plug:d.plug,notice:d.notice,isHostPlugin:true}; + break; + } + } + s.connectedPlugins[d.plug].plugged=true + s.tx({f:'readPlugins',ke:d.ke},'CPU') + s.ocvTx({f:'api_key',key:d.plug}) + s.api[d.plug]={pluginEngine:d.plug,permissions:{},details:{},ip:'0.0.0.0'}; +} +s.pluginInitiatorFail=function(mode,d,cn){ + s.connectedPlugins[d.plug].plugged=false + if(mode==='client'){ + //is in client mode (camera.js is client) + cn.disconnect() + }else{ + //is in host mode (camera.js is client) + } +} +if(config.plugins&&config.plugins.length>0){ + config.plugins.forEach(function(v){ + s.connectedPlugins[v.id]={plug:v.id} + if(v.enabled===false){return} + if(v.mode==='host'){ + //is in host mode (camera.js is client) + if(v.https===true){ + v.https='https://' + }else{ + v.https='http://' + } + if(!v.port){ + v.port=80 + } + var socket = socketIOclient(v.https+v.host+':'+v.port) + s.connectedPlugins[v.id].tx = function(x){return socket.emit('f',x)} + socket.on('connect', function(cn){ + s.systemLog('Connected to plugin (host) : '+v.id) + s.connectedPlugins[v.id].tx({f:'init_plugin_as_host',key:v.key}) + }); + socket.on('init',function(d){ + s.systemLog('Initialize Plugin : Host',d) + if(d.ok===true){ + s.pluginInitiatorSuccess("host",d) + }else{ + s.pluginInitiatorFail("host",d) + } + }); + socket.on('ocv',s.pluginEventController); + socket.on('disconnect', function(){ + s.connectedPlugins[v.id].plugged=false + delete(s.api[v.id]) + s.systemLog('Plugin Disconnected : '+v.id) + s.connectedPlugins[v.id].reconnector = setInterval(function(){ + if(socket.connected===true){ + clearInterval(s.connectedPlugins[v.id].reconnector) + }else{ + socket.connect() + } + },1000*2) + }); + s.connectedPlugins[v.id].ws = socket; + } + }) +} +////socket controller +s.cn=function(cn){return{id:cn.id,ke:cn.ke,uid:cn.uid}} +io.on('connection', function (cn) { +var tx; + //set "client" detector plugin event function + cn.on('ocv',function(d){ + if(!cn.pluginEngine&&d.f==='init'){ + if(config.pluginKeys[d.plug]===d.pluginKey){ + s.pluginInitiatorSuccess("client",d,cn) + }else{ + s.pluginInitiatorFail("client",d,cn) + } + }else{ + if(config.pluginKeys[d.plug]===d.pluginKey){ + s.pluginEventController(d) + }else{ + cn.disconnect() + } + } + }) + //unique Base64 socket stream + cn.on('Base64',function(d){ + if(!s.group[d.ke]||!s.group[d.ke].mon||!s.group[d.ke].mon[d.id]){ + cn.disconnect();return; + } + cn.ip=cn.request.connection.remoteAddress; + var toUTC = function(){ + return new Date().toISOString(); + } + var tx=function(z){cn.emit('data',z);} + d.failed=function(msg){ + tx({f:'stop_reconnect',msg:msg,token_used:d.auth,ke:d.ke}); + cn.disconnect(); + } + d.success=function(r){ + r=r[0]; + var Emitter,chunkChannel + if(!d.channel){ + Emitter = s.group[d.ke].mon[d.id].emitter + chunkChannel = 'MAIN' + }else{ + Emitter = s.group[d.ke].mon[d.id].emitterChannel[parseInt(d.channel)+config.pipeAddition] + chunkChannel = parseInt(d.channel)+config.pipeAddition + } + if(!Emitter){ + cn.disconnect();return; + } + if(!d.channel)d.channel = 'MAIN'; + cn.ke=d.ke, + cn.uid=d.uid, + cn.auth=d.auth; + cn.channel=d.channel; + cn.removeListenerOnDisconnect=true; + cn.socketVideoStream=d.id; + var contentWriter + cn.closeSocketVideoStream = function(){ + Emitter.removeListener('data', contentWriter); + } + Emitter.on('data',contentWriter = function(base64){ + tx(base64) + }) + } + //check if auth key is user's temporary session key + if(s.group[d.ke]&&s.group[d.ke].users&&s.group[d.ke].users[d.auth]){ + d.success(s.group[d.ke].users[d.auth]); + }else{ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND auth=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + s.sqlQuery('SELECT * FROM API WHERE ke=? AND code=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details) + if(r.details.auth_socket==='1'){ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND uid=?',[r.ke,r.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + d.failed('User not found') + } + }) + }else{ + d.failed('Permissions for this key do not allow authentication with Websocket') + } + }else{ + d.failed('Not an API key') + } + }) + } + }) + } + }) + //unique FLV socket stream + cn.on('FLV',function(d){ + if(!s.group[d.ke]||!s.group[d.ke].mon||!s.group[d.ke].mon[d.id]){ + cn.disconnect();return; + } + cn.ip=cn.request.connection.remoteAddress; + var toUTC = function(){ + return new Date().toISOString(); + } + var tx=function(z){cn.emit('data',z);} + d.failed=function(msg){ + tx({f:'stop_reconnect',msg:msg,token_used:d.auth,ke:d.ke}); + cn.disconnect(); + } + d.success=function(r){ + r=r[0]; + var Emitter,chunkChannel + if(!d.channel){ + Emitter = s.group[d.ke].mon[d.id].emitter + chunkChannel = 'MAIN' + }else{ + Emitter = s.group[d.ke].mon[d.id].emitterChannel[parseInt(d.channel)+config.pipeAddition] + chunkChannel = parseInt(d.channel)+config.pipeAddition + } + if(!Emitter){ + cn.disconnect();return; + } + if(!d.channel)d.channel = 'MAIN'; + cn.ke=d.ke, + cn.uid=d.uid, + cn.auth=d.auth; + cn.channel=d.channel; + cn.removeListenerOnDisconnect=true; + cn.socketVideoStream=d.id; + var contentWriter + cn.closeSocketVideoStream = function(){ + Emitter.removeListener('data', contentWriter); + } + tx({time:toUTC(),buffer:s.group[d.ke].mon[d.id].firstStreamChunk[chunkChannel]}) + Emitter.on('data',contentWriter = function(buffer){ + tx({time:toUTC(),buffer:buffer}) + }) + } + if(s.group[d.ke]&&s.group[d.ke].users&&s.group[d.ke].users[d.auth]){ + d.success(s.group[d.ke].users[d.auth]); + }else{ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND auth=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + s.sqlQuery('SELECT * FROM API WHERE ke=? AND code=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details) + if(r.details.auth_socket==='1'){ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND uid=?',[r.ke,r.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + d.failed('User not found') + } + }) + }else{ + d.failed('Permissions for this key do not allow authentication with Websocket') + } + }else{ + d.failed('Not an API key') + } + }) + } + }) + } + }) + //unique MP4 socket stream + cn.on('MP4',function(d){ + if(!s.group[d.ke]||!s.group[d.ke].mon||!s.group[d.ke].mon[d.id]){ + cn.disconnect();return; + } + cn.ip=cn.request.connection.remoteAddress; + var toUTC = function(){ + return new Date().toISOString(); + } + var tx=function(z){cn.emit('data',z);} + d.failed=function(msg){ + tx({f:'stop_reconnect',msg:msg,token_used:d.auth,ke:d.ke}); + cn.disconnect(); + } + d.success=function(r){ + r=r[0]; + var Emitter,chunkChannel + if(!d.channel){ + Emitter = s.group[d.ke].mon[d.id].emitter + chunkChannel = 'MAIN' + }else{ + Emitter = s.group[d.ke].mon[d.id].emitterChannel[parseInt(d.channel)+config.pipeAddition] + chunkChannel = parseInt(d.channel)+config.pipeAddition + } + if(!Emitter){ + cn.disconnect();return; + } + if(!d.channel)d.channel = 'MAIN'; + cn.ke=d.ke, + cn.uid=d.uid, + cn.auth=d.auth; + cn.channel=d.channel; + cn.socketVideoStream=d.id; + var mp4frag = s.group[d.ke].mon[d.id].mp4frag[d.channel]; + var onInitialized = () => { + cn.emit('mime', mp4frag.mime); + mp4frag.removeListener('initialized', onInitialized); + }; + //event listener + var onSegment = function(data){ + cn.emit('segment', data); + }; + cn.closeSocketVideoStream = function(){ + mp4frag.removeListener('segment', onSegment) + mp4frag.removeListener('initialized', onInitialized) + } + cn.on('MP4Command',function(msg){ + switch (msg) { + case 'mime' ://client is requesting mime + var mime = mp4frag.mime; + if (mime) { + cn.emit('mime', mime); + } else { + mp4frag.on('initialized', onInitialized); + } + break; + case 'initialization' ://client is requesting initialization segment + cn.emit('initialization', mp4frag.initialization); + break; + case 'segment' ://client is requesting a SINGLE segment + var segment = mp4frag.segment; + if (segment) { + cn.emit('segment', segment); + } else { + mp4frag.once('segment', onSegment); + } + break; + case 'segments' ://client is requesting ALL segments + //send current segment first to start video asap + var segment = mp4frag.segment; + if (segment) { + cn.emit('segment', segment); + } + //add listener for segments being dispatched by mp4frag + mp4frag.on('segment', onSegment); + break; + case 'pause' : + mp4frag.removeListener('segment', onSegment); + break; + case 'resume' : + mp4frag.on('segment', onSegment); + break; + case 'stop' ://client requesting to stop receiving segments + cn.closeSocketVideoStream() + break; + } + }) + } + if(s.group[d.ke]&&s.group[d.ke].users&&s.group[d.ke].users[d.auth]){ + d.success(s.group[d.ke].users[d.auth]); + }else{ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND auth=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + s.sqlQuery('SELECT * FROM API WHERE ke=? AND code=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details) + if(r.details.auth_socket==='1'){ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND uid=?',[r.ke,r.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + d.failed('User not found') + } + }) + }else{ + d.failed('Permissions for this key do not allow authentication with Websocket') + } + }else{ + d.failed('Not an API key') + } + }) + } + }) + } + }) + //main socket control functions + cn.on('f',function(d){ + if(!cn.ke&&d.f==='init'){//socket login + cn.ip=cn.request.connection.remoteAddress; + tx=function(z){if(!z.ke){z.ke=cn.ke;};cn.emit('f',z);} + d.failed=function(){tx({ok:false,msg:'Not Authorized',token_used:d.auth,ke:d.ke});cn.disconnect();} + d.success=function(r){ + r=r[0];cn.join('GRP_'+d.ke);cn.join('CPU'); + cn.ke=d.ke, + cn.uid=d.uid, + cn.auth=d.auth; + if(!s.group[d.ke])s.group[d.ke]={}; +// if(!s.group[d.ke].vid)s.group[d.ke].vid={}; + if(!s.group[d.ke].users)s.group[d.ke].users={}; +// s.group[d.ke].vid[cn.id]={uid:d.uid}; + s.group[d.ke].users[d.auth]={cnid:cn.id,uid:r.uid,mail:r.mail,details:JSON.parse(r.details),logged_in_at:s.timeObject(new Date).format(),login_type:'Dashboard'} + try{s.group[d.ke].users[d.auth].details=JSON.parse(r.details)}catch(er){} + if(s.group[d.ke].users[d.auth].details.get_server_log!=='0'){ + cn.join('GRPLOG_'+d.ke) + } + s.group[d.ke].users[d.auth].lang=s.getLanguageFile(s.group[d.ke].users[d.auth].details.lang) + s.log({ke:d.ke,mid:'$USER'},{type:s.group[d.ke].users[d.auth].lang['Websocket Connected'],msg:{mail:r.mail,id:d.uid,ip:cn.ip}}) + if(!s.group[d.ke].mon){ + s.group[d.ke].mon={} + if(!s.group[d.ke].mon){s.group[d.ke].mon={}} + } + if(s.ocv){ + tx({f:'detector_plugged',plug:s.ocv.plug,notice:s.ocv.notice}) + s.ocvTx({f:'readPlugins',ke:d.ke}) + } + tx({f:'users_online',users:s.group[d.ke].users}) + s.tx({f:'user_status_change',ke:d.ke,uid:cn.uid,status:1,user:s.group[d.ke].users[d.auth]},'GRP_'+d.ke) + s.init('diskUsedEmit',d) + s.init('apps',d) + s.sqlQuery('SELECT * FROM API WHERE ke=? AND uid=?',[d.ke,d.uid],function(err,rrr) { + tx({ + f:'init_success', + users:s.group[d.ke].vid, + apis:rrr, + os:{ + platform:s.platform, + cpuCount:os.cpus().length, + totalmem:s.totalmem + } + }) + try{ + s.sqlQuery('SELECT * FROM Monitors WHERE ke=?', [d.ke], function(err,r) { + if(r && r[0]){ + r.forEach(function(monitor){ + s.camera('snapshot',{mid:monitor.mid,ke:monitor.ke,mon:monitor}) + }) + } + }) + }catch(err){ + console.log(err) + } + }) + } + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND auth=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + s.sqlQuery('SELECT * FROM API WHERE ke=? AND code=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details) + if(r.details.auth_socket==='1'){ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND uid=?',[r.ke,r.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + d.failed() + } + }) + }else{ + d.failed() + } + }else{ + d.failed() + } + }) + } + }) + return; + } + if((d.id||d.uid||d.mid)&&cn.ke){ + try{ + switch(d.f){ + case'ocv_in': + s.ocvTx(d.data) + break; + case'monitorOrder': + if(d.monitorOrder&&d.monitorOrder instanceof Object){ + s.sqlQuery('SELECT details FROM Users WHERE uid=? AND ke=?',[cn.uid,cn.ke],function(err,r){ + if(r&&r[0]){ + r=JSON.parse(r[0].details); + r.monitorOrder=d.monitorOrder; + s.sqlQuery('UPDATE Users SET details=? WHERE uid=? AND ke=?',[JSON.stringify(r),cn.uid,cn.ke]) + } + }) + } + break; + case'update': + if(!config.updateKey){ + tx({error:lang.updateKeyText1}); + return; + } + if(d.key===config.updateKey){ + exec('chmod +x '+__dirname+'/UPDATE.sh&&'+__dirname+'/UPDATE.sh',{detached: true}) + }else{ + tx({error:lang.updateKeyText2}); + } + break; + case'cron': + if(s.group[cn.ke]&&s.group[cn.ke].users[cn.auth].details&&!s.group[cn.ke].users[cn.auth].details.sub){ + s.tx({f:d.ff},s.cron.id) + } + break; + case'api': + switch(d.ff){ + case'delete': + d.set=[],d.ar=[]; + d.form.ke=cn.ke;d.form.uid=cn.uid;delete(d.form.ip); + if(!d.form.code){tx({f:'form_incomplete',form:'APIs'});return} + d.for=Object.keys(d.form); + d.for.forEach(function(v){ + d.set.push(v+'=?'),d.ar.push(d.form[v]); + }); + s.sqlQuery('DELETE FROM API WHERE '+d.set.join(' AND '),d.ar,function(err,r){ + if(!err){ + tx({f:'api_key_deleted',form:d.form}); + delete(s.api[d.form.code]); + }else{ + s.systemLog('API Delete Error : '+e.ke+' : '+' : '+e.mid,err) + } + }) + break; + case'add': + d.set=[],d.qu=[],d.ar=[]; + d.form.ke=cn.ke,d.form.uid=cn.uid,d.form.code=s.gid(30); + d.for=Object.keys(d.form); + d.for.forEach(function(v){ + d.set.push(v),d.qu.push('?'),d.ar.push(d.form[v]); + }); + s.sqlQuery('INSERT INTO API ('+d.set.join(',')+') VALUES ('+d.qu.join(',')+')',d.ar,function(err,r){ + d.form.time=s.formattedTime(new Date,'YYYY-DD-MM HH:mm:ss'); + if(!err){tx({f:'api_key_added',form:d.form});}else{s.systemLog(err)} + }); + break; + } + break; + case'settings': + switch(d.ff){ + case'filters': + switch(d.fff){ + case'save':case'delete': + s.sqlQuery('SELECT details FROM Users WHERE ke=? AND uid=?',[d.ke,d.uid],function(err,r){ + if(r&&r[0]){ + r=r[0]; + d.d=JSON.parse(r.details); + if(d.form.id===''){d.form.id=s.gid(5)} + if(!d.d.filters)d.d.filters={}; + //save/modify or delete + if(d.fff==='save'){ + d.d.filters[d.form.id]=d.form; + }else{ + delete(d.d.filters[d.form.id]); + } + s.sqlQuery('UPDATE Users SET details=? WHERE ke=? AND uid=?',[JSON.stringify(d.d),d.ke,d.uid],function(err,r){ + tx({f:'filters_change',uid:d.uid,ke:d.ke,filters:d.d.filters}); + }); + } + }) + break; + } + break; + case'edit': + s.sqlQuery('SELECT details FROM Users WHERE ke=? AND uid=?',[d.ke,d.uid],function(err,r){ + if(r&&r[0]){ + r=r[0]; + d.d=JSON.parse(r.details); + if(d.d.get_server_log==='1'){ + cn.join('GRPLOG_'+d.ke) + }else{ + cn.leave('GRPLOG_'+d.ke) + } + ///unchangeable from client side, so reset them in case they did. + d.form.details=JSON.parse(d.form.details) + //admin permissions + d.form.details.permissions=d.d.permissions + d.form.details.edit_size=d.d.edit_size + d.form.details.edit_days=d.d.edit_days + d.form.details.use_admin=d.d.use_admin + d.form.details.use_webdav=d.d.use_webdav + d.form.details.use_ldap=d.d.use_ldap + //check + if(d.d.edit_days=="0"){ + d.form.details.days=d.d.days; + } + if(d.d.edit_size=="0"){ + d.form.details.size=d.d.size; + } + if(d.d.sub){ + d.form.details.sub=d.d.sub; + if(d.d.monitors){d.form.details.monitors=d.d.monitors;} + if(d.d.allmonitors){d.form.details.allmonitors=d.d.allmonitors;} + if(d.d.video_delete){d.form.details.video_delete=d.d.video_delete;} + if(d.d.video_view){d.form.details.video_view=d.d.video_view;} + if(d.d.monitor_edit){d.form.details.monitor_edit=d.d.monitor_edit;} + if(d.d.size){d.form.details.size=d.d.size;} + if(d.d.days){d.form.details.days=d.d.days;} + delete(d.form.details.mon_groups) + } + var newSize = d.form.details.size + d.form.details=JSON.stringify(d.form.details) + /// + d.set=[],d.ar=[]; + if(d.form.pass&&d.form.pass!==''){d.form.pass=s.md5(d.form.pass);}else{delete(d.form.pass)}; + delete(d.form.password_again); + d.for=Object.keys(d.form); + d.for.forEach(function(v){ + d.set.push(v+'=?'),d.ar.push(d.form[v]); + }); + d.ar.push(d.ke),d.ar.push(d.uid); + s.sqlQuery('UPDATE Users SET '+d.set.join(',')+' WHERE ke=? AND uid=?',d.ar,function(err,r){ + if(!d.d.sub){ + s.group[d.ke].sizeLimit = parseFloat(newSize) + delete(s.group[d.ke].webdav) + s.init('apps',d) + } + tx({f:'user_settings_change',uid:d.uid,ke:d.ke,form:d.form}); + }); + } + }) + break; + } + break; + case'monitor': + switch(d.ff){ + case'get': + switch(d.fff){ + case'videos&events': + if(!d.eventLimit){ + d.eventLimit=500 + }else{ + d.eventLimit = parseInt(d.eventLimit); + } + if(!d.eventStartDate&&d.startDate){ + d.eventStartDate=d.startDate + } + if(!d.eventEndDate&&d.endDate){ + d.eventEndDate=d.endDate + } + var monitorQuery = '' + var monitorValues = [] + var permissions = s.group[d.ke].users[cn.auth].details; + if(!d.mid){ + if(permissions.sub&&permissions.monitors&&permissions.allmonitors!=='1'){ + try{permissions.monitors=JSON.parse(permissions.monitors);}catch(er){} + var or = []; + permissions.monitors.forEach(function(v,n){ + or.push('mid=?'); + monitorValues.push(v) + }) + monitorQuery += ' AND ('+or.join(' OR ')+')' + } + }else if(!permissions.sub||permissions.allmonitors!=='0'||permissions.monitors.indexOf(d.mid)>-1){ + monitorQuery += ' and mid=?'; + monitorValues.push(d.mid) + } + var getEvents = function(callback){ + var eventQuery = 'SELECT * FROM Events WHERE ke=?'; + var eventQueryValues = [cn.ke]; + if(d.eventStartDate&&d.eventStartDate!==''){ + d.eventStartDate=d.eventStartDate.replace('T',' ') + if(d.eventEndDate&&d.eventEndDate!==''){ + d.eventEndDate=d.eventEndDate.replace('T',' ') + eventQuery+=' AND `time` >= ? AND `time` <= ?'; + eventQueryValues.push(decodeURIComponent(d.eventStartDate)) + eventQueryValues.push(decodeURIComponent(d.eventEndDate)) + }else{ + eventQuery+=' AND `time` >= ?'; + eventQueryValues.push(decodeURIComponent(d.eventStartDate)) + } + } + if(monitorValues.length>0){ + eventQuery += monitorQuery; + eventQueryValues = eventQueryValues.concat(monitorValues); + } + eventQuery+=' ORDER BY `time` DESC LIMIT '+d.eventLimit+''; + s.sqlQuery(eventQuery,eventQueryValues,function(err,r){ + if(err){ + console.log(eventQuery) + console.error('LINE 2428',err) + setTimeout(function(){ + getEvents(callback) + },2000) + }else{ + if(!r){r=[]} + r.forEach(function(v,n){ + r[n].details=JSON.parse(v.details); + }) + callback(r) + } + }) + } + if(!d.videoLimit&&d.limit){ + d.videoLimit=d.limit + eventQuery.push() + } + if(!d.videoStartDate&&d.startDate){ + d.videoStartDate=d.startDate + } + if(!d.videoEndDate&&d.endDate){ + d.videoEndDate=d.endDate + } + var getVideos = function(callback){ + var videoQuery='SELECT * FROM Videos WHERE ke=?'; + var videoQueryValues=[cn.ke]; + if(d.videoStartDate||d.videoEndDate){ + if(!d.videoStartDateOperator||d.videoStartDateOperator==''){ + d.videoStartDateOperator='>=' + } + if(!d.videoEndDateOperator||d.videoEndDateOperator==''){ + d.videoEndDateOperator='<=' + } + switch(true){ + case(d.videoStartDate&&d.videoStartDate!==''&&d.videoEndDate&&d.videoEndDate!==''): + d.videoStartDate=d.videoStartDate.replace('T',' ') + d.videoEndDate=d.videoEndDate.replace('T',' ') + videoQuery+=' AND `time` '+d.videoStartDateOperator+' ? AND `end` '+d.videoEndDateOperator+' ?'; + videoQueryValues.push(d.videoStartDate) + videoQueryValues.push(d.videoEndDate) + break; + case(d.videoStartDate&&d.videoStartDate!==''): + d.videoStartDate=d.videoStartDate.replace('T',' ') + videoQuery+=' AND `time` '+d.videoStartDateOperator+' ?'; + videoQueryValues.push(d.videoStartDate) + break; + case(d.videoEndDate&&d.videoEndDate!==''): + d.videoEndDate=d.videoEndDate.replace('T',' ') + videoQuery+=' AND `end` '+d.videoEndDateOperator+' ?'; + videoQueryValues.push(d.videoEndDate) + break; + } + } + if(monitorValues.length>0){ + videoQuery += monitorQuery; + videoQueryValues = videoQueryValues.concat(monitorValues); + } + videoQuery+=' ORDER BY `time` DESC'; + if(!d.videoLimit||d.videoLimit==''){ + d.videoLimit='100' + } + if(d.videoLimit!=='0'){ + videoQuery+=' LIMIT '+d.videoLimit + } + s.sqlQuery(videoQuery,videoQueryValues,function(err,r){ + if(err){ + console.log(videoQuery) + console.error('LINE 2416',err) + setTimeout(function(){ + getVideos(callback) + },2000) + }else{ + s.video('linkBuild',r,cn.auth) + callback({total:r.length,limit:d.videoLimit,videos:r}) + } + }) + } + getVideos(function(videos){ + getEvents(function(events){ + tx({ + f:'drawPowerVideoMainTimeLine', + videos:videos, + events:events + }) + }) + }) + break; + } + break; + case'control': + s.camera('control',d,function(resp){ + tx({f:'control',response:resp}) + }) + break; + case'jpeg_off': + delete(cn.jpeg_on); + if(cn.monitor_watching){ + Object.keys(cn.monitor_watching).forEach(function(n,v){ + v=cn.monitor_watching[n]; + cn.join('MON_STREAM_'+n); + }); + } + tx({f:'mode_jpeg_off'}) + break; + case'jpeg_on': + cn.jpeg_on=true; + if(cn.monitor_watching){ + Object.keys(cn.monitor_watching).forEach(function(n,v){ + v=cn.monitor_watching[n]; + cn.leave('MON_STREAM_'+n); + }); + } + tx({f:'mode_jpeg_on'}) + break; + case'watch_on': + if(!d.ke){d.ke=cn.ke} + s.init(0,{mid:d.id,ke:d.ke}); + if(!s.group[d.ke]||!s.group[d.ke].mon[d.id]||s.group[d.ke].mon[d.id].started===0){return false} + s.camera(d.ff,d,cn,tx) + cn.join('MON_'+d.id); + cn.join('DETECTOR_'+d.ke+d.id); + if(cn.jpeg_on!==true){ + cn.join('MON_STREAM_'+d.id); + } if(s.group[d.ke]&&s.group[d.ke].mon&&s.group[d.ke].mon[d.id]&&s.group[d.ke].mon[d.id].watch){ + + tx({f:'monitor_watch_on',id:d.id,ke:d.ke}) + s.tx({viewers:Object.keys(s.group[d.ke].mon[d.id].watch).length,ke:d.ke,id:d.id},'MON_'+d.id) + } + break; + case'watch_off': + if(!d.ke){d.ke=cn.ke;};cn.leave('MON_'+d.id);s.camera(d.ff,d,cn,tx); + s.tx({viewers:d.ob,ke:d.ke,id:d.id},'MON_'+d.id) + break; + case'start':case'stop': + s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND mid=?',[cn.ke,d.id],function(err,r) { + if(r&&r[0]){r=r[0] + s.camera(d.ff,{type:r.type,url:s.init('url',r),id:d.id,mode:d.ff,ke:cn.ke}); + } + }) + break; + } + break; +// case'video': +// switch(d.ff){ +// case'fix': +// s.video('fix',d) +// break; +// } +// break; + case'ffprobe': + if(s.group[cn.ke].users[cn.auth]){ + switch(d.ff){ + case'stop': + exec('kill -9 '+s.group[cn.ke].users[cn.auth].ffprobe.pid,{detatched: true}) + break; + default: + if(s.group[cn.ke].users[cn.auth].ffprobe){ + return + } + s.group[cn.ke].users[cn.auth].ffprobe=1; + tx({f:'ffprobe_start'}) + exec('ffprobe '+('-v quiet -print_format json -show_format -show_streams '+d.query),function(err,data){ + tx({f:'ffprobe_data',data:data.toString('utf8')}) + delete(s.group[cn.ke].users[cn.auth].ffprobe) + tx({f:'ffprobe_stop'}) + }) + //auto kill in 30 seconds + setTimeout(function(){ + exec('kill -9 '+d.pid,{detached: true}) + },30000) + break; + } + } + break; + case'onvif': + d.ip=d.ip.replace(/ /g,''); + d.port=d.port.replace(/ /g,''); + if(d.ip===''){ + var interfaces = os.networkInterfaces(); + var addresses = []; + for (var k in interfaces) { + for (var k2 in interfaces[k]) { + var address = interfaces[k][k2]; + if (address.family === 'IPv4' && !address.internal) { + addresses.push(address.address); + } + } + } + d.arr=[] + addresses.forEach(function(v){ + if(v.indexOf('0.0.0')>-1){return false} + v=v.split('.'); + delete(v[3]); + v=v.join('.'); + d.arr.push(v+'1-'+v+'254') + }) + d.ip=d.arr.join(',') + } + if(d.port===''){ + d.port='80,8080,8000,7575,8081,554' + } + d.ip.split(',').forEach(function(v){ + if(v.indexOf('-')>-1){ + v=v.split('-'); + d.IP_RANGE_START = v[0], + d.IP_RANGE_END = v[1]; + }else{ + d.IP_RANGE_START = v; + d.IP_RANGE_END = v; + } + if(!d.IP_LIST){ + d.IP_LIST = s.ipRange(d.IP_RANGE_START,d.IP_RANGE_END); + }else{ + d.IP_LIST=d.IP_LIST.concat(s.ipRange(d.IP_RANGE_START,d.IP_RANGE_END)) + } + //check port + if(d.port.indexOf('-')>-1){ + d.port=d.port.split('-'); + d.PORT_RANGE_START = d.port[0]; + d.PORT_RANGE_END = d.port[1]; + d.PORT_LIST = s.portRange(d.PORT_RANGE_START,d.PORT_RANGE_END); + }else{ + d.PORT_LIST=d.port.split(',') + } + //check user name and pass + d.USERNAME=''; + if(d.user){ + d.USERNAME = d.user + } + d.PASSWORD=''; + if(d.pass){ + d.PASSWORD = d.pass + } + }) + d.cams=[] + d.IP_LIST.forEach(function(ip_entry,n) { + d.PORT_LIST.forEach(function(port_entry,nn) { + var device = new onvif.OnvifDevice({ + xaddr : 'http://' + ip_entry + ':' + port_entry + '/onvif/device_service', + user : d.USERNAME, + pass : d.PASSWORD + }) + device.init().then((info) => { + var data = { + f : 'onvif', + ip : ip_entry, + port : port_entry, + info : info + } + device.services.device.getSystemDateAndTime().then((date) => { + data.date = date + device.services.media.getStreamUri({ + ProfileToken : device.current_profile.token, + Protocol : 'RTSP' + }).then((stream) => { + data.uri = stream.data.GetStreamUriResponse.MediaUri.Uri + tx(data) + }).catch((error) => { +// console.log(error) + }); + }).catch((error) => { +// console.log(error) + }); + }).catch(function(error){ +// console.log(error) + }) + }); + }); +// tx({f:'onvif_end'}) + break; + } + }catch(er){ + s.systemLog('ERROR CATCH 1',er) + } + }else{ + tx({ok:false,msg:lang.NotAuthorizedText1}); + } + }); + // admin page socket functions + cn.on('super',function(d){ + if(!cn.init&&d.f=='init'){ + d.ok=s.superAuth({mail:d.mail,pass:d.pass},function(data){ + cn.uid=d.mail + cn.join('$'); + cn.ip=cn.request.connection.remoteAddress + s.log({ke:'$',mid:'$USER'},{type:lang['Websocket Connected'],msg:{for:lang['Superuser'],id:cn.uid,ip:cn.ip}}) + cn.init='super'; + cn.mail=d.mail; + s.tx({f:'init_success',mail:d.mail},cn.id); + }) + if(d.ok===false){ + cn.disconnect(); + } + }else{ + if(cn.mail&&cn.init=='super'){ + switch(d.f){ + case'logs': + switch(d.ff){ + case'delete': + s.sqlQuery('DELETE FROM Logs WHERE ke=?',[d.ke]) + break; + } + break; + case'system': + switch(d.ff){ + case'update': + s.ffmpegKill() + s.systemLog('Shinobi ordered to update',{by:cn.mail,ip:cn.ip,distro:d.distro}) + var updateProcess = spawn('sh',(__dirname+'/UPDATE.sh '+d.distro).split(' '),{detached: true}) + updateProcess.stderr.on('data',function(data){ + s.systemLog('Update Info',data.toString()) + }) + updateProcess.stdout.on('data',function(data){ + s.systemLog('Update Info',data.toString()) + }) + break; + case'restart': + d.check=function(x){return d.target.indexOf(x)>-1} + if(d.check('system')){ + s.systemLog('Shinobi ordered to restart',{by:cn.mail,ip:cn.ip}) + s.ffmpegKill() + exec('pm2 restart '+__dirname+'/camera.js') + } + if(d.check('cron')){ + s.systemLog('Shinobi CRON ordered to restart',{by:cn.mail,ip:cn.ip}) + exec('pm2 restart '+__dirname+'/cron.js') + } + if(d.check('logs')){ + s.systemLog('Flush PM2 Logs',{by:cn.mail,ip:cn.ip}) + exec('pm2 flush') + } + break; + case'configure': + s.systemLog('conf.json Modified',{by:cn.mail,ip:cn.ip,old:jsonfile.readFileSync(location.config)}) + jsonfile.writeFile(location.config,d.data,{spaces: 2},function(){ + s.tx({f:'save_configuration'},cn.id) + }) + break; + } + break; + case'accounts': + switch(d.ff){ + case'register': + if(d.form.mail!==''&&d.form.pass!==''){ + if(d.form.pass===d.form.password_again){ + s.sqlQuery('SELECT * FROM Users WHERE mail=?',[d.form.mail],function(err,r) { + if(r&&r[0]){ + //found address already exists + d.msg='Email address is in use.'; + s.tx({f:'error',ff:'account_register',msg:d.msg},cn.id) + }else{ + //create new + //user id + d.form.uid=s.gid(); + //check to see if custom key set + if(!d.form.ke||d.form.ke===''){ + d.form.ke=s.gid() + } + //write user to db + s.sqlQuery('INSERT INTO Users (ke,uid,mail,pass,details) VALUES (?,?,?,?,?)',[d.form.ke,d.form.uid,d.form.mail,s.md5(d.form.pass),d.form.details]) + s.tx({f:'add_account',details:d.form.details,ke:d.form.ke,uid:d.form.uid,mail:d.form.mail},'$'); + //init user + s.init('group',d.form) + } + }) + }else{ + d.msg=lang["Passwords Don't Match"]; + } + }else{ + d.msg=lang['Fields cannot be empty']; + } + if(d.msg){ + s.tx({f:'error',ff:'account_register',msg:d.msg},cn.id) + } + break; + case'edit': + if(d.form.pass&&d.form.pass!==''){ + if(d.form.pass===d.form.password_again){ + d.form.pass=s.md5(d.form.pass); + }else{ + s.tx({f:'error',ff:'account_edit',msg:lang["Passwords Don't Match"]},cn.id) + return + } + }else{ + delete(d.form.pass); + } + delete(d.form.password_again); + d.keys=Object.keys(d.form); + d.set=[]; + d.values=[]; + d.keys.forEach(function(v,n){ + if(d.set==='ke'||d.set==='password_again'||!d.form[v]){return} + d.set.push(v+'=?') + d.values.push(d.form[v]) + }) + d.values.push(d.account.mail) + s.sqlQuery('UPDATE Users SET '+d.set.join(',')+' WHERE mail=?',d.values,function(err,r) { + if(err){ + s.tx({f:'error',ff:'account_edit',msg:lang.AccountEditText1},cn.id) + return + } + s.tx({f:'edit_account',form:d.form,ke:d.account.ke,uid:d.account.uid},'$'); + delete(s.group[d.account.ke].init); + s.init('apps',d.account) + }) + break; + case'delete': + s.sqlQuery('DELETE FROM Users WHERE uid=? AND ke=? AND mail=?',[d.account.uid,d.account.ke,d.account.mail]) + s.sqlQuery('DELETE FROM API WHERE uid=? AND ke=?',[d.account.uid,d.account.ke]) + s.tx({f:'delete_account',ke:d.account.ke,uid:d.account.uid,mail:d.account.mail},'$'); + break; + } + break; + } + } + } + }) + // admin page socket functions + cn.on('a',function(d){ + if(!cn.init&&d.f=='init'){ + s.sqlQuery('SELECT * FROM Users WHERE auth=? AND uid=?',[d.auth,d.uid],function(err,r){ + if(r&&r[0]){ + r=r[0]; + if(!s.group[d.ke]){s.group[d.ke]={users:{}}} + if(!s.group[d.ke].users[d.auth]){s.group[d.ke].users[d.auth]={cnid:cn.id}} + try{s.group[d.ke].users[d.auth].details=JSON.parse(r.details)}catch(er){} + cn.join('ADM_'+d.ke); + cn.ke=d.ke; + cn.uid=d.uid; + cn.auth=d.auth; + cn.init='admin'; + }else{ + cn.disconnect(); + } + }) + }else{ + s.auth({auth:d.auth,ke:d.ke,id:d.id,ip:cn.request.connection.remoteAddress},function(user){ + if(!user.details.sub){ + switch(d.f){ + case'accounts': + switch(d.ff){ + case'edit': + d.keys=Object.keys(d.form); + d.condition=[]; + d.value=[]; + d.keys.forEach(function(v){ + d.condition.push(v+'=?') + d.value.push(d.form[v]) + }) + d.value=d.value.concat([d.ke,d.$uid]) + s.sqlQuery("UPDATE Users SET "+d.condition.join(',')+" WHERE ke=? AND uid=?",d.value) + s.tx({f:'edit_sub_account',ke:d.ke,uid:d.$uid,mail:d.mail,form:d.form},'ADM_'+d.ke); + break; + case'delete': + s.sqlQuery('DELETE FROM Users WHERE uid=? AND ke=? AND mail=?',[d.$uid,d.ke,d.mail]) + s.sqlQuery('DELETE FROM API WHERE uid=? AND ke=?',[d.$uid,d.ke]) + s.tx({f:'delete_sub_account',ke:d.ke,uid:d.$uid,mail:d.mail},'ADM_'+d.ke); + break; + } + break; + } + } + }) + } + }) + //functions for webcam recorder + cn.on('r',function(d){ + if(!cn.ke&&d.f==='init'){ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND auth=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + r=r[0] + cn.ke=d.ke,cn.uid=d.uid,cn.auth=d.auth; + if(!s.group[d.ke])s.group[d.ke]={}; + if(!s.group[d.ke].users)s.group[d.ke].users={}; + s.group[d.ke].users[d.auth]={cnid:cn.id,uid:r.uid,mail:r.mail,details:JSON.parse(r.details),logged_in_at:s.timeObject(new Date).format(),login_type:'Streamer'} + } + }) + }else{ + switch(d.f){ + case'monitor_chunk': + if(!s.group[d.ke]||!s.group[d.ke].mon[d.mid]){return} + if(s.group[d.ke].mon[d.mid].started!==1){s.tx({error:'Not Started'},cn.id);return false}; + s.group[d.ke].mon[d.mid].spawn.stdin.write(new Buffer(d.chunk, "binary")); + break; + case'monitor_frame': + if(!s.group[d.ke]||!s.group[d.ke].mon[d.mid]){return} + if(s.group[d.ke].mon[d.mid].started!==1){s.tx({error:'Not Started'},cn.id);return false}; + s.group[d.ke].mon[d.mid].spawn.stdin.write(d.frame); + break; + } + } + }) + //embed functions + cn.on('e', function (d) { + tx=function(z){if(!z.ke){z.ke=cn.ke;};cn.emit('f',z);} + switch(d.f){ + case'init': + if(!s.group[d.ke]||!s.group[d.ke].mon[d.id]||s.group[d.ke].mon[d.id].started===0){return false} + s.auth({auth:d.auth,ke:d.ke,id:d.id,ip:cn.request.connection.remoteAddress},function(user){ + cn.embedded=1; + cn.ke=d.ke; + if(!cn.mid){cn.mid={}} + cn.mid[d.id]={}; +// if(!s.group[d.ke].embed){s.group[d.ke].embed={}} +// if(!s.group[d.ke].embed[d.mid]){s.group[d.ke].embed[d.mid]={}} +// s.group[d.ke].embed[d.mid][cn.id]={} + + s.camera('watch_on',d,cn,tx) + cn.join('MON_'+d.id); + cn.join('MON_STREAM_'+d.id); + cn.join('DETECTOR_'+d.ke+d.id); + cn.join('STR_'+d.ke); + if(s.group[d.ke]&&s.group[d.ke].mon[d.id]&&s.group[d.ke].mon[d.id].watch){ + + tx({f:'monitor_watch_on',id:d.id,ke:d.ke},'MON_'+d.id) + s.tx({viewers:Object.keys(s.group[d.ke].mon[d.id].watch).length,ke:d.ke,id:d.id},'MON_'+d.id) + } + }); + break; + } + }) + //functions for retrieving cron announcements + cn.on('cron',function(d){ + if(d.f==='init'){ + if(config.cron.key){ + if(config.cron.key===d.cronKey){ + s.cron={started:moment(),last_run:moment(),id:cn.id}; + }else{ + cn.disconnect() + } + }else{ + s.cron={started:moment(),last_run:moment(),id:cn.id}; + } + }else{ + if(s.cron&&cn.id===s.cron.id){ + delete(d.cronKey) + switch(d.f){ + case'filters': + s.filterEvents(d.ff,d); + break; + case's.tx': + s.tx(d.data,d.to) + break; + case's.video': + s.video(d.data,d.file) + break; + case'start':case'end': + d.mid='_cron';s.log(d,{type:'cron',msg:d.msg}) + break; + default: + s.systemLog('CRON : ',d) + break; + } + }else{ + cn.disconnect() + } + } + }) + cn.on('disconnect', function () { + if(cn.socketVideoStream){ + cn.closeSocketVideoStream() + return + } + if(cn.ke){ + if(cn.monitor_watching){ + cn.monitor_count=Object.keys(cn.monitor_watching) + if(cn.monitor_count.length>0){ + cn.monitor_count.forEach(function(v){ + s.camera('watch_off',{id:v,ke:cn.monitor_watching[v].ke},s.cn(cn)) + }) + } + }else if(!cn.embedded){ + if(s.group[cn.ke].users[cn.auth].login_type==='Dashboard'){ + s.tx({f:'user_status_change',ke:cn.ke,uid:cn.uid,status:0}) + } + s.log({ke:cn.ke,mid:'$USER'},{type:lang['Websocket Disconnected'],msg:{mail:s.group[cn.ke].users[cn.auth].mail,id:cn.uid,ip:cn.ip}}) + delete(s.group[cn.ke].users[cn.auth]); + } + } + if(cn.pluginEngine){ + s.connectedPlugins[cn.pluginEngine].plugged=false + s.tx({f:'plugin_engine_unplugged',plug:cn.pluginEngine},'CPU') + delete(s.api[cn.pluginEngine]) + } + if(cn.cron){ + delete(s.cron); + } + if(cn.ocv){ + s.tx({f:'detector_unplugged',plug:s.ocv.plug},'CPU') + delete(s.ocv); + delete(s.api[cn.id]) + } + }) +}); +//Authenticator functions +s.api={}; +//auth handler +//params = parameters +//cb = callback +//res = response, only needed for express (http server) +//request = request, only needed for express (http server) +s.checkChildProxy = function(params,cb,res,req){ + if(s.group[params.ke] && s.group[params.ke].mon[params.id] && s.group[params.ke].mon[params.id].childNode){ + var url = 'http://' + s.group[params.ke].mon[params.id].childNode// + req.originalUrl + proxy.web(req, res, { target: url }) + }else{ + cb() + } +} +//auth handler +//params = parameters +//cb = callback +//res = response, only needed for express (http server) +//request = request, only needed for express (http server) +s.auth = function(params,cb,res,req){ + if(req){ + //express (http server) use of auth function + params.ip=req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress; + var failed=function(){ + if(!req.ret){req.ret={ok:false}} + req.ret.msg=lang['Not Authorized']; + res.end(s.s(req.ret, null, 3)); + } + }else{ + //socket.io use of auth function + var failed=function(){ + //maybe log + } + } + var clearAfterTime=function(){ + //remove temp key from memory + clearTimeout(s.api[params.auth].timeout) + s.api[params.auth].timeout=setTimeout(function(){ + delete(s.api[params.auth]) + },1000*60*5) + } + //check IP address of connecting user + var finish=function(user){ + if(s.api[params.auth].ip.indexOf('0.0.0.0')>-1||s.api[params.auth].ip.indexOf(params.ip)>-1){ + cb(user); + }else{ + failed(); + } + } + //check if auth key is user's temporary session key + if(s.group[params.ke]&&s.group[params.ke].users&&s.group[params.ke].users[params.auth]){ + s.group[params.ke].users[params.auth].permissions={}; + cb(s.group[params.ke].users[params.auth]); + }else{ + //check if key is already in memory to save query time + if(s.api[params.auth]&&s.api[params.auth].details){ + finish(s.api[params.auth]); + if(s.api[params.auth].timeout){ + clearAfterTime() + } + }else{ + //no key in memory, query db to see if key exists + //check if using username and password in plain text or md5 + if(params.username&¶ms.username!==''&¶ms.password&¶ms.password!==''){ + s.sqlQuery('SELECT * FROM Users WHERE mail=? AND (pass=? OR pass=?)',[params.username,params.password,s.md5(params.password)],function(err,r){ + if(r&&r[0]){ + r=r[0]; + r.ip='0.0.0.0'; + r.auth = s.gid(20); + params.auth = r.auth; + r.details=JSON.parse(r.details); + r.permissions = {}; + s.api[r.auth]=r; + clearAfterTime(); + finish(r); + }else{ + failed(); + } + }) + }else{ + //not using plain login + s.sqlQuery('SELECT * FROM API WHERE code=? AND ke=?',[params.auth,params.ke],function(err,r){ + if(r&&r[0]){ + r=r[0]; + s.api[params.auth]={ip:r.ip,uid:r.uid,ke:r.ke,permissions:JSON.parse(r.details),details:{}}; + s.sqlQuery('SELECT details FROM Users WHERE uid=? AND ke=?',[r.uid,r.ke],function(err,rr){ + if(rr&&rr[0]){ + rr=rr[0]; + try{ + s.api[params.auth].mail=rr.mail + s.api[params.auth].details=JSON.parse(rr.details) + s.api[params.auth].lang=s.getLanguageFile(s.api[params.auth].details.lang) + }catch(er){} + } + finish(s.api[params.auth]); + }) + }else{ + s.sqlQuery('SELECT * FROM Users WHERE auth=? AND ke=?',[params.auth,params.ke],function(err,r){ + if(r&&r[0]){ + r=r[0]; + r.ip='0.0.0.0' + s.api[params.auth]=r + s.api[params.auth].details=JSON.parse(r.details) + s.api[params.auth].permissions={} + clearAfterTime() + finish(r) + }else{ + failed(); + } + }) + } + }) + } + } + } +} +//super user authentication handler +s.superAuth=function(x,callback){ + req={}; + req.super=require(location.super); + req.super.forEach(function(v,n){ + if(x.md5===true){ + x.pass=s.md5(x.pass); + } + if(x.mail.toLowerCase()===v.mail.toLowerCase()&&x.pass===v.pass){ + req.found=1; + if(x.users===true){ + s.sqlQuery('SELECT * FROM Users WHERE details NOT LIKE ?',['%"sub"%'],function(err,r) { + callback({$user:v,users:r,config:config,lang:lang}) + }) + }else{ + callback({$user:v,config:config,lang:lang}) + } + } + }) + if(req.found!==1){ + return false; + }else{ + return true; + } +} +////Pages +app.enable('trust proxy'); +app.use('/libs',express.static(__dirname + '/web/libs')); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({extended: true})); +app.set('views', __dirname + '/web'); +app.set('view engine','ejs'); +//add template handler +if(config.renderPaths.handler!==undefined){require(__dirname+'/web/'+config.renderPaths.handler+'.js').addHandlers(s,app,io)} + +//readme +app.get('/:auth/logout/:ke/:id', function (req,res){ + if(s.group[req.params.ke]&&s.group[req.params.ke].users[req.params.auth]){ + delete(s.api[req.params.auth]); + delete(s.group[req.params.ke].users[req.params.auth]); + s.sqlQuery("UPDATE Users SET auth=? WHERE auth=? AND ke=? AND uid=?",['',req.params.auth,req.params.ke,req.params.id]) + res.end(s.s({ok:true,msg:'You have been logged out, session key is now inactive.'}, null, 3)) + }else{ + res.end(s.s({ok:false,msg:'This group key does not exist or this user is not logged in.'}, null, 3)) + } +}); +//main page +app.get(config.webPaths.index, function (req,res){ + res.render(config.renderPaths.index,{lang:lang,config:config,screen:'dashboard'},function(err,html){ + if(err){ + s.systemLog(err) + } + res.end(html) + }) +}); +//admin page +app.get(config.webPaths.admin, function (req,res){ + res.render(config.renderPaths.index,{lang:lang,config:config,screen:'admin'},function(err,html){ + if(err){ + s.systemLog(err) + } + res.end(html) + }) +}); +//super page +app.get(config.webPaths.super, function (req,res){ + res.render(config.renderPaths.index,{lang:lang,config:config,screen:'super'},function(err,html){ + if(err){ + s.systemLog(err) + } + res.end(html) + }) +}); +//update server +app.get('/:auth/update/:key', function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + req.fn=function(user){ + if(!config.updateKey){ + req.ret.msg=user.lang.updateKeyText1; + return; + } + if(req.params.key===config.updateKey){ + req.ret.ok=true; + exec('chmod +x '+__dirname+'/UPDATE.sh&&'+__dirname+'/UPDATE.sh',{detached: true}) + }else{ + req.ret.msg=user.lang.updateKeyText2; + } + res.end(s.s(req.ret, null, 3)); + } + s.auth(req.params,req.fn,res,req); +}); +//get user details by API key +app.get('/:auth/userInfo/:ke',function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + req.ret.ok=true + req.ret.user=user + res.end(s.s(req.ret, null, 3)); + },res,req); +}) +//register function +app.post('/:auth/register/:ke/:uid',function (req,res){ + req.resp={ok:false}; + res.setHeader('Content-Type', 'application/json'); + s.auth(req.params,function(user){ + s.sqlQuery('SELECT * FROM Users WHERE uid=? AND ke=? AND details NOT LIKE ? LIMIT 1',[req.params.uid,req.params.ke,'%"sub"%'],function(err,u) { + if(u&&u[0]){ + if(req.body.mail!==''&&req.body.pass!==''){ + if(req.body.pass===req.body.password_again){ + s.sqlQuery('SELECT * FROM Users WHERE mail=?',[req.body.mail],function(err,r) { + if(r&&r[0]){//found one exist + req.resp.msg='Email address is in use.'; + }else{//create new + req.resp.msg='New Account Created';req.resp.ok=true; + req.gid=s.gid(); + req.body.details='{"sub":"1","allmonitors":"1"}'; + s.sqlQuery('INSERT INTO Users (ke,uid,mail,pass,details) VALUES (?,?,?,?,?)',[req.params.ke,req.gid,req.body.mail,s.md5(req.body.pass),req.body.details]) + s.tx({f:'add_sub_account',details:req.body.details,ke:req.params.ke,uid:req.gid,mail:req.body.mail},'ADM_'+req.params.ke); + } + res.end(s.s(req.resp,null,3)); + }) + }else{ + req.resp.msg=user.lang['Passwords Don\'t Match']; + } + }else{ + req.resp.msg=user.lang['Fields cannot be empty']; + } + }else{ + req.resp.msg=user.lang['Not an Administrator Account']; + } + if(req.resp.msg){ + res.end(s.s(req.resp,null,3)); + } + }) + },res,req); +}) +//login function +s.deleteFactorAuth=function(r){ + delete(s.factorAuth[r.ke][r.uid]) + if(Object.keys(s.factorAuth[r.ke]).length===0){ + delete(s.factorAuth[r.ke]) + } +} +app.post(['/','/:screen'],function (req,res){ + req.ip=req.headers['cf-connecting-ip']||req.headers["CF-Connecting-IP"]||req.headers["'x-forwarded-for"]||req.connection.remoteAddress; + if(req.query.json=='true'){ + res.header("Access-Control-Allow-Origin",req.headers.origin); + } + req.renderFunction=function(focus,data){ + if(req.query.json=='true'){ + delete(data.config) + data.ok=true; + res.setHeader('Content-Type', 'application/json'); + res.end(s.s(data, null, 3)) + }else{ + data.screen=req.params.screen + res.render(focus,data,function(err,html){ + if(err){ + s.systemLog(err) + } + res.end(html) + }); + } + } + req.failed=function(board){ + if(req.query.json=='true'){ + res.setHeader('Content-Type', 'application/json'); + res.end(s.s({ok:false}, null, 3)) + }else{ + res.render(config.renderPaths.index,{failedLogin:true,lang:lang,config:config,screen:req.params.screen},function(err,html){ + if(err){ + s.systemLog(err) + } + res.end(html); + }); + } + req.logTo={ke:'$',mid:'$USER'} + req.logData={type:lang['Authentication Failed'],msg:{for:board,mail:req.body.mail,ip:req.ip}} + if(board==='super'){ + s.log(req.logTo,req.logData) + }else{ + s.sqlQuery('SELECT ke,uid,details FROM Users WHERE mail=?',[req.body.mail],function(err,r) { + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details); + r.lang=s.getLanguageFile(r.details.lang) + req.logData.id=r.uid + req.logData.type=r.lang['Authentication Failed'] + req.logTo.ke=r.ke + } + s.log(req.logTo,req.logData) + }) + } + } + req.fn=function(r){ + switch(req.body.function){ + case'cam': + s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND type=?',[r.ke,"dashcam"],function(err,rr){ + req.resp.mons=rr; + req.renderFunction(config.renderPaths.dashcam,{$user:req.resp,lang:r.lang,define:s.getDefinitonFile(r.details.lang)}); + }) + break; + case'streamer': + s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND type=?',[r.ke,"socket"],function(err,rr){ + req.resp.mons=rr; + req.renderFunction(config.renderPaths.streamer,{$user:req.resp,lang:r.lang,define:s.getDefinitonFile(r.details.lang)}); + }) + break; + case'admin': + if(!r.details.sub){ + s.sqlQuery('SELECT uid,mail,details FROM Users WHERE ke=? AND details LIKE \'%"sub"%\'',[r.ke],function(err,rr) { + s.sqlQuery('SELECT * FROM Monitors WHERE ke=?',[r.ke],function(err,rrr) { + req.renderFunction(config.renderPaths.admin,{$user:req.resp,$subs:rr,$mons:rrr,lang:r.lang,define:s.getDefinitonFile(r.details.lang)}); + }) + }) + }else{ + //not admin user + req.renderFunction(config.renderPaths.home,{$user:req.resp,config:config,lang:r.lang,define:s.getDefinitonFile(r.details.lang),addStorage:s.dir.addStorage,fs:fs,__dirname:__dirname}); + } + break; + default: + req.renderFunction(config.renderPaths.home,{$user:req.resp,config:config,lang:r.lang,define:s.getDefinitonFile(r.details.lang),addStorage:s.dir.addStorage,fs:fs,__dirname:__dirname}); + break; + } + s.log({ke:r.ke,mid:'$USER'},{type:r.lang['New Authentication Token'],msg:{for:req.body.function,mail:r.mail,id:r.uid,ip:req.ip}}) + // res.end(); + } + if(req.body.mail&&req.body.pass){ + req.default=function(){ + s.sqlQuery('SELECT * FROM Users WHERE mail=? AND pass=?',[req.body.mail,s.md5(req.body.pass)],function(err,r) { + req.resp={ok:false}; + if(!err&&r&&r[0]){ + r=r[0];r.auth=s.md5(s.gid()); + s.sqlQuery("UPDATE Users SET auth=? WHERE ke=? AND uid=?",[r.auth,r.ke,r.uid]) + req.resp={ok:true,auth_token:r.auth,ke:r.ke,uid:r.uid,mail:r.mail,details:r.details}; + r.details=JSON.parse(r.details); + r.lang=s.getLanguageFile(r.details.lang) + req.factorAuth=function(cb){ + if(r.details.factorAuth==="1"){ + if(!r.details.acceptedMachines||!(r.details.acceptedMachines instanceof Object)){ + r.details.acceptedMachines={} + } + if(!r.details.acceptedMachines[req.body.machineID]){ + req.complete=function(){ + s.factorAuth[r.ke][r.uid].info=req.resp; + clearTimeout(s.factorAuth[r.ke][r.uid].expireAuth) + s.factorAuth[r.ke][r.uid].expireAuth=setTimeout(function(){ + s.deleteFactorAuth(r) + },1000*60*15) + req.renderFunction(config.renderPaths.factorAuth,{$user:req.resp,lang:r.lang}) + } + if(!s.factorAuth[r.ke]){s.factorAuth[r.ke]={}} + if(!s.factorAuth[r.ke][r.uid]){ + s.factorAuth[r.ke][r.uid]={key:s.nid(),user:r} + r.mailOptions = { + from: '"ShinobiCCTV" ', + to: r.mail, + subject: r.lang['2-Factor Authentication'], + html: r.lang['Enter this code to proceed']+' '+s.factorAuth[r.ke][r.uid].key+'. '+r.lang.FactorAuthText1, + }; + nodemailer.sendMail(r.mailOptions, (error, info) => { + if (error) { + s.systemLog(r.lang.MailError,error) + req.fn(r) + return + } + req.complete() + }); + }else{ + req.complete() + } + }else{ + req.fn(r) + } + }else{ + req.fn(r) + } + } + if(r.details.sub){ + s.sqlQuery('SELECT details FROM Users WHERE ke=? AND details NOT LIKE ?',[r.ke,'%"sub"%'],function(err,rr) { + rr=rr[0]; + rr.details=JSON.parse(rr.details); + r.details.mon_groups=rr.details.mon_groups; + req.resp.details=JSON.stringify(r.details); + req.factorAuth() + }) + }else{ + req.factorAuth() + } + }else{ + req.failed(req.body.function) + } + }) + } + if(LdapAuth&&req.body.function==='ldap'&&req.body.key!==''){ + s.sqlQuery('SELECT * FROM Users WHERE ke=? AND details NOT LIKE ?',[req.body.key,'%"sub"%'],function(err,r) { + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details) + r.lang=s.getLanguageFile(r.details.lang) + if(r.details.use_ldap!=='0'&&r.details.ldap_enable==='1'&&r.details.ldap_url&&r.details.ldap_url!==''){ + req.mailArray={} + req.body.mail.split(',').forEach(function(v){ + v=v.split('=') + req.mailArray[v[0]]=v[1] + }) + if(!r.details.ldap_bindDN||r.details.ldap_bindDN===''){ + r.details.ldap_bindDN=req.body.mail + } + if(!r.details.ldap_bindCredentials||r.details.ldap_bindCredentials===''){ + r.details.ldap_bindCredentials=req.body.pass + } + if(!r.details.ldap_searchFilter||r.details.ldap_searchFilter===''){ + r.details.ldap_searchFilter=req.body.mail + if(req.mailArray.cn){ + r.details.ldap_searchFilter='cn='+req.mailArray.cn + } + if(req.mailArray.uid){ + r.details.ldap_searchFilter='uid='+req.mailArray.uid + } + }else{ + r.details.ldap_searchFilter=r.details.ldap_searchFilter.replace('{{username}}',req.body.mail) + } + if(!r.details.ldap_searchBase||r.details.ldap_searchBase===''){ + r.details.ldap_searchBase='dc=test,dc=com' + } + req.auth = new LdapAuth({ + url:r.details.ldap_url, + bindDN:r.details.ldap_bindDN, + bindCredentials:r.details.ldap_bindCredentials, + searchBase:r.details.ldap_searchBase, + searchFilter:'('+r.details.ldap_searchFilter+')', + reconnect:true + }); + req.auth.on('error', function (err) { + console.error('LdapAuth: ', err); + }); + + req.auth.authenticate(req.body.mail, req.body.pass, function(err, user) { + if(user){ + //found user + if(!user.uid){ + user.uid=s.gid() + } + req.resp={ + ke:req.body.key, + uid:user.uid, + auth:s.md5(s.gid()), + mail:user.mail, + pass:s.md5(req.body.pass), + details:JSON.stringify({ + sub:'1', + ldap:'1', + allmonitors:'1', + filter: {} + }) + } + user.post=[] + Object.keys(req.resp).forEach(function(v){ + user.post.push(req.resp[v]) + }) + s.log({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP Success'],msg:{user:user}}) + s.sqlQuery('SELECT * FROM Users WHERE ke=? AND mail=?',[req.body.key,user.cn],function(err,rr){ + if(rr&&rr[0]){ + //already registered + rr=rr[0] + req.resp=rr; + rr.details=JSON.parse(rr.details) + req.resp.lang=s.getLanguageFile(rr.details.lang) + s.log({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP User Authenticated'],msg:{user:user,shinobiUID:rr.uid}}) + s.sqlQuery("UPDATE Users SET auth=? WHERE ke=? AND uid=?",[req.resp.auth,req.resp.ke,rr.uid]) + }else{ + //new ldap login + s.log({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP User is New'],msg:{info:r.lang['Creating New Account'],user:user}}) + req.resp.lang=r.lang + s.sqlQuery('INSERT INTO Users (ke,uid,auth,mail,pass,details) VALUES (?,?,?,?,?,?)',user.post) + } + req.resp.details=JSON.stringify(req.resp.details) + req.resp.auth_token=req.resp.auth + req.resp.ok=true + req.fn(req.resp) + }) + return + } + s.log({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP Failed'],msg:{err:err}}) + //no user + req.default() + }); + + req.auth.close(function(err) { + + }) + }else{ + req.default() + } + }else{ + req.default() + } + }) + }else{ + if(req.body.function==='super'){ + if(!fs.existsSync(location.super)){ + res.end(lang.superAdminText) + return + } + req.ok=s.superAuth({mail:req.body.mail,pass:req.body.pass,users:true,md5:true},function(data){ + s.sqlQuery('SELECT * FROM Logs WHERE ke=? ORDER BY `time` DESC LIMIT 30',['$'],function(err,r) { + if(!r){ + r=[] + } + data.Logs=r; + fs.readFile(location.config,'utf8',function(err,file){ + data.plainConfig=JSON.parse(file) + req.renderFunction(config.renderPaths.super,data); + }) + }) + }) + if(req.ok===false){ + req.failed(req.body.function) + } + }else{ + req.default() + } + } + }else{ + if(req.body.machineID&&req.body.factorAuthKey){ + if(s.factorAuth[req.body.ke]&&s.factorAuth[req.body.ke][req.body.id]&&s.factorAuth[req.body.ke][req.body.id].key===req.body.factorAuthKey){ + if(s.factorAuth[req.body.ke][req.body.id].key===req.body.factorAuthKey){ + if(req.body.remember==="1"){ + req.details=JSON.parse(s.factorAuth[req.body.ke][req.body.id].info.details) + req.lang=s.getLanguageFile(req.details.lang) + if(!req.details.acceptedMachines||!(req.details.acceptedMachines instanceof Object)){ + req.details.acceptedMachines={} + } + if(!req.details.acceptedMachines[req.body.machineID]){ + req.details.acceptedMachines[req.body.machineID]={} + s.sqlQuery("UPDATE Users SET details=? WHERE ke=? AND uid=?",[s.s(req.details),req.body.ke,req.body.id]) + } + } + req.resp=s.factorAuth[req.body.ke][req.body.id].info + req.fn(s.factorAuth[req.body.ke][req.body.id].user) + }else{ + req.renderFunction(config.renderPaths.factorAuth,{$user:s.factorAuth[req.body.ke][req.body.id].info,lang:req.lang}); + res.end(); + } + }else{ + req.failed(lang['2-Factor Authentication']) + } + }else{ + req.failed(lang['2-Factor Authentication']) + } + } +}); +// Get HLS stream (m3u8) +app.get(['/:auth/hls/:ke/:id/:file','/:auth/hls/:ke/:id/:channel/:file'], function (req,res){ + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.fn=function(user){ + s.checkChildProxy(req.params,function(){ + req.dir=s.dir.streams+req.params.ke+'/'+req.params.id+'/' + if(req.params.channel){ + req.dir+='channel'+(parseInt(req.params.channel)+config.pipeAddition)+'/'+req.params.file; + }else{ + req.dir+=req.params.file; + } + res.on('finish',function(){res.end();}); + if (fs.existsSync(req.dir)){ + fs.createReadStream(req.dir).pipe(res); + }else{ + res.end(lang['File Not Found']) + } + },res,req) + } + s.auth(req.params,req.fn,res,req); +}); +//Get JPEG snap +app.get('/:auth/jpeg/:ke/:id/s.jpg', function(req,res){ + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + s.checkChildProxy(req.params,function(){ + if(user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors&&user.details.monitors.indexOf(req.params.id)===-1){ + res.end(user.lang['Not Permitted']) + return + } + req.dir=s.dir.streams+req.params.ke+'/'+req.params.id+'/s.jpg'; + res.writeHead(200, { + 'Content-Type': 'image/jpeg', + 'Cache-Control': 'no-cache', + 'Pragma': 'no-cache' + }); + res.on('finish',function(){res.end();delete(res)}); + if (fs.existsSync(req.dir)){ + fs.createReadStream(req.dir).pipe(res); + }else{ + fs.createReadStream(config.defaultMjpeg).pipe(res); + } + },res,req); + },res,req); +}); +//Get FLV stream +app.get(['/:auth/flv/:ke/:id/s.flv','/:auth/flv/:ke/:id/:channel/s.flv'], function(req,res) { + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + s.checkChildProxy(req.params,function(){ + var Emitter,chunkChannel + if(!req.params.channel){ + Emitter = s.group[req.params.ke].mon[req.params.id].emitter + chunkChannel = 'MAIN' + }else{ + Emitter = s.group[req.params.ke].mon[req.params.id].emitterChannel[parseInt(req.params.channel)+config.pipeAddition] + chunkChannel = parseInt(req.params.channel)+config.pipeAddition + } + if(s.group[req.params.ke].mon[req.params.id].firstStreamChunk[chunkChannel]){ + //variable name of contentWriter + var contentWriter + //set headers + res.setHeader('Content-Type', 'video/x-flv'); + res.setHeader('Access-Control-Allow-Origin','*'); + //write first frame on stream + res.write(s.group[req.params.ke].mon[req.params.id].firstStreamChunk[chunkChannel]) + //write new frames as they happen + Emitter.on('data',contentWriter=function(buffer){ + res.write(buffer) + }) + //remove contentWriter when client leaves + res.on('close', function () { + Emitter.removeListener('data',contentWriter) + }) + }else{ + res.setHeader('Content-Type', 'application/json'); + res.end(s.s({ok:false,msg:'FLV not started or not ready'},null,3)) + } + },res,req) + },res,req) +}) +//montage - stand alone squished view with gridstackjs +app.get(['/:auth/grid/:ke','/:auth/grid/:ke/:group'], function(req,res) { + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(user.permissions.get_monitors==="0"){ + res.end(user.lang['Not Permitted']) + return + } + + req.params.protocol=req.protocol; + req.sql='SELECT * FROM Monitors WHERE mode!=? AND mode!=? AND ke=?';req.ar=['stop','idle',req.params.ke]; + if(!req.params.id){ + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + } + }else{ + if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + }else{ + res.end(user.lang['There are no monitors that you can view with this account.']); + return; + } + } + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(req.params.group){ + var filteredByGroupCheck = {}; + var filteredByGroup = []; + r.forEach(function(v,n){ + var details = JSON.parse(r[n].details); + try{ + req.params.group.split('|').forEach(function(group){ + var groups = JSON.parse(details.groups); + if(groups.indexOf(group) > -1 && !filteredByGroupCheck[v.mid]){ + filteredByGroupCheck[v.mid] = true; + filteredByGroup.push(v) + } + }) + }catch(err){ + + } + }) + r = filteredByGroup; + } + r.forEach(function(v,n){ + if(s.group[v.ke]&&s.group[v.ke].mon[v.mid]&&s.group[v.ke].mon[v.mid].watch){ + r[n].currentlyWatching=Object.keys(s.group[v.ke].mon[v.mid].watch).length + } + r[n].subStream={} + var details = JSON.parse(r[n].details) + if(details.snap==='1'){ + r[n].subStream.jpeg = '/'+req.params.auth+'/jpeg/'+v.ke+'/'+v.mid+'/s.jpg' + } + if(details.stream_channels&&details.stream_channels!==''){ + try{ + details.stream_channels=JSON.parse(details.stream_channels) + r[n].channels=[] + details.stream_channels.forEach(function(b,m){ + var streamURL + switch(b.stream_type){ + case'mjpeg': + streamURL='/'+req.params.auth+'/mjpeg/'+v.ke+'/'+v.mid+'/'+m + break; + case'hls': + streamURL='/'+req.params.auth+'/hls/'+v.ke+'/'+v.mid+'/'+m+'/s.m3u8' + break; + case'h264': + streamURL='/'+req.params.auth+'/h264/'+v.ke+'/'+v.mid+'/'+m + break; + case'flv': + streamURL='/'+req.params.auth+'/flv/'+v.ke+'/'+v.mid+'/'+m+'/s.flv' + break; + case'mp4': + streamURL='/'+req.params.auth+'/mp4/'+v.ke+'/'+v.mid+'/'+m+'/s.mp4' + break; + } + r[n].channels.push(streamURL) + }) + }catch(err){ + s.log(req.params,{type:'Broken Monitor Object',msg:'Stream Channels Field is damaged. Skipping.'}) + } + } + }) + res.render(config.renderPaths.grid,{ + data:Object.assign(req.params,req.query), + baseUrl:req.protocol+'://'+req.hostname, + config:config, + lang:user.lang, + $user:user, + monitors:r + }); + }) + },res,req) +}); +//MJPEG feed +// if query string `full=true` is not present then it will load the MJPEG data directly and not the iframe ready page. +app.get(['/:auth/mjpeg/:ke/:id','/:auth/mjpeg/:ke/:id/:channel'], function(req,res) { + res.header("Access-Control-Allow-Origin",req.headers.origin); + if(req.query.full=='true'){ + res.render(config.renderPaths.mjpeg,{url:'/'+req.params.auth+'/mjpeg/'+req.params.ke+'/'+req.params.id}); + res.end() + }else{ + s.auth(req.params,function(user){ + s.checkChildProxy(req.params,function(){ + if(s.group[req.params.ke]&&s.group[req.params.ke].mon[req.params.id]){ + if(user.permissions.watch_stream==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){ + res.end(user.lang['Not Permitted']) + return + } + + var Emitter + if(!req.params.channel){ + Emitter = s.group[req.params.ke].mon[req.params.id].emitter + }else{ + Emitter = s.group[req.params.ke].mon[req.params.id].emitterChannel[parseInt(req.params.channel)+config.pipeAddition] + } + res.writeHead(200, { + 'Content-Type': 'multipart/x-mixed-replace; boundary=shinobi', + 'Cache-Control': 'no-cache', + 'Connection': 'keep-alive', + 'Pragma': 'no-cache' + }); + var contentWriter,content = fs.readFileSync(config.defaultMjpeg,'binary'); + res.write("--shinobi\r\n"); + res.write("Content-Type: image/jpeg\r\n"); + res.write("Content-Length: " + content.length + "\r\n"); + res.write("\r\n"); + res.write(content,'binary'); + res.write("\r\n"); + Emitter.on('data',contentWriter=function(d){ + content = d; + res.write(content,'binary'); + }) + res.on('close', function () { + Emitter.removeListener('data',contentWriter) + }); + }else{ + res.end(); + } + },res,req); + },res,req); + } +}); +//embed monitor +app.get(['/:auth/embed/:ke/:id','/:auth/embed/:ke/:id/:addon'], function (req,res){ + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.params.protocol=req.protocol; + s.auth(req.params,function(user){ + if(user.permissions.watch_stream==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){ + res.end(user.lang['Not Permitted']) + return + } + if(s.group[req.params.ke]&&s.group[req.params.ke].mon[req.params.id]){ + if(s.group[req.params.ke].mon[req.params.id].started===1){ + req.params.uid=user.uid; + res.render(config.renderPaths.embed,{data:req.params,baseUrl:req.protocol+'://'+req.hostname,config:config,lang:user.lang,mon:CircularJSON.parse(CircularJSON.stringify(s.group[req.params.ke].mon_conf[req.params.id]))}); + res.end() + }else{ + res.end(user.lang['Cannot watch a monitor that isn\'t running.']) + } + }else{ + res.end(user.lang['No Monitor Exists with this ID.']) + } + },res,req); +}); +// Get TV Channels (Monitor Streams) json +app.get(['/:auth/tvChannels/:ke','/:auth/tvChannels/:ke/:id','/get.php'], function (req,res){ + req.ret={ok:false}; + if(req.query.username&&req.query.password){ + req.params.username = req.query.username + req.params.password = req.query.password + } + var output = ['h264','hls','mp4'] + if(req.query.output&&req.query.output!==''){ + output = req.query.output.split(',') + output.forEach(function(type,n){ + if(type==='ts'){ + output[n]='h264' + if(output.indexOf('hls')===-1){ + output.push('hls') + } + } + }) + } + var isM3u8 = false; + if(req.query.type==='m3u8'||req.query.type==='m3u_plus'){ + //is m3u8 + isM3u8 = true; + }else{ + res.setHeader('Content-Type', 'application/json'); + } + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.fn=function(user){ + if(user.permissions.get_monitors==="0"){ + res.end(s.s([])) + return + } + if(!req.params.ke){ + req.params.ke = user.ke; + } + if(req.query.id&&!req.params.id){ + req.params.id = req.query.id; + } + req.sql='SELECT * FROM Monitors WHERE mode!=? AND ke=?';req.ar=['stop',req.params.ke]; + if(!req.params.id){ + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + } + }else{ + if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + }else{ + res.end('[]'); + return; + } + } + s.sqlQuery(req.sql,req.ar,function(err,r){ + var tvChannelMonitors = []; + r.forEach(function(v,n){ + var buildStreamURL = function(channelRow,type,channelNumber){ + var streamURL + if(channelNumber){channelNumber = '/'+channelNumber}else{channelNumber=''} + switch(type){ + case'mjpeg': + streamURL='/'+req.params.auth+'/mjpeg/'+v.ke+'/'+v.mid+channelNumber + break; + case'hls': + streamURL='/'+req.params.auth+'/hls/'+v.ke+'/'+v.mid+channelNumber+'/s.m3u8' + break; + case'h264': + streamURL='/'+req.params.auth+'/h264/'+v.ke+'/'+v.mid+channelNumber + break; + case'flv': + streamURL='/'+req.params.auth+'/flv/'+v.ke+'/'+v.mid+channelNumber+'/s.flv' + break; + case'mp4': + streamURL='/'+req.params.auth+'/mp4/'+v.ke+'/'+v.mid+channelNumber+'/s.ts' + break; + } + if(streamURL){ + if(!channelRow.streamsSortedByType[type]){ + channelRow.streamsSortedByType[type]=[] + } + channelRow.streamsSortedByType[type].push(streamURL) + channelRow.streams.push(streamURL) + } + return streamURL + } + var details = JSON.parse(r[n].details); + if(!details.tv_channel_id||details.tv_channel_id==='')details.tv_channel_id = 'temp_'+s.gid(5) + var channelRow = { + ke:v.ke, + mid:v.mid, + type:v.type, + groupTitle:details.tv_channel_group_title, + channel:details.tv_channel_id, + }; + if(details.snap==='1'){ + channelRow.snapshot = '/'+req.params.auth+'/jpeg/'+v.ke+'/'+v.mid+'/s.jpg' + } + channelRow.streams=[] + channelRow.streamsSortedByType={} + buildStreamURL(channelRow,details.stream_type) + if(details.stream_channels&&details.stream_channels!==''){ + details.stream_channels=JSON.parse(details.stream_channels) + details.stream_channels.forEach(function(b,m){ + buildStreamURL(channelRow,b.stream_type,m.toString()) + }) + } + if(details.tv_channel==='1'){ + tvChannelMonitors.push(channelRow) + } + }) + if(isM3u8){ + var m3u8 = '#EXTM3U'+'\n' + tvChannelMonitors.forEach(function(channelRow,n){ + output.forEach(function(type){ + if(channelRow.streamsSortedByType[type]){ + if(req.query.type==='m3u_plus'){ + m3u8 +='#EXTINF-1 tvg-id="'+channelRow.mid+'" tvg-name="'+channelRow.channel+'" tvg-logo="'+req.protocol+'://'+req.headers.host+channelRow.snapshot+'" group-title="'+channelRow.groupTitle+'",'+channelRow.channel+'\n' + }else{ + m3u8 +='#EXTINF:-1,'+channelRow.channel+' ('+type.toUpperCase()+') \n' + } + m3u8 += req.protocol+'://'+req.headers.host+channelRow.streamsSortedByType[type][0]+'\n' + } + }) + }) + res.end(m3u8) + }else{ + if(tvChannelMonitors.length===1){tvChannelMonitors=tvChannelMonitors[0];} + res.end(s.s(tvChannelMonitors, null, 3)); + } + }) + } + s.auth(req.params,req.fn,res,req); +}); +// Get monitors json +app.get(['/:auth/monitor/:ke','/:auth/monitor/:ke/:id'], function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.fn=function(user){ + if(user.permissions.get_monitors==="0"){ + res.end(s.s([])) + return + } + req.sql='SELECT * FROM Monitors WHERE ke=?';req.ar=[req.params.ke]; + if(!req.params.id){ + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + } + }else{ + if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + }else{ + res.end('[]'); + return; + } + } + s.sqlQuery(req.sql,req.ar,function(err,r){ + r.forEach(function(v,n){ + if(s.group[v.ke]&&s.group[v.ke].mon[v.mid]&&s.group[v.ke].mon[v.mid].watch){ + r[n].currentlyWatching=Object.keys(s.group[v.ke].mon[v.mid].watch).length + } + var buildStreamURL = function(type,channelNumber){ + var streamURL + if(channelNumber){channelNumber = '/'+channelNumber}else{channelNumber=''} + switch(type){ + case'mjpeg': + streamURL='/'+req.params.auth+'/mjpeg/'+v.ke+'/'+v.mid+channelNumber + break; + case'hls': + streamURL='/'+req.params.auth+'/hls/'+v.ke+'/'+v.mid+channelNumber+'/s.m3u8' + break; + case'h264': + streamURL='/'+req.params.auth+'/h264/'+v.ke+'/'+v.mid+channelNumber + break; + case'flv': + streamURL='/'+req.params.auth+'/flv/'+v.ke+'/'+v.mid+channelNumber+'/s.flv' + break; + case'mp4': + streamURL='/'+req.params.auth+'/mp4/'+v.ke+'/'+v.mid+channelNumber+'/s.mp4' + break; + } + if(streamURL){ + if(!r[n].streamsSortedByType[type]){ + r[n].streamsSortedByType[type]=[] + } + r[n].streamsSortedByType[type].push(streamURL) + r[n].streams.push(streamURL) + } + return streamURL + } + var details = JSON.parse(r[n].details); + if(!details.tv_channel_id||details.tv_channel_id==='')details.tv_channel_id = 'temp_'+s.gid(5) + if(details.snap==='1'){ + r[n].snapshot = '/'+req.params.auth+'/jpeg/'+v.ke+'/'+v.mid+'/s.jpg' + } + r[n].streams=[] + r[n].streamsSortedByType={} + buildStreamURL(details.stream_type) + if(details.stream_channels&&details.stream_channels!==''){ + details.stream_channels=JSON.parse(details.stream_channels) + details.stream_channels.forEach(function(b,m){ + buildStreamURL(b.stream_type,m.toString()) + }) + } + }) + if(r.length===1){r=r[0];} + res.end(s.s(r, null, 3)); + }) + } + s.auth(req.params,req.fn,res,req); +}); +// Get videos json +app.get(['/:auth/videos/:ke','/:auth/videos/:ke/:id'], function (req,res){ + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.video_view.indexOf(req.params.id)===-1){ + res.end(s.s([])) + return + } + req.sql='SELECT * FROM Videos WHERE ke=?';req.ar=[req.params.ke]; + req.count_sql='SELECT COUNT(*) FROM Videos WHERE ke=?';req.count_ar=[req.params.ke]; + if(req.query.archived=='1'){ + req.sql+=' AND details LIKE \'%"archived":"1"\'' + req.count_sql+=' AND details LIKE \'%"archived":"1"\'' + } + if(!req.params.id){ + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + req.count_sql+=' AND ('+req.or.join(' OR ')+')' + } + }else{ + if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + req.count_sql+=' and mid=?';req.count_ar.push(req.params.id) + }else{ + res.end('[]'); + return; + } + } + if(req.query.start||req.query.end){ + if(!req.query.startOperator||req.query.startOperator==''){ + req.query.startOperator='>=' + } + if(!req.query.endOperator||req.query.endOperator==''){ + req.query.endOperator='<=' + } + switch(true){ + case(req.query.start&&req.query.start!==''&&req.query.end&&req.query.end!==''): + req.query.start=req.query.start.replace('T',' ') + req.query.end=req.query.end.replace('T',' ') + req.sql+=' AND `time` '+req.query.startOperator+' ? AND `end` '+req.query.endOperator+' ?'; + req.count_sql+=' AND `time` '+req.query.startOperator+' ? AND `end` '+req.query.endOperator+' ?'; + req.ar.push(req.query.start) + req.ar.push(req.query.end) + req.count_ar.push(req.query.start) + req.count_ar.push(req.query.end) + break; + case(req.query.start&&req.query.start!==''): + req.query.start=req.query.start.replace('T',' ') + req.sql+=' AND `time` '+req.query.startOperator+' ?'; + req.count_sql+=' AND `time` '+req.query.startOperator+' ?'; + req.ar.push(req.query.start) + req.count_ar.push(req.query.start) + break; + case(req.query.end&&req.query.end!==''): + req.query.end=req.query.end.replace('T',' ') + req.sql+=' AND `end` '+req.query.endOperator+' ?'; + req.count_sql+=' AND `end` '+req.query.endOperator+' ?'; + req.ar.push(req.query.end) + req.count_ar.push(req.query.end) + break; + } + } + req.sql+=' ORDER BY `time` DESC'; + if(!req.query.limit||req.query.limit==''){ + req.query.limit='100' + } + if(req.query.limit!=='0'){ + req.sql+=' LIMIT '+req.query.limit + } + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(!r){ + res.end(s.s({total:0,limit:req.query.limit,skip:0,videos:[]}, null, 3)); + return + } + s.sqlQuery(req.count_sql,req.count_ar,function(err,count){ + s.video('linkBuild',r,req.params.auth) + if(req.query.limit.indexOf(',')>-1){ + req.skip=parseInt(req.query.limit.split(',')[0]) + req.query.limit=parseInt(req.query.limit.split(',')[0]) + }else{ + req.skip=0 + req.query.limit=parseInt(req.query.limit) + } + res.end(s.s({isUTC:config.useUTC,total:count[0]['COUNT(*)'],limit:req.query.limit,skip:req.skip,videos:r}, null, 3)); + }) + }) + },res,req); +}); +// Get events json (motion logs) +app.get(['/:auth/events/:ke','/:auth/events/:ke/:id','/:auth/events/:ke/:id/:limit','/:auth/events/:ke/:id/:limit/:start','/:auth/events/:ke/:id/:limit/:start/:end'], function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.video_view.indexOf(req.params.id)===-1){ + res.end(s.s([])) + return + } + req.sql='SELECT * FROM Events WHERE ke=?';req.ar=[req.params.ke]; + if(!req.params.id){ + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + } + }else{ + if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + }else{ + res.end('[]'); + return; + } + } + if(req.params.start&&req.params.start!==''){ + req.params.start=req.params.start.replace('T',' ') + if(req.params.end&&req.params.end!==''){ + req.params.end=req.params.end.replace('T',' ') + req.sql+=' AND `time` >= ? AND `time` <= ?'; + req.ar.push(decodeURIComponent(req.params.start)) + req.ar.push(decodeURIComponent(req.params.end)) + }else{ + req.sql+=' AND `time` >= ?'; + req.ar.push(decodeURIComponent(req.params.start)) + } + } + if(!req.params.limit||req.params.limit==''){req.params.limit=100} + req.sql+=' ORDER BY `time` DESC LIMIT '+req.params.limit+''; + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(err){ + err.sql=req.sql; + res.end(s.s(err, null, 3)); + return + } + if(!r){r=[]} + r.forEach(function(v,n){ + r[n].details=JSON.parse(v.details); + }) + res.end(s.s(r, null, 3)); + }) + },res,req); +}); +// Get logs json +app.get(['/:auth/logs/:ke','/:auth/logs/:ke/:id'], function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(user.permissions.get_logs==="0"){ + res.end(s.s([])) + return + } + req.sql='SELECT * FROM Logs WHERE ke=?';req.ar=[req.params.ke]; + if(!req.params.id){ + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + } + }else{ + if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1||req.params.id.indexOf('$')>-1){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + }else{ + res.end('[]'); + return; + } + } + if(!req.query.limit||req.query.limit==''){req.query.limit=50} + req.sql+=' ORDER BY `time` DESC LIMIT '+req.query.limit+''; + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(err){ + err.sql=req.sql; + res.end(s.s(err, null, 3)); + return + } + if(!r){r=[]} + r.forEach(function(v,n){ + r[n].info=JSON.parse(v.info) + }) + res.end(s.s(r, null, 3)); + }) + },res,req); +}); +// Get monitors online json +app.get('/:auth/smonitor/:ke', function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.fn=function(user){ + if(user.permissions.get_monitors==="0"){ + res.end(s.s([])) + return + } + req.sql='SELECT * FROM Monitors WHERE ke=?';req.ar=[req.params.ke]; + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + } + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(r&&r[0]){ + req.ar=[]; + r.forEach(function(v){ + if(s.group[req.params.ke]&&s.group[req.params.ke].mon[v.mid]&&s.group[req.params.ke].mon[v.mid].started===1){ + req.ar.push(v) + } + }) + }else{ + req.ar=[]; + } + res.end(s.s(req.ar, null, 3)); + }) + } + s.auth(req.params,req.fn,res,req); +}); +// Monitor Add,Edit,Delete +app.all(['/:auth/configureMonitor/:ke/:id','/:auth/configureMonitor/:ke/:id/:f'], function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(req.params.f!=='delete'){ + if(!req.body.data&&!req.query.data){ + req.ret.msg='No Monitor Data found.' + res.end(s.s(req.ret, null, 3)) + return + } + try{ + if(req.query.data){ + req.monitor=JSON.parse(req.query.data) + }else{ + req.monitor=JSON.parse(req.body.data) + } + }catch(er){ + if(!req.monitor){ + req.ret.msg=user.lang.monitorEditText1; + res.end(s.s(req.ret, null, 3)) + } + return + } + if(!user.details.sub||user.details.allmonitors==='1'||user.details.monitor_edit.indexOf(req.monitor.mid)>-1){ + if(req.monitor&&req.monitor.mid&&req.monitor.name){ + req.set=[],req.ar=[]; + req.monitor.mid=req.params.id.replace(/[^\w\s]/gi,'').replace(/ /g,''); + try{ + JSON.parse(req.monitor.details) + }catch(er){ + if(!req.monitor.details||!req.monitor.details.stream_type){ + req.ret.msg=user.lang.monitorEditText2; + res.end(s.s(req.ret, null, 3)) + return + }else{ + req.monitor.details=JSON.stringify(req.monitor.details) + } + } + req.monitor.ke=req.params.ke + req.logObject={details:JSON.parse(req.monitor.details),ke:req.params.ke,mid:req.params.id} + s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND mid=?',[req.monitor.ke,req.monitor.mid],function(er,r){ + req.tx={f:'monitor_edit',mid:req.monitor.mid,ke:req.monitor.ke,mon:req.monitor}; + if(r&&r[0]){ + req.tx.new=false; + Object.keys(req.monitor).forEach(function(v){ + if(req.monitor[v]&&req.monitor[v]!==''){ + req.set.push(v+'=?'),req.ar.push(req.monitor[v]); + } + }) + req.set=req.set.join(','); + req.ar.push(req.monitor.ke),req.ar.push(req.monitor.mid); + s.log(req.monitor,{type:'Monitor Updated',msg:'by user : '+user.uid}); + req.ret.msg=user.lang['Monitor Updated by user']+' : '+user.uid; + s.sqlQuery('UPDATE Monitors SET '+req.set+' WHERE ke=? AND mid=?',req.ar) + req.finish=1; + }else{ + if(!s.group[req.monitor.ke].init.max_camera||s.group[req.monitor.ke].init.max_camera==''||Object.keys(s.group[req.monitor.ke].mon).length <= parseInt(s.group[req.monitor.ke].init.max_camera)){ + req.tx.new=true; + req.st=[]; + Object.keys(req.monitor).forEach(function(v){ + if(req.monitor[v]&&req.monitor[v]!==''){ + req.set.push(v),req.st.push('?'),req.ar.push(req.monitor[v]); + } + }) + // req.set.push('ke'),req.st.push('?'),req.ar.push(req.monitor.ke); + req.set=req.set.join(','),req.st=req.st.join(','); + s.log(req.monitor,{type:'Monitor Added',msg:'by user : '+user.uid}); + req.ret.msg=user.lang['Monitor Added by user']+' : '+user.uid; + s.sqlQuery('INSERT INTO Monitors ('+req.set+') VALUES ('+req.st+')',req.ar) + req.finish=1; + }else{ + req.tx.f='monitor_edit_failed'; + req.tx.ff='max_reached'; + req.ret.msg=user.lang.monitorEditFailedMaxReached; + } + } + if(req.finish===1){ + req.monitor.details=JSON.parse(req.monitor.details) + req.ret.ok=true; + s.init(0,{mid:req.monitor.mid,ke:req.monitor.ke}); + s.group[req.monitor.ke].mon_conf[req.monitor.mid]=s.init('noReference',req.monitor); + if(req.monitor.mode==='stop'){ + s.camera('stop',req.monitor); + }else{ + s.camera('stop',req.monitor);setTimeout(function(){s.camera(req.monitor.mode,req.monitor);},5000) + }; + s.tx(req.tx,'STR_'+req.monitor.ke); + }; + s.tx(req.tx,'GRP_'+req.monitor.ke); + res.end(s.s(req.ret, null, 3)) + }) + }else{ + req.ret.msg=user.lang.monitorEditText1; + res.end(s.s(req.ret, null, 3)) + } + }else{ + req.ret.msg=user.lang['Not Permitted']; + res.end(s.s(req.ret, null, 3)) + } + }else{ + if(!user.details.sub||user.details.allmonitors==='1'||user.details.monitor_edit.indexOf(req.params.id)>-1){ + s.log(s.group[req.params.ke].mon_conf[req.params.id],{type:'Monitor Deleted',msg:'by user : '+user.uid}); + req.params.delete=1;s.camera('stop',req.params); + s.tx({f:'monitor_delete',uid:user.uid,mid:req.params.id,ke:req.params.ke},'GRP_'+req.params.ke); + s.sqlQuery('DELETE FROM Monitors WHERE ke=? AND mid=?',[req.params.ke,req.params.id]) + req.ret.ok=true; + req.ret.msg='Monitor Deleted by user : '+user.uid + res.end(s.s(req.ret, null, 3)) + } + } + }) +}) +app.get(['/:auth/monitor/:ke/:id/:f','/:auth/monitor/:ke/:id/:f/:ff','/:auth/monitor/:ke/:id/:f/:ff/:fff'], function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(user.permissions.control_monitors==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitor_edit.indexOf(req.params.id)===-1){ + res.end(user.lang['Not Permitted']) + return + } + if(req.params.f===''){req.ret.msg=user.lang.monitorGetText1;res.end(s.s(req.ret, null, 3));return} + if(req.params.f!=='stop'&&req.params.f!=='start'&&req.params.f!=='record'){ + req.ret.msg='Mode not recognized.'; + res.end(s.s(req.ret, null, 3)); + return; + } + s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND mid=?',[req.params.ke,req.params.id],function(err,r){ + if(r&&r[0]){ + r=r[0]; + if(req.query.reset==='1'||(s.group[r.ke]&&s.group[r.ke].mon_conf[r.mid].mode!==req.params.f)||req.query.fps&&(!s.group[r.ke].mon[r.mid].currentState||!s.group[r.ke].mon[r.mid].currentState.trigger_on)){ + if(req.query.reset!=='1'||!s.group[r.ke].mon[r.mid].trigger_timer){ + if(!s.group[r.ke].mon[r.mid].currentState)s.group[r.ke].mon[r.mid].currentState={} + s.group[r.ke].mon[r.mid].currentState.mode=r.mode.toString() + s.group[r.ke].mon[r.mid].currentState.fps=r.fps.toString() + if(!s.group[r.ke].mon[r.mid].currentState.trigger_on){ + s.group[r.ke].mon[r.mid].currentState.trigger_on=true + }else{ + s.group[r.ke].mon[r.mid].currentState.trigger_on=false + } + r.mode=req.params.f; + try{r.details=JSON.parse(r.details);}catch(er){} + if(req.query.fps){ + r.fps=parseFloat(r.details.detector_trigger_record_fps) + s.group[r.ke].mon[r.mid].currentState.detector_trigger_record_fps=r.fps + } + r.id=r.mid; + s.sqlQuery('UPDATE Monitors SET mode=? WHERE ke=? AND mid=?',[r.mode,r.ke,r.mid]); + s.group[r.ke].mon_conf[r.mid]=r; + s.tx({f:'monitor_edit',mid:r.mid,ke:r.ke,mon:r},'GRP_'+r.ke); + s.tx({f:'monitor_edit',mid:r.mid,ke:r.ke,mon:r},'STR_'+r.ke); + s.camera('stop',s.init('noReference',r)); + if(req.params.f!=='stop'){ + s.camera(req.params.f,s.init('noReference',r)); + } + req.ret.msg=user.lang['Monitor mode changed']+' : '+req.params.f; + }else{ + req.ret.msg=user.lang['Reset Timer']; + } + req.ret.cmd_at=s.formattedTime(new Date,'YYYY-MM-DD HH:mm:ss'); + req.ret.ok=true; + if(req.params.ff&&req.params.f!=='stop'){ + req.params.ff=parseFloat(req.params.ff); + clearTimeout(s.group[r.ke].mon[r.mid].trigger_timer) + switch(req.params.fff){ + case'day':case'days': + req.timeout=req.params.ff*1000*60*60*24 + break; + case'hr':case'hour':case'hours': + req.timeout=req.params.ff*1000*60*60 + break; + case'min':case'minute':case'minutes': + req.timeout=req.params.ff*1000*60 + break; + default://seconds + req.timeout=req.params.ff*1000 + break; + } + s.group[r.ke].mon[r.mid].trigger_timer=setTimeout(function(){ + delete(s.group[r.ke].mon[r.mid].trigger_timer) + s.sqlQuery('UPDATE Monitors SET mode=? WHERE ke=? AND mid=?',[s.group[r.ke].mon[r.mid].currentState.mode,r.ke,r.mid]); + r.neglectTriggerTimer=1; + r.mode=s.group[r.ke].mon[r.mid].currentState.mode; + r.fps=s.group[r.ke].mon[r.mid].currentState.fps; + s.camera('stop',s.init('noReference',r),function(){ + if(s.group[r.ke].mon[r.mid].currentState.mode!=='stop'){ + s.camera(s.group[r.ke].mon[r.mid].currentState.mode,s.init('noReference',r)); + } + s.group[r.ke].mon_conf[r.mid]=r; + }); + s.tx({f:'monitor_edit',mid:r.mid,ke:r.ke,mon:r},'GRP_'+r.ke); + s.tx({f:'monitor_edit',mid:r.mid,ke:r.ke,mon:r},'STR_'+r.ke); + },req.timeout); +// req.ret.end_at=s.formattedTime(new Date,'YYYY-MM-DD HH:mm:ss').add(req.timeout,'milliseconds'); + } + }else{ + req.ret.msg=user.lang['Monitor mode is already']+' : '+req.params.f; + } + }else{ + req.ret.msg=user.lang['Monitor or Key does not exist.']; + } + res.end(s.s(req.ret, null, 3)); + }) + },res,req); +}) +//get file from fileBin bin +app.get(['/:auth/fileBin/:ke','/:auth/fileBin/:ke/:id'],function (req,res){ + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.fn=function(user){ + req.sql='SELECT * FROM Files WHERE ke=?';req.ar=[req.params.ke]; + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + }else{ + if(req.params.id&&(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1)){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + } + } + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(!r){ + r=[] + }else{ + r.forEach(function(v){ + v.details=JSON.parse(v.details) + v.href='/'+req.params.auth+'/fileBin/'+req.params.ke+'/'+req.params.id+'/'+v.details.year+'/'+v.details.month+'/'+v.details.day+'/'+v.name; + }) + } + res.end(s.s(r, null, 3)); + }) + } + s.auth(req.params,req.fn,res,req); +}); +//get file from fileBin bin +app.get('/:auth/fileBin/:ke/:id/:year/:month/:day/:file', function (req,res){ + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.fn=function(user){ + req.failed=function(){ + res.end(user.lang['File Not Found']) + } + if (!s.group[req.params.ke].fileBin[req.params.id+'/'+req.params.file]){ + s.sqlQuery('SELECT * FROM Files WHERE ke=? AND mid=? AND name=?',[req.params.ke,req.params.id,req.params.file],function(err,r){ + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details) + req.dir=s.dir.fileBin+req.params.ke+'/'+req.params.id+'/'+r.details.year+'/'+r.details.month+'/'+r.details.day+'/'+req.params.file; + if(fs.existsSync(req.dir)){ + res.on('finish',function(){res.end();}); + fs.createReadStream(req.dir).pipe(res); + }else{ + req.failed() + } + }else{ + req.failed() + } + }) + }else{ + res.end(user.lang['Please Wait for Completion']) + } + } + s.auth(req.params,req.fn,res,req); +}); +// Get video file +app.get('/:auth/videos/:ke/:id/:file', function (req,res){ + s.auth(req.params,function(user){ + if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){ + res.end(user.lang['Not Permitted']) + return + } + var filename = s.nameToTime(req.params.file) + if(req.query.isUTC === 'true'){ + filename = s.utcToLocal(filename) + } + s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND mid=? AND time=?',[req.params.ke,req.params.id,filename],function(err,r){ + if(r&&r[0]){ + req.dir=s.video('getDir',r[0])+req.params.file + if (fs.existsSync(req.dir)){ + req.ext=req.params.file.split('.')[1]; + var total = fs.statSync(req.dir).size; + if (req.headers['range']) { + var range = req.headers.range; + var parts = range.replace(/bytes=/, "").split("-"); + var partialstart = parts[0]; + var partialend = parts[1]; + + var start = parseInt(partialstart, 10); + var end = partialend ? parseInt(partialend, 10) : total-1; + var chunksize = (end-start)+1; + var file = fs.createReadStream(req.dir, {start: start, end: end}); + req.headerWrite={ 'Content-Range': 'bytes ' + start + '-' + end + '/' + total, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize, 'Content-Type': 'video/'+req.ext } + req.writeCode=206 + } else { + req.headerWrite={ 'Content-Length': total, 'Content-Type': 'video/'+req.ext}; + var file=fs.createReadStream(req.dir) + req.writeCode=200 + } + if(req.query.downloadName){ + req.headerWrite['content-disposition']='attachment; filename="'+req.query.downloadName+'"'; + } + res.writeHead(req.writeCode,req.headerWrite); + file.on('close',function(){ + res.end(); + }) + file.pipe(res); + }else{ + res.end(user.lang['File Not Found in Filesystem']) + } + }else{ + res.end(user.lang['File Not Found in Database']) + } + }) + },res,req); +}); +//motion trigger +app.get('/:auth/motion/:ke/:id', function (req,res){ + s.auth(req.params,function(user){ + if(req.query.data){ + try{ + var d={id:req.params.id,ke:req.params.ke,details:JSON.parse(req.query.data)}; + }catch(err){ + res.end('Data Broken',err); + return; + } + }else{ + res.end('No Data'); + return; + } + if(!d.ke||!d.id||!s.group[d.ke]){ + res.end(user.lang['No Group with this key exists']); + return; + } + s.camera('motion',d,function(){ + res.end(user.lang['Trigger Successful']) + }); + },res,req); +}) +//hookTester trigger +app.get('/:auth/hookTester/:ke/:id', function (req,res){ + res.setHeader('Content-Type', 'application/json'); + s.auth(req.params,function(user){ + s.log(req.params,{type:'Test',msg:'Hook Test'}) + res.end(s.s({ok:true},null,3)) + },res,req); +}) +//control trigger +app.get('/:auth/control/:ke/:id/:direction', function (req,res){ + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + s.camera('control',req.params,function(resp){ + res.end(s.s(resp,null,3)) + }); + },res,req); +}) +//modify video file +app.get(['/:auth/videos/:ke/:id/:file/:mode','/:auth/videos/:ke/:id/:file/:mode/:f'], function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.video_delete.indexOf(req.params.id)===-1){ + res.end(user.lang['Not Permitted']) + return + } + var filename = s.nameToTime(req.params.file) + if(req.query.isUTC === 'true'){ + filename = s.utcToLocal(filename) + } + req.sql='SELECT * FROM Videos WHERE ke=? AND mid=? AND time=?'; + req.ar=[req.params.ke,req.params.id,filename]; + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(r&&r[0]){ + r=r[0];r.filename=s.formattedTime(r.time)+'.'+r.ext; + switch(req.params.mode){ + case'fix': + req.ret.ok=true; + s.video('fix',r) + break; + case'status': + req.params.f=parseInt(req.params.f) + if(isNaN(req.params.f)||req.params.f===0){ + req.ret.msg='Not a valid value.'; + }else{ + req.ret.ok=true; + s.sqlQuery('UPDATE Videos SET status=? WHERE ke=? AND mid=? AND time=?',[req.params.f,req.params.ke,req.params.id,filename]) + s.tx({f:'video_edit',status:req.params.f,filename:r.filename,mid:r.mid,ke:r.ke,time:s.nameToTime(r.filename),end:s.formattedTime(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+r.ke); + } + break; + case'delete': + req.ret.ok=true; + s.video('delete',r) + break; + default: + req.ret.msg=user.lang.modifyVideoText1; + break; + } + }else{ + req.ret.msg=user.lang['No such file']; + } + res.end(s.s(req.ret, null, 3)); + }) + },res,req); +}) +//ffmpeg pushed stream in here to make a pipe +app.all(['/streamIn/:ke/:id','/streamIn/:ke/:id/:feed'], function (req, res) { + var checkOrigin = function(search){return req.headers.host.indexOf(search)>-1} + if(checkOrigin('127.0.0.1')){ + if(!req.params.feed){req.params.feed='1'} + if(!s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed]){ + s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed] = new events.EventEmitter().setMaxListeners(0) + } + //req.params.feed = Feed Number + res.connection.setTimeout(0); + req.on('data', function(buffer){ + s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed].emit('data',buffer) + }); + req.on('end',function(){ +// console.log('streamIn closed',req.params); + }); + }else{ + res.end('Local connection is only allowed.') + } +}) +//MP4 Stream +app.get(['/:auth/mp4/:ke/:id/:channel/s.mp4','/:auth/mp4/:ke/:id/s.mp4','/:auth/mp4/:ke/:id/:channel/s.ts','/:auth/mp4/:ke/:id/s.ts'], function (req, res) { + s.auth(req.params,function(user){ + if(!s.group[req.params.ke] || !s.group[req.params.ke].mon[req.params.id]){ + res.status(404); + res.end('404 : Monitor not found'); + return + } + s.checkChildProxy(req.params,function(){ + var Channel = 'MAIN' + if(req.params.channel){ + Channel = parseInt(req.params.channel)+config.pipeAddition + } + var mp4frag = s.group[req.params.ke].mon[req.params.id].mp4frag[Channel]; + var errorMessage = 'MP4 Stream is not enabled' + if(!mp4frag){ + res.status(503); + res.end('503 : initialization : '+errorMessage); + }else{ + var init = mp4frag.initialization; + if (!init) { + res.status(503); + res.end('404 : Not Found : '+errorMessage); + } else { + res.locals.mp4frag = mp4frag + res.set('Access-Control-Allow-Origin', '*') + res.set('Connection', 'close') + res.set('Cache-Control', 'private, no-cache, no-store, must-revalidate') + res.set('Expires', '-1') + res.set('Pragma', 'no-cache') + res.set('Content-Type', 'video/mp4') + res.status(200); + res.write(init); + mp4frag.pipe(res); + res.on('close', () => { + mp4frag.unpipe(res); + }); + } + } + },res,req); + },res,req); +}); +//simulate RTSP over HTTP +app.get([ + '/:auth/mpegts/:ke/:id/:feed/:file', + '/:auth/mpegts/:ke/:id/:feed/', + '/:auth/h264/:ke/:id/:feed/:file', + '/:auth/h264/:ke/:id/:feed', + '/:auth/h264/:ke/:id' +], function (req, res) { + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + s.checkChildProxy(req.params,function(){ + if(!req.query.feed){req.query.feed='1'} + var Emitter + if(!req.params.feed){ + Emitter = s.group[req.params.ke].mon[req.params.id].streamIn[req.query.feed] + }else{ + Emitter = s.group[req.params.ke].mon[req.params.id].emitterChannel[parseInt(req.params.feed)+config.pipeAddition] + } + s.init('streamIn',req.params) + var contentWriter + var date = new Date(); + res.writeHead(200, { + 'Date': date.toUTCString(), + 'Connection': 'keep-alive', + 'Cache-Control': 'no-cache', + 'Pragma': 'no-cache', + 'Content-Type': 'video/mp4', + 'Server': 'Shinobi H.264 Test Stream', + }); + Emitter.on('data',contentWriter=function(buffer){ + res.write(buffer) + }) + res.on('close', function () { + Emitter.removeListener('data',contentWriter) + }) + },res,req); + },res,req); +}); +//FFprobe by API +app.get('/:auth/probe/:ke',function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + switch(req.query.action){ +// case'stop': +// exec('kill -9 '+user.ffprobe.pid,{detatched: true}) +// break; + default: + if(!req.query.url){ + req.ret.error = 'Missing URL' + res.end(s.s(req.ret, null, 3)); + return + } + if(user.ffprobe){ + req.ret.error = 'Account is already probing' + res.end(s.s(req.ret, null, 3)); + return + } + user.ffprobe=1; + if(req.query.flags==='default'){ + req.query.flags = '-v quiet -print_format json -show_format -show_streams' + }else{ + if(!req.query.flags){ + req.query.flags = '' + } + } + req.probeCommand = s.splitForFFPMEG(req.query.flags+' -i '+req.query.url).join(' ') + exec('ffprobe '+req.probeCommand+' | echo ',function(err,stdout,stderr){ + delete(user.ffprobe) + if(err){ + req.ret.error=(err) + }else{ + req.ret.ok=true + req.ret.result = stdout+stderr + } + req.ret.probe = req.probeCommand + res.end(s.s(req.ret, null, 3)); + }) + break; + } + },res,req); +}) +//ONVIF requesting with Shinobi API structure +app.all(['/:auth/onvif/:ke/:id/:action','/:auth/onvif/:ke/:id/:service/:action'],function (req,res){ + var response = {ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + var errorMessage = function(msg,error){ + response.ok = false + response.msg = msg + response.error = error + res.end(s.s(response,null,3)) + } + var actionCallback = function(onvifActionResponse){ + response.ok = true + if(onvifActionResponse.data){ + response.responseFromDevice = onvifActionResponse.data + }else{ + response.responseFromDevice = onvifActionResponse + } + if(onvifActionResponse.soap)response.soap = onvifActionResponse.soap + res.end(s.s(response,null,3)) + } + var isEmpty = function(obj) { + for(var key in obj) { + if(obj.hasOwnProperty(key)) + return false; + } + return true; + } + var doAction = function(Camera){ + var completeAction = function(command){ + if(command.then){ + command.then(actionCallback).catch(function(error){ + errorMessage('Device responded with an error',error) + }) + }else if(command){ + response.ok = true + response.repsonseFromDevice = command + res.end(s.s(response,null,3)) + }else{ + response.error = 'Big Errors, Please report it to Shinobi Development' + res.end(s.s(response,null,3)) + } + } + var action + if(req.params.service){ + if(Camera.services[req.params.service] === undefined){ + return errorMessage('This is not an available service. Please use one of the following : '+Object.keys(Camera.services).join(', ')) + } + if(Camera.services[req.params.service] === null){ + return errorMessage('This service is not activated. Maybe you are not connected through ONVIF. You can test by attempting to use the "Control" feature with ONVIF in Shinobi.') + } + action = Camera.services[req.params.service][req.params.action] + }else{ + action = Camera[req.params.action] + } + if(!action || typeof action !== 'function'){ + errorMessage(req.params.action+' is not an available ONVIF function. See https://github.com/futomi/node-onvif for functions.') + }else{ + var argNames = s.getFunctionParamNames(action) + var options + var command + if(argNames[0] === 'options' || argNames[0] === 'params'){ + options = {} + if(req.query.options){ + var jsonRevokedText = 'JSON not formated correctly' + try{ + options = JSON.parse(req.query.options) + }catch(err){ + return errorMessage(jsonRevokedText,err) + } + }else if(req.body.options){ + try{ + options = JSON.parse(req.body.options) + }catch(err){ + return errorMessage(jsonRevokedText,err) + } + }else if(req.query.params){ + try{ + options = JSON.parse(req.query.params) + }catch(err){ + return errorMessage(jsonRevokedText,err) + } + }else if(req.body.params){ + try{ + options = JSON.parse(req.body.params) + }catch(err){ + return errorMessage(jsonRevokedText,err) + } + } + } + if(req.params.service){ + command = Camera.services[req.params.service][req.params.action](options) + }else{ + command = Camera[req.params.action](options) + } + completeAction(command) + } + } + if(!s.group[req.params.ke].mon[req.params.id].onvifConnection){ + //prepeare onvif connection + var controlURL + var monitorConfig = s.group[req.params.ke].mon_conf[req.params.id] + if(!monitorConfig.details.control_base_url||monitorConfig.details.control_base_url===''){ + controlURL = s.init('url_no_path',monitorConfig) + }else{ + controlURL = monitorConfig.details.control_base_url + } + var controlURLOptions = s.camera('buildOptionsFromUrl',controlURL,monitorConfig) + //create onvif connection + s.group[req.params.ke].mon[req.params.id].onvifConnection = new onvif.OnvifDevice({ + xaddr : 'http://' + controlURLOptions.host + ':' + controlURLOptions.port + '/onvif/device_service', + user : controlURLOptions.username, + pass : controlURLOptions.password + }) + var device = s.group[req.params.ke].mon[req.params.id].onvifConnection + device.init().then((info) => { + if(info)doAction(device) + }).catch(function(error){ + return errorMessage('Device responded with an error',error) + }) + }else{ + doAction(s.group[req.params.ke].mon[req.params.id].onvifConnection) + } + },res,req); +}) +s.cpuUsage=function(e){ + k={} + switch(s.platform){ + case'win32': + k.cmd="@for /f \"skip=1\" %p in ('wmic cpu get loadpercentage') do @echo %p%" + break; + case'darwin': + k.cmd="ps -A -o %cpu | awk '{s+=$1} END {print s}'"; + break; + case'linux': + k.cmd='LANG=C top -b -n 2 | grep "^'+config.cpuUsageMarker+'" | awk \'{print $2}\' | tail -n1'; + break; + } + if(config.customCpuCommand){ + exec(config.customCpuCommand,{encoding:'utf8',detached: true},function(err,d){ + if(s.isWin===true) { + d = d.replace(/(\r\n|\n|\r)/gm, "").replace(/%/g, "") + } + e(d) + }); + } else if(k.cmd){ + exec(k.cmd,{encoding:'utf8',detached: true},function(err,d){ + if(s.isWin===true){ + d=d.replace(/(\r\n|\n|\r)/gm,"").replace(/%/g,"") + } + e(d) + }); + } else{ + e(0) + } +} +s.ramUsage=function(e){ + k={} + switch(s.platform){ + case'win32': + k.cmd = "wmic OS get FreePhysicalMemory /Value" + break; + case'darwin': + k.cmd = "vm_stat | awk '/^Pages free: /{f=substr($3,1,length($3)-1)} /^Pages active: /{a=substr($3,1,length($3-1))} /^Pages inactive: /{i=substr($3,1,length($3-1))} /^Pages speculative: /{s=substr($3,1,length($3-1))} /^Pages wired down: /{w=substr($4,1,length($4-1))} /^Pages occupied by compressor: /{c=substr($5,1,length($5-1)); print ((a+w)/(f+a+i+w+s+c))*100;}'" + break; + default: + k.cmd = "LANG=C free | grep Mem | awk '{print $4/$2 * 100.0}'"; + break; + } + if(k.cmd){ + exec(k.cmd,{encoding:'utf8',detached: true},function(err,d){ + if(s.isWin===true){ + d=(parseInt(d.split('=')[1])/(s.totalmem/1000))*100 + } + e(d) + }); + }else{ + e(0) + } +} +//check disk space every 20 minutes +if(config.autoDropCache===true){ + setInterval(function(){ + exec('echo 3 > /proc/sys/vm/drop_caches',{detached: true}) + },60000*20); +} +s.beat=function(){ + setTimeout(s.beat, 8000); + io.sockets.emit('ping',{beat:1}); +} +s.beat(); +s.processReady = function(){ + s.systemLog(lang.startUpText5) + process.send('ready') +} +//setup Master for childNodes +if(config.childNodes.enabled === true && config.childNodes.mode === 'master'){ + s.childNodes = {}; + var childNodeHTTP = express(); + var childNodeServer = http.createServer(app); + var childNodeWebsocket = new (require('socket.io'))() + childNodeServer.listen(config.childNodes.port,config.bindip,function(){ + console.log(lang.Shinobi+' - CHILD NODE PORT : '+config.childNodes.port); + }); + childNodeWebsocket.attach(childNodeServer); + //send data to child node function (experimental) + s.cx = function(z,y,x){if(!z.mid && !z.d){ + var err = new Error(); + console.log(err.stack); + };if(x){return x.broadcast.to(y).emit('c',z)};childNodeWebsocket.to(y).emit('c',z);} + //child Node Websocket + childNodeWebsocket.on('connection', function (cn) { + //functions for dispersing work to child servers; + cn.on('c',function(d){ + if(config.childNodes.key.indexOf(d.socketKey) > -1){ + if(!cn.shinobi_child&&d.f=='init'){ + cn.ip = cn.request.connection.remoteAddress.replace('::ffff:','')+':'+d.port + cn.shinobi_child = 1 + tx = function(z){ + cn.emit('c',z) + } + if(!s.childNodes[cn.ip]){ + s.childNodes[cn.ip] = {} + }; + s.childNodes[cn.ip].cnid = cn.id + s.childNodes[cn.ip].cpu = 0 + s.childNodes[cn.ip].activeCameras = {} + tx({ + f : 'init_success', + childNodes : s.childNodes + }); + }else{ + switch(d.f){ + case'cpu': + s.childNodes[cn.ip].cpu = d.cpu; + break; + case'sql': + s.sqlQuery(d.query,d.values,function(err,rows){ + cn.emit('c',{f:'sqlCallback',rows:rows,err:err,callbackId:d.callbackId}); + }); + break; + case'camera': + s.camera(d.mode,d.data) + break; + case's.tx': + s.tx(d.data,d.to) + break; + case's.log': + if(!d.mon || !d.data)return console.log('LOG DROPPED',d.mon,d.data); + s.log(d.mon,d.data) + break; + case'created_file_chunk': + if(!s.group[d.ke].mon[d.mid].childNodeStreamWriters[d.filename]){ + d.dir = s.video('getDir',s.group[d.ke].mon_conf[d.mid]) + s.group[d.ke].mon[d.mid].childNodeStreamWriters[d.filename] = fs.createWriteStream(d.dir+d.filename) + } + s.group[d.ke].mon[d.mid].childNodeStreamWriters[d.filename].write(d.chunk) + break; + case'created_file': + if(!s.group[d.ke].mon[d.mid].childNodeStreamWriters[d.filename]){ + return console.log('FILE NOT EXIST') + } + s.group[d.ke].mon[d.mid].childNodeStreamWriters[d.filename].end(); + tx({ + f:'delete', + file:d.filename, + ke:d.ke, + mid:d.mid + }); + s.txWithSubPermissions({ + f:'video_build_success', + hrefNoAuth:'/videos/'+d.ke+'/'+d.mid+'/'+d.filename, + filename:d.filename, + mid:d.mid, + ke:d.ke, + time:s.timeObject(d.startTime).format(), + size:d.filesize, + end:s.timeObject(d.endTime).format() + },'GRP_'+d.ke,'video_view'); + clearTimeout(s.group[d.ke].mon[d.mid].checker) + clearTimeout(s.group[d.ke].mon[d.mid].checkStream) + break; + } + } + } + }) + cn.on('disconnect',function(){ + if(s.childNodes[cn.ip]){ + var activeCameraKeys = Object.keys(s.childNodes[cn.ip].activeCameras) + activeCameraKeys.forEach(function(key){ + var monitor = s.childNodes[cn.ip].activeCameras[key] + s.camera('stop',s.init('noReference',monitor)) + delete(s.group[monitor.ke].mon[monitor.mid].childNode) + delete(s.group[monitor.ke].mon[monitor.mid].childNodeId) + setTimeout(function(){ + s.camera(monitor.mode,s.init('noReference',monitor)) + },1300) + }) + delete(s.childNodes[cn.ip]); + } + }) + }) +}else +//setup Child for childNodes +if(config.childNodes.enabled === true && config.childNodes.mode === 'child' && config.childNodes.host){ + s.connected = false; + childIO = require('socket.io-client')('ws://'+config.childNodes.host); + s.cx = function(x){x.socketKey = config.childNodes.key;childIO.emit('c',x)} + s.tx = function(x,y){s.cx({f:'s.tx',data:x,to:y})} + s.log = function(x,y){s.cx({f:'s.log',mon:x,data:y})} + s.queuedSqlCallbacks = {} + s.sqlQuery = function(query,values,onMoveOn){ + var callbackId = s.gid() + if(!values){values=[]} + if(typeof values === 'function'){ + var onMoveOn = values; + var values = []; + } + if(typeof onMoveOn !== 'function'){onMoveOn=function(){}} + s.queuedSqlCallbacks[callbackId] = onMoveOn + s.cx({f:'sql',query:query,values:values,callbackId:callbackId}); + } + setInterval(function(){ + s.cpuUsage(function(cpu){ + io.emit('c',{f:'cpu',cpu:parseFloat(cpu)}); + }) + },2000); + childIO.on('connect', function(d){ + console.log('CHILD CONNECTION SUCCESS') + s.cx({ + f : 'init', + port : config.port + }) + }) + childIO.on('c', function (d) { + switch(d.f){ + case'sqlCallback': + if(s.queuedSqlCallbacks[d.callbackId]){ + s.queuedSqlCallbacks[d.callbackId](d.err,d.rows) + delete(s.queuedSqlCallbacks[d.callbackId]) + } + break; + case'init_success': + s.connected=true; + s.other_helpers=d.child_helpers; + break; + case'kill': + s.init(0,d.d); + s.kill(s.group[d.d.ke].mon[d.d.id].spawn,d.d) + break; + case'sync': + s.init(0,d.sync); + Object.keys(d.sync).forEach(function(v){ + s.group[d.sync.ke].mon[d.sync.mid][v]=d.sync[v]; + }); + break; + case'delete'://delete video + s.file('delete',s.dir.videos+d.ke+'/'+d.mid+'/'+d.file) + break; + case'insertCompleted'://close video + s.video('insertCompleted',d.d,d.k) + break; + case'cameraStop'://start camera + s.camera('stop',d.d) + break; + case'cameraStart'://start or record camera + s.camera(d.mode,d.d) + break; + } + }) + childIO.on('disconnect',function(d){ + s.connected = false; + }) +} +if(config.childNodes.mode === 'child'){ + //child node - startup functions +// fs.readdir(s.dir.videos, function(err,groupKeys) { +// groupKeys.forEach(function(groupKey){ +// fs.readdir(s.dir.videos+groupKey, function(err,monitorIds) { +// monitorIds.forEach(function(monitorId){ +// fs.readdir(s.dir.videos+groupKey+'/'+monitorId, function(err,files) { +// files.forEach(function(file){ +// if(/T[0-9][0-9]-[0-9][0-9]-[0-9][0-9]./.test(file)){ +// var filePath = s.dir.videos+groupKey+'/'+monitorId+'/'+file +// var stat = fs.statSync(filePath) +// var filesize = stat.size +// var filesizeMB = parseFloat((filesize/1000000).toFixed(2)) +// var startTime = s.nameToTime(file) +// var endTime = s.formattedTime(stat.mtime,'YYYY-MM-DD HH:mm:ss') +// fs.createReadStream(filePath) +// .on('data',function(data){ +// s.cx({ +// f:'created_file_chunk', +// mid:monitorId, +// ke:groupKey, +// chunk:data, +// filename:file, +// filesize:filesize, +// time:s.timeObject(startTime).format(), +// end:s.timeObject(endTime).format() +// }) +// }) +// .on('close',function(){ +// s.cx({ +// f:'created_file', +// mid:monitorId, +// ke:groupKey, +// filename:file, +// filesize:filesize, +// time:s.timeObject(startTime).format(), +// end:s.timeObject(endTime).format() +// }) +// }) +// .on('error',function(){ +// console.log('File Read Error',file) +// }); +// }else{ +// console.log('Not Video',file) +// } +// }) +// }) +// }) +// }) +// }) +// }) +}else{ + //master node - startup functions + setInterval(function(){ + s.cpuUsage(function(cpu){ + s.ramUsage(function(ram){ + s.tx({f:'os',cpu:cpu,ram:ram},'CPU'); + }) + }) + },10000); + setTimeout(function(){ + //get current disk used for each isolated account (admin user) on startup + s.sqlQuery('SELECT * FROM Users WHERE details NOT LIKE ?',['%"sub"%'],function(err,r){ + if(r&&r[0]){ + var count = r.length + var countFinished = 0 + r.forEach(function(v,n){ + v.size=0; + v.limit=JSON.parse(v.details).size + s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND status!=?',[v.ke,0],function(err,rr){ + ++countFinished + if(r&&r[0]){ + rr.forEach(function(b){ + v.size+=b.size + }) + } + s.systemLog(v.mail+' : '+lang.startUpText0+' : '+rr.length,v.size) + s.init('group',v) + s.systemLog(v.mail+' : '+lang.startUpText1,countFinished+'/'+count) + if(countFinished===count){ + s.systemLog(lang.startUpText4) + //preliminary monitor start + s.sqlQuery('SELECT * FROM Monitors', function(err,r) { + if(err){s.systemLog(err)} + if(r&&r[0]){ + r.forEach(function(v){ + s.init(0,v); + r.ar={}; + r.ar.id=v.mid; + Object.keys(v).forEach(function(b){ + r.ar[b]=v[b]; + }) + if(!s.group[v.ke]){ + s.group[v.ke]={} + s.group[v.ke].mon_conf={} + } + v.details=JSON.parse(v.details); + s.group[v.ke].mon_conf[v.mid]=v; + s.camera(v.mode,r.ar); + }); + } + s.processReady() + }); + } + }) + }) + }else{ + s.processReady() + } + }) + },1500) +} \ No newline at end of file diff --git a/conf.sample.json b/conf.sample.json new file mode 100644 index 0000000..e24865c --- /dev/null +++ b/conf.sample.json @@ -0,0 +1,28 @@ +{ + "port": 8080, + "addStorage": [ + {"name":"second","path":"__DIR__/videos2"} + ], + "db": { + "host": "127.0.0.1", + "user": "majesticflame", + "password": "", + "database": "ccio", + "port":3306 + }, + "mail":{ + "service": "gmail", + "auth": { + "user": "your_email@gmail.com", + "pass": "your_password_or_app_specific_password" + } + }, + "cron":{ + "key":"change_this_to_something_very_random__just_anything_other_than_this" + }, + "pluginKeys":{ + "Motion":"change_this_to_something_very_random____make_sure_to_match__/plugins/motion/conf.json", + "OpenCV":"change_this_to_something_very_random____make_sure_to_match__/plugins/opencv/conf.json", + "OpenALPR":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi" + } +} \ No newline at end of file diff --git a/cron.js b/cron.js new file mode 100644 index 0000000..ea98d8a --- /dev/null +++ b/cron.js @@ -0,0 +1,518 @@ +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +var fs = require('fs'); +var path = require('path'); +var knex = require('knex'); +var moment = require('moment'); +var exec = require('child_process').exec; +var spawn = require('child_process').spawn; +var config=require('./conf.json'); + +//set option defaults +s={ + utcOffset : moment().utcOffset() +}; +if(config.cron===undefined)config.cron={}; +if(config.cron.deleteOld===undefined)config.cron.deleteOld=true; +if(config.cron.deleteOrphans===undefined)config.cron.deleteOrphans=false; +if(config.cron.deleteNoVideo===undefined)config.cron.deleteNoVideo=true; +if(config.cron.deleteNoVideoRecursion===undefined)config.cron.deleteNoVideoRecursion=false; +if(config.cron.deleteOverMax===undefined)config.cron.deleteOverMax=true; +if(config.cron.deleteLogs===undefined)config.cron.deleteLogs=true; +if(config.cron.deleteEvents===undefined)config.cron.deleteEvents=true; +if(config.cron.deleteFileBins===undefined)config.cron.deleteFileBins=true; +if(config.cron.interval===undefined)config.cron.interval=1; +if(config.databaseType===undefined){config.databaseType='mysql'} +if(config.databaseLogs===undefined){config.databaseLogs=false} +if(config.useUTC===undefined){config.useUTC=false} + +if(!config.ip||config.ip===''||config.ip.indexOf('0.0.0.0')>-1)config.ip='localhost'; +if(!config.videosDir)config.videosDir=__dirname+'/videos/'; +if(!config.binDir){config.binDir=__dirname+'/fileBin/'} +if(!config.addStorage){config.addStorage=[]} + +// Database Connection +var databaseOptions = { + client: config.databaseType, + connection: config.db, +} +if(databaseOptions.client.indexOf('sqlite')>-1){ + databaseOptions.client = 'sqlite3'; + databaseOptions.useNullAsDefault = true; +} +if(databaseOptions.client === 'sqlite3' && databaseOptions.connection.filename === undefined){ + databaseOptions.connection.filename = __dirname+"/shinobi.sqlite" +} +s.databaseEngine = knex(databaseOptions) +s.sqlDate = function(value){ + var dateQueryFunction = '' + if(databaseOptions.client === 'sqlite3'){ + value = value.toLowerCase() + if (value.slice(-1) !== 's') { + value = value+'s' + } + dateQueryFunction = "datetime('now', '-"+value+"')" + }else{ + value = value.toUpperCase() + if (value.slice(-1) === 'S') { + value = value.slice(0, -1); + } + dateQueryFunction = "DATE_SUB(NOW(), INTERVAL "+value+")" + } + return dateQueryFunction +} +s.sqlQuery = function(query,values,onMoveOn,hideLog){ + if(!values){values=[]} + var valuesNotFunction = true; + if(typeof values === 'function'){ + var onMoveOn = values; + var values = []; + valuesNotFunction = false; + } + if(!onMoveOn){onMoveOn=function(){}} + if(values&&valuesNotFunction){ + var splitQuery = query.split('?') + var newQuery = '' + splitQuery.forEach(function(v,n){ + newQuery += v + if(values[n]){ + if(isNaN(values[n])){ + newQuery += "'"+values[n]+"'" + }else{ + newQuery += values[n] + } + } + }) + }else{ + newQuery = query + } + return s.databaseEngine.raw(newQuery) + .asCallback(function(err,r){ + if(err&&config.databaseLogs){ + s.systemLog('s.sqlQuery QUERY',query) + s.systemLog('s.sqlQuery ERROR',err) + } + if(onMoveOn) + if(typeof onMoveOn === 'function'){ + switch(databaseOptions.client){ + case'sqlite3': + if(!r)r=[] + break; + default: + if(r)r=r[0] + break; + } + onMoveOn(err,r) + }else{ + console.log(onMoveOn) + } + }) +} + +//containers +s.overlapLock={}; +s.alreadyDeletedRowsWithNoVideosOnStart={}; +//functions +s.checkCorrectPathEnding=function(x){ + var length=x.length + if(x.charAt(length-1)!=='/'){ + x=x+'/' + } + return x.replace('__DIR__',__dirname) +} +s.dir={ + videos:s.checkCorrectPathEnding(config.videosDir), + fileBin:s.checkCorrectPathEnding(config.binDir), + addStorage:config.addStorage, +}; +s.moment=function(e,x){ + if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'}; + return moment(e).format(x); +} +s.utcToLocal = function(time){ + return moment.utc(time).utcOffset(s.utcOffset).format() +} +s.localToUtc = function(time){ + return moment(time).utc() +} +s.nameToTime=function(x){x=x.replace('.webm','').replace('.mp4','').split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;} +io = require('socket.io-client')('ws://'+config.ip+':'+config.port);//connect to master +s.cx=function(x){x.cronKey=config.cron.key;return io.emit('cron',x)} +//emulate master socket emitter +s.tx=function(x,y){s.cx({f:'s.tx',data:x,to:y})} +s.video=function(x,y){s.cx({f:'s.video',data:x,file:y})} +//Cron Job +s.cx({f:'init',time:moment()}) +s.getVideoDirectory=function(e){ + if(e.mid&&!e.id){e.id=e.mid}; + if(e.details&&(e.details instanceof Object)===false){ + try{e.details=JSON.parse(e.details)}catch(err){} + } + if(e.details.dir&&e.details.dir!==''){ + return s.checkCorrectPathEnding(e.details.dir)+e.ke+'/'+e.id+'/' + }else{ + return s.dir.videos+e.ke+'/'+e.id+'/'; + } +} +s.getFileBinDirectory=function(e){ + if(e.mid&&!e.id){e.id=e.mid}; + return s.dir.fileBin+e.ke+'/'+e.id+'/'; +} +//filters set by the user in their dashboard +//deleting old videos is part of the filter - config.cron.deleteOld +s.checkFilterRules=function(v,callback){ + //filters + if(!v.d.filters||v.d.filters==''){ + v.d.filters={}; + } + //delete old videos with filter + if(config.cron.deleteOld===true){ + v.d.filters.deleteOldByCron={ + "id":"deleteOldByCron", + "name":"deleteOldByCron", + "sort_by":"time", + "sort_by_direction":"ASC", + "limit":"", + "enabled":"1", + "archive":"0", + "email":"0", + "delete":"1", + "execute":"", + "where":[{ + "p1":"end", + "p2":"<", + "p3":s.sqlDate(v.d.days+" DAYS"), + "p3_type":"function", + }] + }; + } + var keys = Object.keys(v.d.filters) + if(keys.length>0){ + keys.forEach(function(m,current){ + var b=v.d.filters[m]; + if(b.enabled==="1"){ + b.ar=[v.ke]; + b.sql=[]; + b.where.forEach(function(j,k){ + if(j.p1==='ke'){j.p3=v.ke} + switch(j.p3_type){ + case'function': + b.sql.push(j.p1+' '+j.p2+' '+j.p3) + break; + default: + b.sql.push(j.p1+' '+j.p2+' ?') + b.ar.push(j.p3) + break; + } + }) + b.sql='WHERE ke=? AND status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND ('+b.sql.join(' AND ')+')'; + if(b.sort_by&&b.sort_by!==''){ + b.sql+=' ORDER BY `'+b.sort_by+'` '+b.sort_by_direction + } + if(b.limit&&b.limit!==''){ + b.sql+=' LIMIT '+b.limit + } + s.sqlQuery('SELECT * FROM Videos '+b.sql,b.ar,function(err,r){ + if(r&&r[0]){ + b.cx={ + f:'filters', + name:b.name, + videos:r, + time:moment(), + ke:v.ke, + id:b.id + }; + if(b.archive==="1"){ + s.cx({f:'filters',ff:'archive',videos:r,time:moment(),ke:v.ke,id:b.id}); + }else{ + if(b.delete==="1"){ + s.cx({f:'filters',ff:'delete',videos:r,time:moment(),ke:v.ke,id:b.id}); + } + } + if(b.email==="1"){ + b.cx.ff='email'; + b.cx.delete=b.delete; + b.cx.mail=v.mail; + b.cx.execute=b.execute; + b.cx.query=b.sql; + s.cx(b.cx); + } + if(b.execute&&b.execute!==""){ + s.cx({f:'filters',ff:'execute',execute:b.execute,time:moment()}); + } + } + }) + + } + if(current===keys.length-1){ + //last filter + callback() + } + }) + }else{ + //no filters + callback() + } +} +//database rows with no videos in the filesystem +s.deleteRowsWithNoVideo=function(v,callback){ + if( + config.cron.deleteNoVideo===true&&( + config.cron.deleteNoVideoRecursion===true|| + (config.cron.deleteNoVideoRecursion===false&&!s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]) + ) + ){ + s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]=true; + es={}; + s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND status!=0 AND details NOT LIKE \'%"archived":"1"%\' AND time < '+s.sqlDate('10 MINUTE'),[v.ke],function(err,evs){ + if(evs&&evs[0]){ + es.del=[];es.ar=[v.ke]; + evs.forEach(function(ev){ + var details = JSON.parse(ev.details) + var filename = ev.time + var dir = s.getVideoDirectory(ev)+s.moment(filename)+'.'+ev.ext; + var fileExists = fs.existsSync(dir) + if(details.isUTC === true){ + filename = s.localToUtc(filename).format('YYYY-MM-DDTHH-mm-ss') + dir = s.getVideoDirectory(ev)+filename+'.'+ev.ext; + fileExists = fs.existsSync(dir) + } + if(fileExists !== true){ + s.video('delete',ev) + s.tx({f:'video_delete',filename:filename+'.'+ev.ext,mid:ev.mid,ke:ev.ke,time:ev.time,end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+ev.ke); + } + }); + if(es.del.length>0){ + s.cx({f:'deleteNoVideo',msg:es.del.length+' SQL rows with no file deleted',ke:v.ke,time:moment()}) + } + } + setTimeout(function(){ + callback() + },3000) + }) + }else{ + callback() + } +} +//info about what the application is doing +s.deleteOldLogs=function(v,callback){ + if(!v.d.log_days||v.d.log_days==''){v.d.log_days=10}else{v.d.log_days=parseFloat(v.d.log_days)}; + if(config.cron.deleteLogs===true&&v.d.log_days!==0){ + s.sqlQuery("DELETE FROM Logs WHERE ke=? AND `time` < "+s.sqlDate('? DAYS'),[v.ke,v.d.log_days],function(err,rrr){ + callback() + if(err)return console.error(err); + if(rrr.affectedRows && rrr.affectedRows.length>0){ + s.cx({f:'deleteLogs',msg:rrr.affectedRows+' SQL rows older than '+v.d.log_days+' days deleted',ke:v.ke,time:moment()}) + } + }) + }else{ + callback() + } +} +//events - motion, object, etc. detections +s.deleteOldEvents=function(v,callback){ + if(!v.d.event_days||v.d.event_days==''){v.d.event_days=10}else{v.d.event_days=parseFloat(v.d.event_days)}; + if(config.cron.deleteEvents===true&&v.d.event_days!==0){ + s.sqlQuery("DELETE FROM Events WHERE ke=? AND `time` < "+s.sqlDate('? DAYS'),[v.ke,v.d.event_days],function(err,rrr){ + callback() + if(err)return console.error(err); + if(rrr.affectedRows && rrr.affectedRows.length>0){ + s.cx({f:'deleteEvents',msg:rrr.affectedRows+' SQL rows older than '+v.d.event_days+' days deleted',ke:v.ke,time:moment()}) + } + }) + }else{ + callback() + } +} +//check for temporary files (special archive) +s.deleteOldFileBins=function(v,callback){ + if(!v.d.fileBin_days||v.d.fileBin_days==''){v.d.fileBin_days=10}else{v.d.fileBin_days=parseFloat(v.d.fileBin_days)}; + if(config.cron.deleteFileBins===true&&v.d.fileBin_days!==0){ + var fileBinQuery = " FROM Files WHERE ke=? AND `date` < "+s.sqlDate('? DAYS'); + s.sqlQuery("SELECT *"+fileBinQuery,[v.ke,v.d.fileBin_days],function(err,files){ + if(files&&files[0]){ + //delete the files + files.forEach(function(file){ + fs.unlink(s.getFileBinDirectory(file)+file.name,function(err){ +// if(err)console.error(err) + }) + }) + //delete the database rows + s.sqlQuery("DELETE"+fileBinQuery,[v.ke,v.d.fileBin_days],function(err,rrr){ + callback() + if(err)return console.error(err); + if(rrr.affectedRows && rrr.affectedRows.length>0){ + s.cx({f:'deleteFileBins',msg:rrr.affectedRows+' files older than '+v.d.fileBin_days+' days deleted',ke:v.ke,time:moment()}) + } + }) + }else{ + callback() + } + }) + }else{ + callback() + } +} +//check for files with no database row +s.checkForOrphanedFiles=function(v,callback){ + if(config.cron.deleteOrphans===true){ + var finish=function(count){ + if(count>0){ + s.cx({f:'deleteOrphanedFiles',msg:count+' SQL rows with no database row deleted',ke:v.ke,time:moment()}) + } + callback() + } + e={}; + var numberOfItems = 0; + s.sqlQuery('SELECT * FROM Monitors WHERE ke=?',[v.ke],function(arr,b) { + if(b&&b[0]){ + b.forEach(function(mon,m){ + fs.readdir(s.getVideoDirectory(mon), function(err, items) { + e.query=[]; + e.filesFound=[mon.ke,mon.mid]; + numberOfItems+=items.length; + if(items&&items.length>0){ + items.forEach(function(v,n){ + e.query.push('time=?') + e.filesFound.push(s.nameToTime(v)) + }) + s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND mid=? AND ('+e.query.join(' OR ')+')',e.filesFound,function(arr,r) { + if(!r){r=[]}; + e.foundSQLrows=[]; + r.forEach(function(v,n){ + v.index=e.filesFound.indexOf(s.moment(v.time,'YYYY-MM-DD HH:mm:ss')); + if(v.index>-1){ + delete(items[v.index-2]); + } + }); + items.forEach(function(v,n){ + if(v&&v!==null){ + exec('rm '+s.getVideoDirectory(mon)+v); + } + if(m===b.length-1&&n===items.length-1){ + finish(numberOfItems) + } + }) + }) + }else{ + if(m===b.length-1){ + finish(numberOfItems) + } + } + }) + }); + }else{ + finish(numberOfItems) + } + }); + }else{ + callback() + } +} +//user processing function +s.processUser = function(number,rows){ + var v = rows[number]; + if(!v){ + //no user object given + return + } + console.log(v) + if(!s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]){ + s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]=false; + } + if(!s.overlapLock[v.ke]){ + // set overlap lock + s.overlapLock[v.ke]=true; + //set permissions + v.d=JSON.parse(v.details); + //size + if(!v.d.size||v.d.size==''){v.d.size=10000}else{v.d.size=parseFloat(v.d.size)}; + //days to keep videos + if(!v.d.days||v.d.days==''){v.d.days=5}else{v.d.days=parseFloat(v.d.days)}; + s.sqlQuery('SELECT * FROM Monitors WHERE ke=?', [v.ke], function(err,rr) { + if(!v.d.filters||v.d.filters==''){ + v.d.filters={}; + } + rr.forEach(function(b,m){ + b.details=JSON.parse(b.details); + if(b.details.max_keep_days&&b.details.max_keep_days!==''){ + v.d.filters['deleteOldByCron'+b.mid]={ + "id":'deleteOldByCron'+b.mid, + "name":'deleteOldByCron'+b.mid, + "sort_by":"time", + "sort_by_direction":"ASC", + "limit":"", + "enabled":"1", + "archive":"0", + "email":"0", + "delete":"1", + "execute":"", + "where":[{ + "p1":"ke", + "p2":"=", + "p3":b.mid + },{ + "p1":"end", + "p2":"<", + "p3":s.sqlDate(b.details.max_keep_days+" DAYS"), + "p3_type":"function", + }] + }; + } + }) + s.deleteOldLogs(v,function(){ + console.log('deleteOldLogs') + s.deleteOldFileBins(v,function(){ + console.log('deleteOldFileBins') + s.deleteOldEvents(v,function(){ + console.log('deleteOldEvents') + s.checkFilterRules(v,function(){ + console.log('checkFilterRules') + s.deleteRowsWithNoVideo(v,function(){ + console.log('deleteRowsWithNoVideo') + s.checkForOrphanedFiles(v,function(){ + //done user, unlock current, and do next + s.overlapLock[v.ke]=false; + s.processUser(number+1,rows) + }) + }) + }) + }) + }) + }) + }) + }else{ + s.processUser(number+1,rows) + } +} +//recursive function +s.cron=function(){ + x={}; + s.cx({f:'start',time:moment()}) + s.sqlQuery('SELECT ke,uid,details,mail FROM Users WHERE details NOT LIKE \'%"sub"%\'', function(err,rows) { + if(err){ + console.error(err) + } + if(rows&&rows[0]){ + s.processUser(0,rows) + } + }) + s.timeout=setTimeout(function(){ + s.cron(); + },parseFloat(config.cron.interval)*60000*60) +} +s.cron(); +//socket commander +io.on('f',function(d){ + switch(d.f){ + case'start':case'restart': + clearTimeout(s.timeout); + s.cron(); + break; + case'stop': + clearTimeout(s.timeout); + break; + } +}) +console.log('Shinobi : cron.js started') \ No newline at end of file diff --git a/definitions/en_CA.json b/definitions/en_CA.json new file mode 100644 index 0000000..223b35e --- /dev/null +++ b/definitions/en_CA.json @@ -0,0 +1,1192 @@ +{ + "Monitor Settings": { + "section": "Monitor Settings", + "blocks": { + "Identity": { + "name": "Identity", + "color": "", + "info": [ + { + "name": "mode", + "field": "Mode", + "description": "This is the primary task of the monitor.", + "default": "Disabled", + "example": "", + "possible": [ + { + "name": "Disabled", + "info": "Inactive monitor, no process will be created in this mode." + }, + { + "name": "Watch-Only", + "info": "Monitor will only stream, no recording will occur unless otherwise ordered by API or Detector." + }, + { + "name": "Record", + "info": "Continuous Recording. Segments are made every 15 minutes by default." + } + ] + }, + { + "name": "mid", + "field": "Monitor ID", + "description": "This is a non-changeable identifier for the monitor. You can duplicate a monitor by double clicking the Monitor ID and changing it.", + "default": "Provided by Server", + "example": "awFST99MGn", + "possible": "" + }, + { + "name": "name", + "field": "Name", + "description": "This is the human-readable display name for the monitor.", + "default": "", + "example": "Bunny", + "possible": "" + }, + { + "name": "detail=fatal_max", + "field": "Retry Connection", + "description": "The number of times to retry for network connection between the server and camera before setting the monitor to Disabled. No decimals. Set to 0 to retry forever.", + "default": "10", + "example": "100000", + "possible": "" + }, + { + "name": "detail=notes", + "field": "Notes", + "description": "Comments you want to leave for this camera.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=dir", + "field": "Storage Location", + "description": "Location of where recorded files will be saved. You can configure more locations with the addStorage variable.", + "default": "", + "example": "", + "possible": "" + } + ] + }, + "Input": { + "name": "Input", + "color": "forestgreen", + "info": [ + { + "name": "type", + "field": "Input Type", + "description": "The method that will used to consume the video stream.", + "default": "JPEG", + "example": "", + "possible": [ + { + "name": "JPEG", + "info": "Reading snapshots from a URL and making a stream and/or video from them." + }, + { + "name": "MJPEG", + "info": "Similar to JPEG except the frame handling is done by FFMPEG, not Shinobi." + }, + { + "name": "H.264", + "info": "Reading a high quality video streas that sometimes include audio." + }, + { + "name": "Local", + "info": "Reading Capture Cards, Webcams, or Integrated Cameras." + }, + { + "name": "Shinobi Streamer", + "info": "Continuous Recording. Segments are made every 15 minutes by default." + } + ] + }, + { + "name": "detail=auto_host_enable", + "field": "Automatic", + "description": "Feed the individual pieces required to build a stream URL or provide the full URL and allow Shinobi to parse it for you.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=auto_host", + "field": "Full URL Path", + "description": "The full Stream URL.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=accelerator", + "field": "Accelerator", + "description": "Hardware Acceleration (HWAccel) for decoding streams.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "protocol", + "field": "Connection Type", + "description": "The protocol that will used to consume the video stream.", + "default": "HTTP", + "example": "", + "possible": [ + { + "name": "HTTP", + "info": "Standard connection method." + }, + { + "name": "HTTPS", + "info": "Standard connection method with SSL." + }, + { + "name": "RTSP", + "info": "Real Time Streaming Protocol" + }, + { + "name": "UDP", + "info": "Near restrictionless data transfer method." + } + ] + }, + { + "name": "detail=muser", + "field": "Username", + "description": "The user login for your camera", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=mpass", + "field": "Password", + "description": "The password for your camera", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "host", + "field": "Host", + "description": "Connection address", + "default": "", + "example": "111.111.111.111", + "possible": "" + }, + { + "name": "port", + "field": "Port", + "description": "Port number that your camera is streaming out on.", + "default": "80", + "example": "554", + "possible": "1-65535" + }, + { + "name": "detail=port_force", + "field": "Force Port", + "description": "Using the default web port can allow automatic switch to other ports for streams like RTSP.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "path", + "field": "Path", + "description": "The path to your camera", + "default": "", + "example": "/video.h264", + "possible": "" + }, + { + "name": "detail=aduration", + "field": "Analyzation Duration", + "description": "Specify how many microseconds are analyzed to probe the input. Set to 100000 if you are using RTSP and having stream issues.", + "default": "", + "example": "100000", + "possible": "" + }, + { + "name": "detail=probesize", + "field": "Probe Size", + "description": "Specify how big to make the analyzation probe for the input. Set to 100000 if you are using RTSP and having stream issues.", + "default": "", + "example": "100000", + "possible": "" + }, + { + "name": "detail=rtsp_transport", + "field": "RTSP Transport", + "description": "The transport protocol your camera will use. TCP is usually the best choice.", + "default": "", + "example": "", + "possible": [ + { + "name": "Auto", + "info": "Let FFMPEG decide. Normally it will try UDP first." + }, + { + "name": "TCP", + "info": "Set it to this if UDP starts giving undesired results." + }, + { + "name": "UDP", + "info": "FFMPEG tries this first." + }, + { + "name": "HTTP", + "info": "Standard connection method." + } + ] + } + ] + }, + "Stream": { + "name": "Stream", + "color": "blue", + "info": [ + { + "name": "detail=stream_type", + "field": "Stream Type", + "description": "The method that will used to consume the video stream.", + "default": "HLS", + "example": "", + "possible": [ + { + "name": "MJPEG", + "info": "Standard Motion JPEG image. No audio." + }, + { + "name": "HLS", + "info": "Similar method to facebook live streams. Includes audio if input provides it. There is a delay of about 4-6 seconds because this method records segments then pushes them to the client rather than push as while it creates them." + }, + { + "name": "Base64", + "info": "Sending Base64 encoded frames over WebSocket. This avoids caching but there is no audio." + }, + { + "name": "FLV", + "info": "Sending FLV encoded frames over WebSocket." + }, + { + "name": "kVid", + "info": "Using Kevin Godell's custom JavaScript MP4 segmenting engine." + } + ] + }, + { + "name": "detail=signal_check", + "field": "Check Signal Interval", + "description": "How often your client will check each stream to see if it is alive. This is calculated in minutes.", + "default": "10", + "example": "", + "possible": "" + }, + { + "name": "detail=stream_flv_type", + "field": "FLV Stream Type", + "description": "The method you will view your FLV stream. Both methods are always active for each stream regardless of your viewing choice for the Shinobi Dashboard.", + "default": "10", + "example": "", + "possible": "" + }, + { + "name": "detail=signal_check_log", + "field": "Log Signal Event", + "description": "This is for the client side only. It will display in the log thread when client side signal checks occur.", + "default": "No", + "example": "", + "possible": [ + { + "name": "No", + "info": "No signal check." + }, + { + "name": "Yes", + "info": "Check signal based on the number of minutes provided." + } + ] + }, + { + "name": "detail=stream_quality", + "field": "Quality", + "description": "Low number means higher quality. Higher number means less quality.", + "default": "15", + "example": "1", + "possible": "1-23" + }, + { + "name": "detail=stream_fps", + "field": "Rate (FPS)", + "description": "The speed in which frames are displayed to clients, in Frames Per Second. Be aware there is no default. This can lead to high bandwidth usage.", + "default": "", + "example": "1", + "possible": "" + }, + { + "name": "height", + "field": "Height", + "description": "Height of the stream image.", + "default": "640", + "example": "1280", + "possible": "" + }, + { + "name": "width", + "field": "Width", + "description": "Width of the stream image.", + "default": "480", + "example": "720", + "possible": "" + }, + { + "name": "detail=svf", + "field": "Video Filter", + "description": "Place FFMPEG video filters in this box to affect the streaming portion. No spaces.", + "default": "", + "example": "", + "possible": "" + } + ] + }, + "Stream - HLS": { + "name": "Stream - HLS", + "color": "blue", + "info": [ + { + "name": "detail=stream_vcodec", + "field": "Video Codec", + "description": "Video codec for streaming.", + "default": "copy", + "example": "", + "possible": [ + { + "name": "Default", + "info": "Let Shinobi choose." + }, + { + "name": "Auto", + "info": "Let FFMPEG choose." + }, + { + "name": "libvpx", + "info": "Used for WebM video." + }, + { + "name": "libvpx-vp9", + "info": "Used for WebM video." + }, + { + "name": "libx264", + "info": "Used for MP4 video." + }, + { + "name": "libx265", + "info": "Used for MP4 video." + }, + { + "name": "copy", + "info": "Used for MP4 video. Has very low CPU usage but cannot use video filters and filesizes may be gigantic. Best to setup your MP4 settings camera-side when using this option." + } + ] + }, + { + "name": "detail=stream_acodec", + "field": "Audio Codec", + "description": "Audio codec for streaming.", + "default": "No Audio", + "example": "", + "possible": [ + { + "name": "Default", + "info": "Let Shinobi choose." + }, + { + "name": "Auto", + "info": "Let FFMPEG choose." + }, + { + "name": "No Audio", + "info": "No Audio, this is an option that must be set in some parts of the world due to legal reasons." + }, + { + "name": "libvorbis", + "info": "Used for WebM video." + }, + { + "name": "libopus", + "info": "Used for WebM video." + }, + { + "name": "libmp3lame", + "info": "Used for MP4 video." + }, + { + "name": "aac", + "info": "Used for MP4 video." + }, + { + "name": "ac3", + "info": "Used for MP4 video." + }, + { + "name": "copy", + "info": "Used for MP4 video. Has very low CPU usage but some audio codecs need custom flags like -strict 2 for aac." + } + ] + }, + { + "name": "detail=hls_time", + "field": "HLS Segment Length", + "description": "How long each video segment should be, in minutes. Each segment will be drawn by the client through an m3u8 file. Shorter segments take less space.", + "default": "2", + "example": "3", + "possible": "" + }, + { + "name": "detail=hls_list_size", + "field": "HLS List Size", + "description": "The number of segments maximum before deleting old segments automatically.", + "default": "2", + "example": "3", + "possible": "" + }, + { + "name": "detail=preset_stream", + "field": "HLS Preset", + "description": "Preset flag for certain video encoders. If you find your camera is crashing every few seconds : try leaving it blank.", + "default": "", + "example": "ultrafast", + "possible": "" + }, + { + "name": "detail=stream_scale_x", + "field": "Width", + "description": "Width of the stream image.", + "default": "640", + "example": "640", + "possible": "" + }, + { + "name": "detail=stream_scale_y", + "field": "Height", + "description": "Height of the stream image.", + "default": "480", + "example": "480", + "possible": "" + }, + { + "name": "detail=tv_channel", + "field": "TV Channel", + "description": "This monitor will have TV Channel features enabled. You will be able to view it in your TV Channel list.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=tv_channel_id", + "field": "TV Channel ID", + "description": "A Custom ID for the Channel.", + "default": "", + "example": "", + "possible": "" + } + ] + }, + "Recording": { + "name": "Recording", + "color": "red", + "info": [ + { + "name": "ext", + "field": "Record File Type", + "description": "The file type for your recorded video file.", + "default": "MP4", + "example": "", + "possible": [ + { + "name": "MP4", + "info": "This file type is playable is almost all modern web browsers, that includes mobile. The filesize just tends to be larger unless you lower the quality." + }, + { + "name": "WebM", + "info": "Small filesize, low client compatibility. Good for uploading to sites like YouTube." + } + ] + }, + { + "name": "detail=vcodec", + "field": "Video Codec", + "description": "Video codec for recording.", + "default": "copy", + "example": "", + "possible": [ + { + "name": "Default", + "info": "Let Shinobi choose." + }, + { + "name": "Auto", + "info": "Let FFMPEG choose." + }, + { + "name": "libvpx", + "info": "Used for WebM video." + }, + { + "name": "libvpx-vp9", + "info": "Used for WebM video." + }, + { + "name": "libx264", + "info": "Used for MP4 video." + }, + { + "name": "libx265", + "info": "Used for MP4 video." + }, + { + "name": "copy", + "info": "Used for MP4 video. Has very low CPU usage but cannot use video filters and filesizes may be gigantic. Best to setup your MP4 settings camera-side when using this option." + } + ] + }, + { + "name": "detail=acodec", + "field": "Audio Codec", + "description": "Audio codec for recording.", + "default": "No Audio", + "example": "", + "possible": [ + { + "name": "Default", + "info": "Let Shinobi choose." + }, + { + "name": "Auto", + "info": "Let FFMPEG choose." + }, + { + "name": "No Audio", + "info": "No Audio, this is an option that must be set in some parts of the world due to legal reasons." + }, + { + "name": "libvorbis", + "info": "Used for WebM video." + }, + { + "name": "libopus", + "info": "Used for WebM video." + }, + { + "name": "libmp3lame", + "info": "Used for MP4 video." + }, + { + "name": "aac", + "info": "Used for MP4 video." + }, + { + "name": "ac3", + "info": "Used for MP4 video." + }, + { + "name": "copy", + "info": "Used for MP4 video. Has very low CPU usage but some audio codecs need custom flags like -strict 2 for aac." + } + ] + }, + { + "name": "crf", + "field": "Quality", + "description": "Low number means higher quality. Higher number means less quality.", + "default": "15", + "example": "1", + "possible": "1-23" + }, + { + "name": "preset_record", + "field": "Preset", + "description": "Preset flag for certain video encoders. If you find your camera is crashing every few seconds : try leaving it blank.", + "default": "", + "example": "ultrafast", + "possible": "" + }, + { + "name": "fps", + "field": "Video Record Rate (FPS)", + "description": "The speed in which frames are recorded to files, Frames Per Second. Be aware there is no default. This can lead to large files. Best to set this camera-side.", + "default": "", + "example": "2", + "possible": "" + }, + { + "name": "height", + "field": "Record Height", + "description": "Height of the stream image.", + "default": "640", + "example": "1280", + "possible": "" + }, + { + "name": "width", + "field": "Record Width", + "description": "Width of the stream image.", + "default": "480", + "example": "720", + "possible": "" + }, + { + "name": "detail=cutoff", + "field": "Recording Segment Interval", + "description": "In minutes. When to slice off and start a new video file.", + "default": "15", + "example": "60", + "possible": "" + }, + { + "name": "detail=dqf", + "field": "Double Quote Directory", + "description": "Some directories have spaces depending on how you setup your OS.", + "default": "No", + "example": "", + "possible": [ + { + "name": "No", + "info": "No is the default." + }, + { + "name": "Yes", + "info": "Using this may crash some cameras." + } + ] + }, + { + "name": "detail=vf", + "field": "Record Video Filter", + "description": "Place FFMPEG video filters in this box to affect the recording portion. No spaces.", + "default": "", + "example": "", + "possible": "" + } + ] + }, + "Timestamp": { + "name": "Timestamp", + "color": "red", + "info": [ + { + "name": "detail=timestamp_font", + "field": "Font Path", + "description": "Font File to style your timestamp.", + "default": "/usr/share/fonts/truetype/freefont/FreeSans.ttf", + "example": "", + "possible": "" + }, + { + "name": "detail=timestamp_font_size", + "field": "Font Size", + "description": "Font size in pt.", + "default": "10", + "example": "", + "possible": "" + }, + { + "name": "detail=timestamp_color", + "field": "Text Color", + "description": "Timstamp text color.", + "default": "white", + "example": "", + "possible": "" + }, + { + "name": "detail=timestamp_box_color", + "field": "Text Box Color", + "description": "Timstamp backdrop color.", + "default": "0x00000000@1", + "example": "", + "possible": "" + }, + { + "name": "detail=timestamp_x", + "field": "Position X", + "description": "Horiztonal Position of Timestamp", + "default": "(w-tw)/2", + "example": "", + "possible": "" + }, + { + "name": "detail=timestamp_y", + "field": "Position Y", + "description": "Vertical Position of Timestamp", + "default": "0", + "example": "", + "possible": "" + } + ] + }, + "Detector": { + "name": "Detector", + "color": "orange", + "info": [ + { + "name": "detail=detector", + "field": "Enabled", + "description": "This will add another output in the FFMPEG command for the motion detector. A detector plugin must be connected for this to have any effect.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_pam", + "field": "Use Built-In", + "description": "Use Kevin Godell's Motion Detector. This is built into Shinobi and requires no other configuration to activate.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_trigger", + "field": "Trigger Record", + "description": "This will order the camera to record if it is set to \"Watch-Only\" when a motion even is detected.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_timeout", + "field": "Recording Timeout", + "description": "The length of time \"Trigger Record\" will run for. This is read in minutes.", + "default": "10", + "example": "", + "possible": "" + }, + { + "name": "detail=watchdog_reset", + "field": "Timeout Reset on Next Event", + "description": "If there is an overlap in trigger record should it reset.", + "default": "No", + "example": "1", + "possible": [ + { + "name": "No", + "info": "Finish the current 10 minute order.." + }, + { + "name": "Yes", + "info": "Reset the timer" + } + ] + }, + { + "name": "detail=detector_save", + "field": "Save Events to SQL", + "description": "Save Motion Events in SQL. This will allow display of motion over video during the time motion events occured in the Power Viewer.", + "default": "Yes", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_send_frames", + "field": "Send Frames", + "description": "Push frames to the connected plugin to be analyzed.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_frame_save", + "field": "Save Frames to Events", + "description": "Save frames to the event row in the database as a base64 string. Enabling this can drain performance.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_mail", + "field": "Email on Trigger", + "description": "Recieve an email of an image during a motion event to the master account for the camera group. You must setup SMTP details in conf.json.", + "default": "No", + "example": "1", + "possible": [ + { + "name": "No", + "info": "Finish the current 10 minute order." + }, + { + "name": "Yes", + "info": "Reset the timer" + } + ] + }, + { + "name": "detail=detector_mail_timeout", + "field": "Allow Next Email", + "description": "The amount of time until a trigger is allowed to send another email with motion details and another image.", + "default": "10", + "example": "0.5", + "possible": "" + }, + { + "name": "detail=detector_fps", + "field": "Detector Rate (FPS)", + "description": "How many frames a second to send to the motion detector; 1 is the default.", + "default": "1", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_scale_x", + "field": "Feed-in Image Width", + "description": "Width of the image being detected. Smaller sizes take less CPU.", + "default": "", + "example": "640", + "possible": "" + }, + { + "name": "detail=detector_scale_y", + "field": "Feed-in Image Height", + "description": "Height of the image being detected. Smaller sizes take less CPU.", + "default": "", + "example": "480", + "possible": "" + }, + { + "name": "detail=detector_frame", + "field": "Full Frame Detection", + "description": "This will read the entire frame for pixel differences.", + "default": "Yes", + "example": "", + "possible": [ + { + "name": "No", + "info": "Makes motion detector do nothing if regions are not specified. Which is a stupid option to have if motion detection is on. One day we will remove this option." + }, + { + "name": "Yes", + "info": "Read entire frame." + } + ] + }, + { + "name": "detail=detector_sensitivity", + "field": "Indifference", + "description": "How much Shinobi doesn't care about motion before doing something. The opposite of sensitivity; a lower number means it will trigger sooner. The value ranges up to 15(+) decimal places. 10 is default, 0.005 is pretty sensitive to motion changes. Note: If using Region Editor, leave this blank, and set indifference in the Region Editor (below).", + "default": "10", + "example": "10", + "possible": "" + }, + { + "name": "detail=detector_webhook", + "field": "Webhook", + "description": "Send a GET request to a URL with some values from the event.", + "default":"No", + "example": "", + "possible":"" + }, + { + "name": "detail=detector_command_enable", + "field": "Detector Command", + "description": "You may use this to trigger a script on command.", + "default": "No", + "example": "", + "possible": [ + { + "name": "No", + "info": "No script will run." + }, + { + "name": "Yes", + "info": "Trigger the script that is set in the Command option. Command is only visible when selecting this option." + } + ] + }, + { + "name": "detail=detector_command", + "field": "Command", + "description": "The command that will run. This is the equivalent of running a shell command from terminal.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_command_timeout", + "field": "Allow Next Command", + "description": "This value is a timer to allow the next running of your script. This value is in minutes.", + "default": "10", + "example": "0.1", + "possible": "Any number." + } + ] + }, + "\"No Motion\" Detector": { + "name": "\"No Motion\" Detector", + "color": "orange", + "info": [ + { + "name": "detail=detector_notrigger_mail", + "field": "Email on \"No Motion\"", + "description": "If motion has not been detected after the timeout period you will recieve an email.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_notrigger_timeout", + "field": "Timeout", + "description": "Timeout is calculated in minutes.", + "default": "1", + "example": "", + "possible": "" + } + ] + }, + "Custom": { + "name": "Custom", + "color": "navy", + "info": [ + { + "name": "detail=cust_input", + "field": "Input Flags", + "description": "Custom Flags that bind to the Input of the FFMPEG process.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=cust_snap", + "field": "Snapshot Flags", + "description": "Custom Flags that bind to the Snapshots.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=cust_detect", + "field": "Detector Flags", + "description": "Custom Flags that bind to the stream Detector uses for analyzation.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=cust_stream", + "field": "Stream Flags", + "description": "Custom Flags that bind to the Stream (client side view) of the FFMPEG process.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=cust_record", + "field": "Recording Flags", + "description": "Custom Flags that bind to the recording of the FFMPEG process.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=custom_output", + "field": "Output Method", + "description": "Add a custom output like JPEG frames or send data straight to another server.", + "default": "", + "example": "", + "possible": "" + } + ] + }, + "Logging": { + "name": "Logging", + "color": "green", + "info": [ + { + "name": "detail=loglevel", + "field": "Log Level", + "description": "The amount of data to provide while doing the job.", + "default": "No", + "example": "", + "possible": [ + { + "name": "Silent", + "info": "None. This will silence all logging." + }, + { + "name": "Fatal", + "info": "Display only fatal errors." + }, + { + "name": "On Error", + "info": "Display all important errors. Note : this doesn't always show important information." + }, + { + "name": "All Warnings", + "info": "Display all warnings. Use this if you can't find out what's wrong with your camera." + }, + { + "name": "Debug", + "info": "Show all information FFMPEG can provide on STDERR while doing the job." + } + ] + }, + { + "name": "detail=sqllog", + "field": "Save Log in SQL", + "description": "Use this with caution as FFMPEG likes to throw up superfluous data at times which can lead to a lot of database rows.", + "default": "No", + "example": "", + "possible": [ + { + "name": "No", + "info": "No is the default." + }, + { + "name": "Yes", + "info": "Do this if you are having recurring issues only." + } + ] + } + ] + } + } + }, + "Account Settings": { + "section": "Account Settings", + "blocks": { + "Profile": { + "name": "Profile", + "color": "grey", + "info": [ + { + "name": "mail", + "field": "Email", + "description": "The login for accounts. The main account holder's email address will get notifications.", + "default": "", + "example": "ccio@m03.ca", + "possible": "Email compliant string." + }, + { + "name": "pass", + "field": "Password", + "description": "Leave blank to keep the same password during settings modification.", + "default": "", + "example": "ccio@m03.ca", + "possible": "" + }, + { + "name": "detail=size", + "field": "Max Storage Amount", + "description": "The amount max space Shinobi will allow to be consumed before purging. This value is read in megabytes.", + "default": "10000", + "example": "600000", + "possible": "Up to 95% of your maximum storage space if only one master account exists." + }, + { + "name": "detail=days", + "field": "Number of Days to keep Videos", + "description": "The number of days to keep videos before purging.", + "default": "7", + "example": "30", + "possible": "" + }, + { + "name": "detail=event_days", + "field": "Number of Days to keep Events", + "description": "The number of days to keep events before purging.", + "default": "7", + "example": "30", + "possible": "" + }, + { + "name": "detail=log_days", + "field": "Number of Days to keep Logs", + "description": "The number of days to keep logs before purging.", + "default": "7", + "example": "30", + "possible": "" + } + ] + }, + "Monitor Groups": { + "name": "Monitor Groups", + "color": "blue", + "info": [ + { + "field": "Groups", + "description": "The list of groups you have created.", + "default": "", + "example": "", + "possible": "" + }, + { + "field": "Group Name", + "description": "Name of selected group.", + "default": "", + "example": "", + "possible": "" + } + ] + }, + "WebDAV": { + "name": "WebDAV", + "color": "forestgreen", + "info": [ + { + "name": "detail=webdav_url", + "field": "URL", + "description": "The connection URL for your WebDAV server.", + "default": "", + "example": "http://owncloud.server/remote.php/webdav/", + "possible": "" + }, + { + "name": "detail=webdav_user", + "field": "Username", + "description": "The username required to access this server.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=webdav_pass", + "field": "Password", + "description": "The password required to access this server.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=webdav_save", + "field": "Autosave", + "description": "Whether or not the server should auto upload videos as they are finished.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=webdav_dir", + "field": "Save Directory", + "description": "The directory where videos will be saved.", + "default": "/", + "example": "/videos", + "possible": "" + } + ] + }, + "Custom Styles": { + "name": "Custom Styles", + "color": "navy", + "info": [ + { + "name": "detail=css", + "field": "CSS", + "description": "Add custom colors to your dashboard. This field should only be used by advanced users.", + "default": "", + "example": "", + "possible": "" + } + ] + } + } + } +} diff --git a/languages/ar.json b/languages/ar.json new file mode 100644 index 0000000..a1f3fef --- /dev/null +++ b/languages/ar.json @@ -0,0 +1,497 @@ +{ + "\"No Motion\" Detector": "\"لا الحركة\" كاشف", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "180 Degrees": "180 درجة", + "2-Factor Authentication": "2-عامل التوثيق", + "90 Clockwise": "90 اتجاه عقارب الساعة", + "90 Clockwise and Vertical Flip": "90 اتجاه عقارب الساعة العمودي الوجه", + "90 Counter Clockwise and Vertical Flip (default)": "90 عكس اتجاه عقارب الساعة و انعكاس عمودي (الافتراضي)", + "API": "API", + "API Key Added": "مفتاح API وأضاف", + "API Key Deleted": "مفتاح API حذف", + "API Keys": "مفاتيح API", + "APIKeyAddedText": "يمكنك استخدام هذا المفتاح الآن.", + "APIKeyDeletedText": "تم حذف مفتاح. وسوف لم يعد يعمل.", + "ASC": "ASC", + "Account Info": "معلومات الحساب", + "AccountEditText1": "لا يمكن تحريرها. تحديث الصفحة إذا كانت المشكلة لا تزال.", + "Accounts": "حسابات", + "Action for Selected": "العمل المحدد", + "Add": "إضافة", + "Add Monitor": "إضافة مراقبة", + "Add New": "إضافة جديدة", + "Admin": "المشرف", + "Advanced": "المتقدمة", + "Again": "مرة أخرى", + "All Monitors": "جميع الشاشات", + "All Monitors and Privileges": "جميع شاشات والامتيازات", + "All Warnings": "كل التحذيرات", + "Allow Next Command": "تسمح الأمر التالي في دقائق", + "Allow Next Email": "تسمح المقبل البريد الإلكتروني في غضون دقائق", + "Allow Next Trigger": "تسمح الزناد التالي في ميلي ثانية", + "Allowed IPs": "يسمح IPs", + "Analyzation Duration": "Analyzation مدة", + "Archive": "أرشيف", + "Audio Codec": "ترميز الصوت", + "Authenticate": "المصادقة", + "Auto": "السيارات", + "Autosave": "الحفظ التلقائي", + "Base64 over Websocket": "Base64 على Websocket", + "Bottom Left": "أسفل اليسار", + "Bottom Right": "أسفل اليمين", + "Browser Console Log": "المتصفح سجل وحدة", + "CPU": "وحدة المعالجة المركزية", + "CPU indicator will not work. Continuing...": "وحدة المعالجة المركزية المؤشر لا يعمل. استمرار...", + "CSS": "CSS أسلوب لوحة القيادة الخاصة بك.", + "Calendar": "التقويم", + "Camera Password": "كاميرا المرور", + "Camera Username": "الكاميرا المستخدم", + "Camera is not recording": "الكاميرا ليست تسجيل", + "CameraNotRecordingText": "الإعدادات قد تكون غير متوافقة. التحقق من الترميز. إعادة تشغيل...", + "Can Control Monitors": "يمكن التحكم في الشاشات", + "Can Delete Videos": "يمكن حذف الفيديو", + "Can Delete Videos and Events": "يمكن حذف الفيديو و الأحداث", + "Can Edit Monitor": "يمكن تحرير رصد", + "Can Get Logs": "يمكن الحصول على سجلات", + "Can Get Monitors": "يمكن الحصول على شاشات", + "Can View Monitor": "يمكن عرض الشاشة", + "Can View Snapshots": "يمكن عرض لقطات", + "Can View Streams": "يمكن عرض الجداول", + "Can View Videos": "يمكن عرض الفيديو", + "Can View Videos and Events": "يمكن عرض أشرطة الفيديو والأحداث", + "Can't Connect": "لا يمكن الاتصال", + "Center": "مركز عنوان URL", + "Chat on Discord": "الدردشة على الفتنة", + "Check": "تحقق", + "Check Signal Interval": "التحقق من إشارة الفاصل الزمني في دقائق", + "Check for Motion First": "تحقق من الحركة الأولى", + "Close": "قريب", + "Closed": "مغلقة", + "Command": "الأمر", + "Command on Trigger": "القيادة على الزناد", + "Complete Stream URL": "كاملة تيار URL", + "Confirm": "تأكيد", + "Connected": "متصل", + "Connection Type": "نوع الاتصال", + "Control": "التحكم", + "Control Error": "السيطرة على خطأ", + "ControlErrorText1": "لم يتم تمكين التحكم", + "Controllable": "يمكن السيطرة عليها", + "Country of Plates": "البلد من لوحات", + "Counts of Motion": "تهم الحركة", + "Current": "الحالي", + "Currently viewing": "حاليا عرض", + "Custom": "مخصص", + "Custom Base URL": "العرف قاعدة URL ترك فارغا لاستخدام المضيف URL", + "DB Lost.. Retrying..": "قاعدة البيانات المفقودة.. إعادة المحاولة..", + "DESC": "DESC", + "Dashboard": "لوحة القيادة", + "Dashboard Language": "لوحة أجهزة القياس في اللغة", + "Dashcam": "Dashcam", + "Dashcam (Streamer v2)": "Dashcam (غاسل v2)", + "Date Range": "نطاق التاريخ", + "Debug": "التصحيح", + "Default": "الافتراضي", + "Delete": "حذف", + "Delete Filter": "حذف الفلتر", + "Delete Matches": "حذف المباريات", + "Delete Monitor": "حذف رصد", + "Delete Motionless Video": "حذف حراك الفيديو", + "Delete Motionless Videos (Record)": "حذف حراك الفيديو (رقم قياسي)", + "Delete Selected Videos": "حذف الفيديو المختار", + "Delete Video": "حذف الفيديو", + "Delete selected": "حذف المحدد", + "DeleteMonitorText": "هل تريد حذف هذا العرض ؟ لا يمكنك استرداد. ملفات هذه الهوية ستبقى في نظام الملفات. إذا اخترت إعادة رصد مع نفس معرف الفيديو و أحداث سوف تصبح مرئية في لوحة القيادة.", + "DeleteSelectedVideosMsg": "هل تريد حذف هذا الفيديو ؟ لا يمكنك استرداد.", + "DeleteVideoMsg": "هل تريد حذف هذا الفيديو ؟ لا يمكنك استرداد.", + "Deleted": "حذف", + "Detect Objects": "الكشف عن الكائنات انظر أدناه", + "Detector": "كاشف", + "Detector Flags": "كشف أعلام", + "Detector Rate": "للكشف عن معدل (FPS)", + "DetectorText": "

عندما المربعات عرض وارتفاع ترد عليك أن مجموعة منهم إلى 640 × 480 أو أقل. هذا وسوف تحسين سرعة القراءة من الإطارات.

", + "Disable Night Vision": "تعطيل للرؤية الليلية عنوان URL", + "Disable Nightvision": "تعطيل رؤية ليلية", + "Disabled": "تعطيل", + "Documentation": "الوثائق", + "Don't show this anymore": "لا تظهر هذا بعد الآن", + "Double Quote Directory": "اقتباس مزدوجة الدليل بعض الدلائل التي تحتوي على مسافات. باستخدام هذا قد يتلف بعض الكاميرات.", + "Down": "أسفل عنوان URL", + "Down Stop": "أسفل وقف عنوان URL", + "Download": "تحميل", + "EU": "الاتحاد الأوروبي", + "Edit": "تحرير", + "Email": "البريد الإلكتروني", + "Email Details": "البريد الإلكتروني التفاصيل", + "Email on No Motion": "البريد الإلكتروني على \"لا الحركة\"", + "Email on Trigger": "البريد الإلكتروني على الزناد رسائل البريد الإلكتروني الذهاب إلى الحساب الرئيسي حامل عنوان تسجيل الدخول.", + "Enable Night Vision": "تمكين الرؤية الليلية عنوان URL", + "Enable Nightvision": "تمكن رؤية ليلية", + "Enabled": "تمكين", + "End": "نهاية", + "End Time": "نهاية الوقت", + "Ended": "انتهت", + "Enlarge": "تكبير", + "Enter this code to proceed": "أدخل هذا الرمز إلى المضي قدما", + "Equal to": "يساوي", + "Error Connecting": "حدث خطأ أثناء الاتصال", + "Event": "الحدث", + "Event Limit": "الحدث الحد", + "EventText1": "أثار الحدث الحركة في", + "EventText2": "لا يمكن أن البريد الإلكتروني صورة الملف لا يمكن الوصول إليها", + "Events": "الأحداث", + "Example": "على سبيل المثال", + "Execute Command": "تنفيذ الأوامر", + "Executed": "أعدم", + "Export": "التصدير", + "FFmpegCantStart": "FFmpeg لم تبدأ", + "FFmpegCantStartText": "تسجيل محرك هذه الكاميرا لا يمكن أن تبدأ. قد يكون هناك شيء خاطئ مع الكاميرا التكوين. إذا كان هناك أي سجلات أخرى من هذا واحد يرجى نشرها في القضايا على جيثب.", + "FFmpegTip": "FFprobe بسيط تيارات متعددة الوسائط محلل. يمكنك استخدامه لانتاج جميع أنواع المعلومات حول المدخلات بما في ذلك مدة, معدل الإطار, حجم الإطار ، إلخ.", + "FFprobe": "التحقيق", + "FactorAuthText1": "كود سوف يكون نشطا فقط لمدة 15 دقيقة. إذا كنت تسجيل الدخول مرة أخرى الموقت سيتم إعادة تعيين إلى 15 دقيقة مع نفس القانون.", + "Fatal": "قاتلة", + "Fatal Maximum Reached": "قاتلة الأقصى التوصل إلى وقف الكاميرا.", + "FatalMaximumReachedText": "JPEG كان خطأ فادح.", + "Feed-in Image Height": "تغذية في ارتفاع الصورة", + "Feed-in Image Width": "تغذية في صورة العرض", + "Fields cannot be empty": "المجالات لا يمكن أن تكون فارغة", + "File Not Exist": "الملف غير موجود", + "File Not Found": "لم يتم العثور على الملف", + "File Type": "نوع الملف", + "FileNotExistText": "لا يمكن حفظ غير متوفرة. شيء ذهب على نحو خاطئ.", + "Filename": "اسم الملف", + "Filesize": "حجم الملف", + "Filter ID": "تصفية معرف", + "Filter Matches": "تصفية المباريات", + "Filter Name": "اسم عامل التصفية", + "FilterMatchesText1": "هذا الفلتر قد استوفت الشروط.", + "FilterMatchesText2": "أشرطة الفيديو وجدت.", + "Filters": "المرشحات", + "Filters Updated": "مرشحات تحديث", + "FiltersUpdatedText": "التغييرات التي تم حفظها وتطبيقها.", + "Find Where": "تجد فيها", + "Fix": "Fix", + "Fix Video": "إصلاح الفيديو", + "FixVideoMsg": "هل تريد إصلاح هذا الفيديو ؟ لا يمكن التراجع عن هذا الإجراء.", + "Font Path": "مسار الخط", + "Font Size": "حجم الخط", + "Force Port": "القوة ميناء", + "Found Devices": "وجدت الأجهزة", + "Frame Rate": "معدل الإطار (FPS)", + "Full Frame Detection": "الإطار الكامل الكشف", + "Fullscreen": "ملء الشاشة", + "Greater Than": "أكبر من", + "Greater Than or Equal to": "أكبر من أو يساوي", + "Group Key": "المجموعة الرئيسية", + "Group Name": "اسم المجموعة", + "Grouping": "تجمع ", + "H.264 / H.265 / H.265+": "H. 264 / H. 265 / H. 265 ", + "HLS (.m3u8)": "HLS (.m3u8)", + "HLS (includes Audio)": "HLS (ويشمل الصوت)", + "HLS Audio Encoder": "HLS ترميز الصوت", + "HLS List Size": "HLS قائمة الحجم", + "HLS Preset": "HLS مسبقا", + "HLS Segment Length": "HLS قطعة طول في ثواني", + "HLS Video Encoder": "HLS ترميز الفيديو", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "Height": "ارتفاع", + "Help": "مساعدة", + "Hide List": "إخفاء قائمة", + "Hide Notes": "إخفاء الملاحظات", + "Host": "المضيف", + "Hotswap Modes (Watch-Only)": "Hotswap وسائط (مشاهدة فقط)", + "How to Record": "كيفية تسجيل", + "IP Address": "عنوان IP", + "Identity": "الهوية", + "IdentityText1": "هذا هو كيف نظام تحديد البيانات عن هذا التيار. لا يمكنك تغيير الشاشة معرف بمجرد الضغط على حفظ. إذا كنت تريد أن تجعل الشاشة معرف المزيد الإنسان للقراءة قبل المتابعة.", + "IdentityText2": "يمكنك تكرار رصد بتعديل رصد الهوية ثم الضغط على حفظ. هل يمكن استخدام معرف جهاز موجود بالفعل أو أنه سيوفر أكثر من أن الشاشة معلومات قاعدة البيانات.", + "Idle": "الخمول", + "Image Height": "ارتفاع الصورة", + "Image Location": "صورة موقع المسار المطلق أو ترك فارغا لاستخدام العالمية", + "Image Position": "صورة الموقف", + "Image Width": "صورة العرض", + "Import": "استيراد", + "Import Monitor Configuration": "استيراد رصد التكوين", + "ImportMonitorConfigurationText": "عند القيام بذلك سوف overrwrite أي تغييرات في الوقت الراهن لم يتم حفظها. التغييرات المستوردة تطبق فقط عند الضغط على حفظ.", + "In": "في", + "Incorrect Settings Chosen": "إعدادات غير صحيحة المختار", + "Indifference": "اللامبالاة", + "Input": "المدخلات", + "Input Flags": "إدخال الأعلام", + "Input Type": "نوع الإدخال", + "InputText1": "هذا المقطع يحكي شينوبي كيفية تستهلك تيار. للحصول على الأداء الأمثل محاولة ضبط الكاميرا الإعدادات الداخلية. العثور على الخيارات التالية ومجموعة منهم كما هو مبين. العثور على الكاميرا الخاصة بك يمكنك استخدام بنيت في ONVIF الماسح الضوئي من شينوبي. بعض كاميرات ONVIF تتطلب استخدام أداة إدارة إلى تعديل الإعدادات الداخلية. إذا كنت لا يمكن العثور على الكاميرات الخاصة بك يمكنك محاولة ONVIF مدير جهاز ويندوز.", + "InputText2": "
  • فراميراتي (FPS) : : 10 - 15 إطارا في الثانية ، منخفض : 2-5 إطارا في الثانية
  • I-الإطار الزمني : 80
  • نوع معدل بت : CBR (ثابت معدل بت)
  • معدل بت : بين 256kbps - 500kbps
", + "InputText3": "إذا كنت بحاجة إلى مساعدة في معرفة ما هو إدخال نوع الكاميرا الخاصة بك يمكنك أن تأخذ نظرة في الكاميرا عناوين قائمة على شينوبي الموقع.", + "Invalid JSON": "صالح سلمان", + "InvalidJSONText": "يرجى التأكد من هذا هو صالح سلمان سلسلة شينوبي رصد التكوين.", + "JPEG": "JPEG", + "JPEG (Auto Enables JPEG API)": "JPEG (السيارات تمكن JPEG API)", + "JPEG API": "JPEG API لقطة (cgi-bin)", + "JPEG Error": "JPEG خطأ", + "JPEG Mode": "وضع JPEG", + "JPEGErrorText": "كان هناك مشكلة في الحصول على البيانات من الكاميرا الخاصة بك.", + "Leave blank for random.": "ترك فارغا عشوائية.", + "Left": "ترك عنوان URL", + "Left Stop": "غادر وقف عنوان URL", + "Less Than": "أقل من", + "Less Than or Equal to": "أقل من أو يساوي", + "Like": "مثل", + "Lisence Plate Detector": "رخصة لوحة كاشف", + "List Toggle": "قائمة تبديل", + "Live Stream Toggle": "بث مباشر تبديل", + "Live View": "عرض لايف", + "Local": "المحلية", + "Log Level": "سجل مستوى", + "Log Signal Event": "سجل إشارة الحدث من جانب العميل فقط", + "Logging": "تسجيل", + "Login": "تسجيل الدخول", + "Logout": "خروج", + "Logs": "سجلات", + "MB": "MB", + "MJPEG": "MJPEG", + "MP4 (copy, libx264, libx265)": "MP4 (نسخ ، libx264, libx265)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)", + "MailError": "البريد خطأ : لا يمكن إرسال البريد الإلكتروني التحقق من conf.json. تخطي أي ملامح الاعتماد على البريدية.", + "Matches": "مباريات", + "Max Storage Amount": "ماكس تخزين كمية في ميغا بايت", + "Mode": "وضع", + "Monitor": "رصد", + "Monitor Added by user": "رصد المضافة من قبل المستخدم.", + "Monitor Capture Rate": "رصد معدل التقاط (FPS)", + "Monitor Groups": "رصد مجموعات", + "Monitor ID": "رصد ID", + "Monitor Idling": "رصد تسكع", + "Monitor Name": "رصد اسم", + "Monitor Settings": "إعدادات الشاشة", + "Monitor Stopped": "رصد توقف", + "Monitor Updated by user": "مراقبة تحديث من قبل المستخدم.", + "Monitor mode changed": "مراقبة الوضع تغير", + "Monitor mode is already": "رصد وضع بالفعل", + "Monitor or Key does not exist.": "مراقبة أو عدم وجود مفتاح.", + "MonitorIdlingText": "مراقبة الدورة وقد أمر إلى الخمول.", + "MonitorStoppedText": "مراقبة الدورة وقد أمر التوقف.", + "Monitors": "شاشات", + "Monitors per row": "شاشات لكل صف على المونتاج", + "Montage": "المونتاج", + "Motion GUI": "الحركة واجهة المستخدم الرسومية", + "Motion Meter": "الحركة متر", + "Name": "اسم", + "No": "لا", + "No Audio": "لا الصوت", + "No Data": "لا توجد بيانات", + "No Events found for this video": "لا الأحداث وجدت هذا الفيديو", + "No Group with this key exists": "أي جماعة مع هذا المفتاح موجود", + "No Monitor Found, Ignoring Request": "لا مراقبة وجدت تجاهل الطلب", + "No Rotation": "لا دوران", + "No such file": "لا يوجد مثل هذا الملف", + "NoMotionEmailText1": "لا الحركة", + "NoMotionEmailText2": "لم يكن هناك أي حركة الكشف على الكاميرا", + "NoVideosFoundForDateRange": "لا أشرطة الفيديو الموجودة في هذا النطاق الزمني. محاولة تحديد بداية التاريخ إلى الوراء.", + "Not Authorized": "لا يؤذن", + "Not Connected": "غير متصل", + "Not Equal to": "لا يساوي", + "Not In": "لا في", + "Not Matches": "لا يطابق", + "Not Permitted": "لا يسمح", + "Not an Administrator Account": "لا حساب مسؤول", + "NotAuthorizedText1": "لا يحق تقديم init الأمر مع \"مصادقة\",\"كه\", \"uid\"", + "Notes": "ملاحظات", + "NotesPlacholder": "التعليقات كنت تريد أن تترك هذه الكاميرات الإعدادات.", + "Number of Days to keep": "عدد أيام الاحتفاظ", + "ONVIF": "ONVIF", + "ONVIF Scanner": "ONVIF الماسح الضوئي", + "ONVIFnote": "اكتشاف ONVIF الأجهزة على الشبكات خارج الخاص بك أو اتركه فارغا لمسح شبكة الاتصال الحالية الخاصة بك.
اسم المستخدم وكلمة المرور يمكن أن تترك فارغة.", + "OpenCV Cascades": "بنسف شلالات", + "Order Streams": "ترتيب الجداول", + "Output Method": "أسلوب الإخراج", + "Password": "كلمة المرور", + "Password Again": "كلمة المرور مرة أخرى", + "Passwords don't match": "كلمات السر لا تتطابق", + "Paste JSON here.": "لصق JSON هنا.", + "Path": "المسار", + "Permissions": "أذونات", + "Points": "نقاط عند إضافة نقاط انقر على حافة المضلع.", + "Port": "ميناء", + "Position X": "موقف X", + "Position Y": "موقف Y", + "Power Video Viewer": "فيديو المشاهد", + "Power Viewer": "السلطة المشاهد", + "Preferences": "تفضيلات", + "Preset": "مسبقا", + "Probe Size": "التحقيق الحجم", + "Process Crashed for Monitor": "عملية تحطمت على رصد", + "Process Unexpected Exit": "عملية خروج غير متوقع", + "Profile": "الملف الشخصي", + "Quality": "جودة 1 عالية ، 23 منخفضة", + "Query": "الاستعلام", + "RAM": "ذاكرة الوصول العشوائي", + "RTSP": "RTSP", + "RTSP Transport": "RTSP النقل", + "Range or Single": "مجموعة أو واحد", + "Rate": "معدل (FPS)", + "Record": "سجل", + "Record File Type": "تسجيل نوع الملف", + "Record Height": "سجل ارتفاع", + "Record Video Filter": "تسجيل الفيديو فلتر", + "Record Width": "سجل العرض", + "Recording": "تسجيل", + "Recording Flags": "تسجيل الأعلام", + "Recording Segment Interval": "تسجيل الجزء الفاصل الزمني في دقائق", + "Recording Timeout": "تسجيل مهلة في دقائق", + "Recording Timestamp": "تسجيل الزمني", + "Recording Watermark": "تسجيل العلامة المائية", + "RecordingText": "فمن المستحسن أن تقوم بتعيين تسجيل نوع الملف إلى WebMMP4 و ترميز الفيديو إلى libvpxنسخ أو libx264 لأن إدخال نوع هو .", + "Refresh List of Cascades": "تحديث قائمة شلالات", + "Region Editor": "المنطقة محرر", + "Region Name": "اسم المنطقة", + "RegionNote": "النقاط يتم حفظها فقط عند الضغط حفظ على إعدادات الشاشة نافذة.", + "Regions": "المناطق", + "Remember Me": "تذكر لي", + "Reset Timer": "إعادة تعيين جهاز ضبط الوقت", + "Restarting Process": "إعادة تشغيل العملية", + "Retry Connection": "إعادة المحاولة اتصال عدد المرات التي يسمح تفشل", + "Retrying...": "إعادة المحاولة...", + "Right": "صحيح عنوان URL", + "Right Stop": "صحيح وقف عنوان URL", + "Rotate": "تدوير", + "Save": "حفظ", + "Save Directory": "حفظ الدليل", + "Save Events to SQL": "حفظ الأحداث إلى SQL", + "Save Log in SQL": "حفظ سجل في SQL وهذا يمكن أن تملأ بسرعة.", + "Save as": "حفظ باسم", + "Saved Filters": "حفظ الفلاتر", + "Scan Settings": "إعدادات المسح الضوئي", + "Search": "البحث", + "Send Frames": "إرسال إطارات دفع الإطارات ليتم تحليلها", + "Separate with commas, no spaces": "منفصلة بفواصل, بدون مسافات", + "Set to Watch Only": "تعيين مشاهدة فقط", + "Settings": "الإعدادات", + "Settings Changed": "تغيير الإعدادات", + "SettingsChangedText": "إعدادات تم حفظها وتطبيقها.", + "Shinobi": "شينوبي", + "Shinobi Streamer": "شينوبي غاسل", + "Show Logs": "تظهر سجلات", + "Silent": "الصمت", + "Simple": "بسيطة", + "Size (mb)": "الحجم (ميجا بايت)", + "Snapshot": "لقطة", + "Snapshot Flags": "لقطة الأعلام", + "Snapshots": "لقطات", + "Sort By": "فرز حسب", + "Start": "تبدأ", + "Start Recording": "بدء التسجيل", + "Start Time": "وقت البدء", + "Started": "بدأت", + "Status Indicator": "مؤشر حالة", + "Stop URL": "وقف URL", + "Stream": "تيار", + "Stream Flags": "تيار الأعلام", + "Stream Timestamp": "تيار الزمني", + "Stream Type": "تيار من نوع", + "Stream Watermark": "تيار مائية", + "Stream to YouTube": "تيار يوتيوب", + "Stream to YouTube Flags": "تيار يوتيوب الأعلام", + "StreamText": "

هذا القسم سوف تعين الابتدائي تيار الأسلوب وإعدادات. هذا التيار سوف يتم عرضها في لوحة القيادة. إذا اخترت استخدام HLS, JPEG, أو MJPEG ثم يمكنك تستهلك تيار من خلال البرامج الأخرى.

استخدام JPEG تيار أساسا إيقاف البث الأساسية يستخدم اللقطة بن للحصول على إطارات.

", + "Streamer": "غاسل", + "Streams": "تيارات", + "Superuser": "الخارق", + "Switch on for Still Image": "التبديل على صورة ثابتة", + "TCP": "TCP", + "Text Box Color": "النص مربع اللون", + "Text Color": "لون النص", + "Time-lapse": "الوقت الفاصل بين", + "Time-lapse Tool": "الوقت الفاصل بين أداة", + "Timeout": "مهلة", + "Timeout Reset on Next Motion": "مهلة إعادة تعيين على الحركة القادمة", + "Toggle Sidebar": "تبديل الشريط الجانبي", + "Top Left": "أعلى اليسار", + "Top Right": "أعلى اليمين", + "Trigger Record": "الزناد سجل", + "Trigger Successful": "الزناد ناجحة", + "UDP": "UDP", + "URL": "URL", + "URL Stop Timeout": "URL وقف مهلة تشغيل إيقاف URL بعد X ثانية", + "US": "لنا", + "Unable to Launch": "قادر على إطلاق", + "UnabletoLaunchText": "الرجاء حفظ رصد جديدة أولا. ثم محاولة إطلاق محرر المنطقة.", + "Up": "حتى عنوان URL", + "Up Stop": "حتى وقف عنوان URL", + "Username": "اسم المستخدم", + "Value": "القيمة", + "Video": "فيديو", + "Video Codec": "ترميز الفيديو", + "Video Filter": "فيديو مرشح", + "Video Finished": "الفيديو النهائي", + "Video Length (minutes) and Motion Count per video": "طول الفيديو (دقيقة) و الحركة الاعتماد في الفيديو", + "Video Record Rate": "الفيديو سجل معدل (FPS)", + "Video Status": "فيديو حالة", + "Video and Time Span (Minutes)": "فيديو من الزمن (دقيقة)", + "Videos": "الفيديو", + "Videos List": "قائمة أشرطة الفيديو", + "Watch": "مشاهدة", + "Watch Only": "مشاهدة فقط", + "WebDAV": "WebDAV", + "WebM (libvpx)": "WebM (libvpx)", + "Webdav Error": "خطأ Webdav", + "WebdavErrorText": "لا يمكن حفظ. هل جعل الكاميرا المجلدات داخل اخترتها حفظ الدليل ؟ ", + "Webhook": "Webhook", + "Webhook URL": "Webhook URL", + "Width": "العرض", + "Yes": "نعم", + "Zoom In": "التكبير في عنوان URL", + "Zoom In Stop": "التكبير في التوقف عن عنوان URL", + "Zoom Out": "تصغير عنوان URL", + "Zoom Out Stop": "تصغير وقف عنوان URL", + "a day": "اليوم", + "a few seconds": "بضع ثوان", + "a minute": "دقيقة", + "a month": "شهر", + "a year": "في السنة", + "aac": "الجميح للسيارات", + "aac (Default)": "الجميح للسيارات (افتراضي)", + "ac3": "ac3", + "ago": "قبل", + "an hour": "ساعة", + "blankPassword": "تترك فارغة إلى الحفاظ على نفس كلمة المرور", + "calendar": "التقويم", + "clientStreamFailedattemptingReconnect": "العميل ctream تحقق فشلت محاولة إعادة الاتصال.", + "confirmDeleteFilter": "هل تريد حذف هذا الفلتر ؟ لا يمكنك استرداد.", + "copy": "نسخ", + "days": "أيام", + "dropBoxSuccess": "النجاح! الملفات المحفوظة إلى دروببوإكس الخاص بك.", + "for Global Access": "من أجل الوصول العالمي", + "hours": "ساعات", + "in": "في", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis (الافتراضي)", + "libvpx (Default)": "libvpx (الافتراضي)", + "libvpx-vp9": "libvpx-vp9", + "libx264": "libx264", + "libx264 (Default)": "libx264 (الافتراضي)", + "libx265": "libx265", + "minutes": "دقائق", + "modifyVideoText1": "طريقة لا وجود لها. تحقق للتأكد من أن آخر قيمة URL ليست فارغة.", + "monitorEditFailedMaxReached": "حسابك قد بلغ أقصى عدد من الكاميرات التي يمكن إنشاؤها. التحدث إلى مسؤول إذا كنت ترغب في تغيير هذا.", + "monitorEditText1": "بيانات غير صالحة ، تحقق لمعرفة هذا هو صالح استيراد السلسلة.", + "monitorEditText2": "غير صالحة تفاصيل السلسلة. تحقق لمعرفة ما هو سلسلة JSON و غير منتظم وجوه يتم تمريرها.", + "monitorGetText1": "الطلب غير المكتمل ، وإزالة الماضي مائل في URL أو وضع مقبول القيمة.", + "months": "أشهر", + "noSpecialCharacters": "بدون مسافات أو أحرف خاصة.", + "on": "على", + "on Error": "على خطأ", + "startUpText0": "حجم التحقق من أشرطة الفيديو", + "startUpText1": "الغاية من حجم التحقق من أشرطة الفيديو", + "startUpText2": "جميع المستخدمين فحص الانتظار لإغلاق الملفات المفتوحة وإزالة الملفات على حد المستخدم", + "startUpText3": "في انتظار أن تعطي لم تنته الفيديو تحقق بعض الوقت. 3 ثوان.", + "startUpText4": "بدأت كل مجموعة شاشات لمشاهدة وتسجيل", + "startUpText5": "شينوبي جاهز.", + "superAdminText": "\"السوبر.سلمان\" لا وجود لها. الرجاء إعادة تسمية \"سوبر.العينة.سلمان\" إلى \"السوبر.سلمان\".", + "superAdminTitle": "شينوبي : المشرف المميز", + "total": "مجموع", + "undefined": "غير معرف", + "updateKeyText1": "\"updateKey\" مفقود من \"conf.json\", لا يمكن أن تفعل التحديثات هذه الطريقة حتى يمكنك إضافته.", + "updateKeyText2": "\"updateKey\" غير صحيحة.", + "years": "سنوات" +} diff --git a/languages/bn.json b/languages/bn.json new file mode 100644 index 0000000..2d9adcf --- /dev/null +++ b/languages/bn.json @@ -0,0 +1,496 @@ +{ + "\"No Motion\" Detector": "\"কোন গতি\" আবিষ্কারক", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "180 Degrees": "180 ডিগ্রী", + "2-Factor Authentication": "2 ফ্যাক্টর প্রমাণীকরণ", + "90 Clockwise": "ঘড়ির কাঁটার দিকে 90", + "90 Clockwise and Vertical Flip": "90 ঘড়ির কাঁটার দিকে এবং উল্লম্ব উল্টানো", + "90 Counter Clockwise and Vertical Flip (default)": "90 পাল্টা ঘড়ির কাঁটার দিকে এবং উল্লম্ব উল্টানো (ডিফল্ট)", + "API": "এপিআই", + "API Key Added": "API কী যোগ করা হয়েছে", + "API Key Deleted": "API কী মুছে ফেলা", + "API Keys": "API কী", + "APIKeyAddedText": "আপনি এই ব্যবহার করতে পারেন কী এখন.", + "APIKeyDeletedText": "কী মুছে ফেলা হয়েছে. এটা আর কাজ.", + "ASC": "ASC", + "Account Info": "অ্যাকাউন্ট তথ্য", + "AccountEditText1": "না পারে সম্পাদনা করুন. রিফ্রেশ পাতা যদি সমস্যা চলতে থাকে.", + "Accounts": "অ্যাকাউন্ট", + "Action for Selected": "কর্ম জন্য নির্বাচিত", + "Add": "যোগ", + "Add Monitor": "যোগ মনিটর", + "Add New": "নতুন যুক্ত করুন", + "Admin": "অ্যাডমিন", + "Advanced": "উন্নত", + "Again": "আবার", + "All Monitors": "সব মনিটর", + "All Monitors and Privileges": "সব মনিটর এবং বিশেষাধিকার", + "All Warnings": "সব সতর্কবার্তা", + "Allow Next Command": "অনুমতি পরবর্তী কমান্ড মিনিটের মধ্যে", + "Allow Next Email": "অনুমতি পরবর্তী ইমেইল মিনিটের মধ্যে", + "Allow Next Trigger": "অনুমতি পরবর্তী ট্রিগার মিলিসেকেন্ডে ব্যক্ত", + "Allowed IPs": "অনুমোদিত আইপিএস", + "Analyzation Duration": "Analyzation সময়কাল", + "Archive": "আর্কাইভ", + "Audio Codec": "অডিও কোডেক", + "Authenticate": "প্রমাণীকরণ", + "Auto": "অটো", + "Autosave": "স্বয়ংসংরক্ষিত", + "Base64 over Websocket": "Base64 উপর Websocket", + "Bottom Left": "নীচে বাম", + "Bottom Right": "নীচের অংশে ডানদিকে", + "Browser Console Log": "ব্রাউজার কনসোল লগ", + "CPU": "CPU-র", + "CPU indicator will not work. Continuing...": "CPU-র সূচক কাজ করবে না. অব্যাহত...", + "CSS": "CSS এর শৈলী আপনার ড্যাশবোর্ড.", + "Calendar": "ক্যালেন্ডার", + "Camera Password": "ক্যামেরা পাসওয়ার্ড", + "Camera Username": "ক্যামেরা ব্যবহারকারীর নাম", + "Camera is not recording": "ক্যামেরা নয়, রেকর্ডিং", + "CameraNotRecordingText": "সেটিংস বেমানান হতে পারে. পরীক্ষা এনকোডার. রিস্টার্ট...", + "Can Control Monitors": "নিয়ন্ত্রণ করতে পারেন মনিটর", + "Can Delete Videos": "মুছে দিতে পারেন ভিডিও", + "Can Delete Videos and Events": "মুছে দিতে পারেন ভিডিও এবং ঘটনা", + "Can Edit Monitor": "সম্পাদনা করতে পারেন নিরীক্ষণ", + "Can Get Logs": "পেতে পারেন, লগ", + "Can Get Monitors": "পেতে পারেন মনিটর", + "Can View Monitor": "দেখতে পারেন, নিরীক্ষণ", + "Can View Snapshots": "স্ন্যাপশট দেখতে পারেন", + "Can View Streams": "দেখতে পারেন স্ট্রিম", + "Can View Videos": "করতে পারেন, দেখুন ভিডিও", + "Can View Videos and Events": "করতে পারেন, দেখুন ভিডিও এবং ঘটনা", + "Can't Connect": "সংযোগ করতে পারবেন না পারে", + "Center": "কেন্দ্র URL ঠিকানা", + "Chat on Discord": "চ্যাট বিভেদ", + "Check": "পরীক্ষা", + "Check Signal Interval": "পরীক্ষা সংকেত ব্যবধান মিনিটের মধ্যে", + "Check for Motion First": "পরীক্ষা গতি জন্য প্রথম", + "Close": "বন্ধ", + "Closed": "বন্ধ", + "Command": "কমান্ড", + "Command on Trigger": "কমান্ড ট্রিগার", + "Complete Stream URL": "সম্পূর্ণ স্ট্রিম URL", + "Confirm": "নিশ্চিত", + "Connected": "সংযুক্ত", + "Connection Type": "সংযোগের ধরন", + "Control": "নিয়ন্ত্রণ", + "Control Error": "কন্ট্রোল ত্রুটি", + "ControlErrorText1": "নিয়ন্ত্রণ সক্রিয় করা হয় না", + "Controllable": "নিয়ন্ত্রণযোগ্য", + "Country of Plates": "দেশ প্লেট", + "Counts of Motion": "সংখ্যা, গতি", + "Current": "বর্তমান", + "Currently viewing": "বর্তমানে দেখছেন", + "Custom": "কাস্টম", + "Custom Base URL": "কাস্টম বেস URL ফাঁকা ছেড়ে দিন ব্যবহার করে হোস্ট URL টি", + "DB Lost.. Retrying..": "ডাটাবেস হারিয়ে.. Retrying..", + "DESC": "নিম্নক্রমে", + "Dashboard": "ড্যাশবোর্ড", + "Dashboard Language": "ড্যাশবোর্ড ভাষা", + "Dashcam": "Dashcam", + "Dashcam (Streamer v2)": "Dashcam (আলোকরশ্মি v2)", + "Date Range": "তারিখ পরিসীমা", + "Debug": "ডিবাগ", + "Default": "ডিফল্ট", + "Delete": "মুছে দিন", + "Delete Filter": "মুছে দিন, ফিল্টার", + "Delete Matches": "মুছে ম্যাচ", + "Delete Monitor": "মুছে মনিটর", + "Delete Motionless Video": "মুছে নিস্পন্দ ভিডিও", + "Delete Motionless Videos (Record)": "মুছে নিস্পন্দ ভিডিও (রেকর্ড)", + "Delete Selected Videos": "মুছে ফেলুন ভিডিও", + "Delete Video": "মুছে ভিডিও", + "Delete selected": "মুছে ফেলুন", + "DeleteMonitorText": "আপনি মুছে ফেলতে চান, এই নিরীক্ষণ? আপনি পুনরুদ্ধার করা সম্ভব না, এটা. ফাইল জন্য এই আইডি থাকবে ফাইলসিস্টেম. যদি আপনি চয়ন করতে পুনঃ একটি মনিটর সঙ্গে একই আইডি ভিডিও এবং ঘটনা হয়ে যাবে দৃশ্যমান ড্যাশবোর্ড.", + "DeleteSelectedVideosMsg": "আপনি মুছে ফেলতে চান, এই ভিডিও? আপনি পুনরুদ্ধার করা সম্ভব না তাদের.", + "DeleteVideoMsg": "আপনি মুছে ফেলতে চান, এই ভিডিও? আপনি পুনরুদ্ধার করা সম্ভব না, এটা.", + "Deleted": "মুছে ফেলা", + "Detect Objects": "সনাক্ত বস্তু নিচে দেখুন", + "Detector": "আবিষ্কারক", + "Detector Flags": "আবিষ্কারক পতাকা", + "Detector Rate": "আবিষ্কারক হার (FPS যে)", + "DetectorText": "

যখন প্রস্থ এবং উচ্চতা বাক্সে দেখানো হয়, আপনি সেট করা উচিত তাদের 640x480 বা নিচে. এই হবে নিখুত, গতি পড়া ফ্রেম.

", + "Disable Night Vision": "নিষ্ক্রিয় রাতে দৃষ্টি URL ঠিকানা", + "Disable Nightvision": "নিষ্ক্রিয় Nightvision", + "Disabled": "প্রতিবন্ধী", + "Documentation": "ডকুমেন্টেশন", + "Don't show this anymore": "প্রদর্শন করবেন না, এই আর", + "Double Quote Directory": "ডবল উদ্ধৃতি ডিরেক্টরি কিছু ডিরেক্টরি আছে স্পেস. এই ব্যবহার করে বিপর্যস্ত হতে পারে, কিছু ক্যামেরা.", + "Down": "নিচে URL ঠিকানা", + "Down Stop": "নিচে বন্ধ URL ঠিকানা", + "Download": "ডাউনলোড", + "EU": "ইইউ", + "Edit": "সম্পাদনা", + "Email": "ইমেইল", + "Email Details": "ইমেইল বিস্তারিত", + "Email on No Motion": "ইমেইল, \"কোন গতি\"", + "Email on Trigger": "ইমেইল উপর ট্রিগার ইমেল যান প্রধান অ্যাকাউন্ট ধারক এর লগইন ঠিকানা.", + "Enable Night Vision": "সক্রিয় নাইট দৃষ্টি URL ঠিকানা", + "Enable Nightvision": "সক্রিয় Nightvision", + "Enabled": "সক্রিয়", + "End": "শেষ", + "End Time": "শেষ সময়", + "Ended": "শেষ", + "Enlarge": "বিবর্ধন", + "Enter this code to proceed": "এই কোড লিখুন এগিয়ে যেতে", + "Equal to": "সমান", + "Error Connecting": "সংযোগ ত্রুটি", + "Event": "ইভেন্ট", + "Event Limit": "ইভেন্ট সীমা", + "EventText1": "সূত্রপাত গতি এ ঘটনা", + "EventText2": "না পারে, ইমেইল, ইমেজ ফাইল ছিল না, প্রবেশযোগ্য", + "Events": "ঘটনা", + "Example": "উদাহরণ", + "Execute Command": "চালানো কমান্ড", + "Executed": "মৃত্যুদন্ড কার্যকর", + "Export": "রপ্তানি", + "FFmpegCantStart": "FFmpeg শুরু করতে পারে না", + "FFmpegCantStartText": "রেকর্ডিং ইঞ্জিন জন্য এই ক্যামেরা শুরু করতে পারে না. হতে পারে, কিছু ভুল আপনার ক্যামেরা সঙ্গে কনফিগারেশন. যদি সেখানে হয় কোন লগ তুলনায় অন্যান্য, এই এক পোস্ট করুন তাদের সমস্যা Github উপর.", + "FFmpegTip": "FFprobe একটি সহজ মাল্টিমিডিয়া স্ট্রিম বিশ্লেষক. আপনি এটি ব্যবহার করতে পারেন আউটপুট সব ধরণের তথ্য সম্পর্কে একটি ইনপুট সহ, সময়কাল, ফ্রেম রেট, ফ্রেম সাইজ, ইত্যাদি.", + "FFprobe": "প্রোবের", + "FactorAuthText1": "কোড কেবল তখনই সক্রিয় করা হবে 15 মিনিটের জন্য. যদি আপনি আবার লগইন হবে টাইমার রিসেট করার 15 মিনিট একই সঙ্গে কোড.", + "Fatal": "মারাত্মক", + "Fatal Maximum Reached": "মারাত্মক সর্বোচ্চ পৌঁছেছেন বাঁধন ক্যামেরা.", + "FatalMaximumReachedText": "কোন JPEG ত্রুটি ছিল মারাত্মক.", + "Feed-in Image Height": "ফিড-ইন ইমেজ উচ্চতা", + "Feed-in Image Width": "ফিড-ইন ইমেজ প্রস্থ", + "Fields cannot be empty": "ক্ষেত্র হতে পারে না, খালি", + "File Not Exist": "ফাইল উপস্থিত না", + "File Not Found": "ফাইল পাওয়া যায় না", + "File Type": "ফাইল টাইপ", + "FileNotExistText": "সংরক্ষণ করতে পারবেন না, অ existant ফাইল. কিছু ভুল হয়েছে.", + "Filename": "ফাইলের নাম", + "Filesize": "Filesize", + "Filter ID": "ফিল্টার আইডি", + "Filter Matches": "ফিল্টার ম্যাচ", + "Filter Name": "ফিল্টার নাম", + "FilterMatchesText1": "এই ফিল্টার শর্ত পূরণ করা হয়েছে.", + "FilterMatchesText2": "ভিডিও পাওয়া যায়.", + "Filters": "ফিল্টার", + "Filters Updated": "ফিল্টার আপডেট করা হয়েছে", + "FiltersUpdatedText": "আপনার পরিবর্তনগুলি সংরক্ষণ করা হয়েছে এবং প্রয়োগ.", + "Find Where": "এটি যেখানে", + "Fix": "ফিক্স", + "Fix Video": "ফিক্স ভিডিও", + "FixVideoMsg": "আপনি কি করতে চান ঠিক এই ভিডিও? আপনি পূর্বাবস্থা করতে পারবেন না, এই কর্ম.", + "Font Path": "ফন্ট পথ", + "Font Size": "ফন্টের আকার", + "Force Port": "বল পোর্ট", + "Found Devices": "পাওয়া ডিভাইসের", + "Frame Rate": "ফ্রেম হার (FPS যে)", + "Full Frame Detection": "পুরো ফ্রেম সনাক্তকরণ", + "Fullscreen": "পর্দা জুড়ে প্রদর্শন", + "Greater Than": "তার চেয়ে অনেক বেশী", + "Greater Than or Equal to": "তার চেয়ে অনেক বেশী বা সমান", + "Group Key": "গ্রুপ কী", + "Group Name": "গ্রুপের নাম", + "Grouping": "জোট ", + "H.264 / H.265 / H.265+": "H. 264 / H. 265 / H. 265 ", + "HLS (.m3u8)": "HLS (.m3u8)", + "HLS (includes Audio)": "HLS (অন্তর্ভুক্ত অডিও)", + "HLS Audio Encoder": "HLS অডিও এনকোডার", + "HLS List Size": "HLS তালিকা আকার", + "HLS Preset": "HLS প্রিসেট", + "HLS Segment Length": "HLS সেগমেন্ট দৈর্ঘ্য সেকেন্ডের মধ্যে", + "HLS Video Encoder": "HLS ভিডিও এনকোডার", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "Height": "উচ্চতা", + "Help": "সাহায্য", + "Hide List": "আড়াল তালিকা", + "Hide Notes": "আড়াল নোট", + "Host": "হোস্ট", + "Hotswap Modes (Watch-Only)": "Hotswap মোড (দেখুন শুধুমাত্র)", + "How to Record": "রেকর্ড কিভাবে", + "IP Address": "আইপি ঠিকানা", + "Identity": "পরিচয়", + "IdentityText1": "কিভাবে এই সিস্টেম সনাক্ত করা হবে এই জন্য তথ্য প্রবাহ. আপনি পরিবর্তন করতে পারবেন না, মনিটর আইডি আছে একবার আপনি চাপা সংরক্ষণ করুন. যদি আপনি চান আপনি করতে পারেন নিরীক্ষণ, আইডি , আরো মানুষের পাঠযোগ্য আপনি অবিরত আগে.", + "IdentityText2": "আপনি প্রতিলিপি করতে পারেন একটি মনিটর পরিবর্তন করে মনিটর আইডি , তারপর টিপে সংরক্ষণ করুন. আপনি না ব্যবহার করে আইডি এর একটি মনিটর যে ইতিমধ্যেই বিদ্যমান, অথবা এটি সংরক্ষণ করতে হবে যে ওভার মনিটর এর ডাটাবেস তথ্য.", + "Idle": "অলস", + "Image Height": "ইমেজ উচ্চতা", + "Image Location": "ইমেজ অবস্থান পরম পাথ অথবা ফাঁকা ছেড়ে দিন ব্যবহার করতে গ্লোবাল", + "Image Position": "ইমেজ অবস্থান", + "Image Width": "চিত্র প্রস্থ", + "Import": "আমদানি", + "Import Monitor Configuration": "আমদানি মনিটর কনফিগারেশন", + "ImportMonitorConfigurationText": "এই কাজ হবে overrwrite কোন পরিবর্তন বর্তমানে সংরক্ষিত নয়. আমদানি পরিবর্তন হবে শুধুমাত্র প্রয়োগ করা হলে, আপনি প্রেস সংরক্ষণ করুন.", + "In": "এ", + "Incorrect Settings Chosen": "ভুল সেটিংস চয়ন", + "Indifference": "অযত্ন", + "Input": "ইনপুট", + "Input Flags": "ইনপুট পতাকা", + "Input Type": "ইনপুট টাইপ", + "InputText1": "এই অধ্যায় বলে Shinobi গ্রাস কিভাবে একটি স্ট্রিম. অনুকূল কর্ম সঞ্চালনের জন্য টিউন করার চেষ্টা করুন, আপনার ক্যামেরা এর অভ্যন্তরীণ সেটিংস. এটি নিম্নলিখিত অপশন এবং তাদের সেট হিসাবে দেখানো হয়েছে. খুঁজে বের করতে আপনার ক্যামেরা ব্যবহার করতে পারেন বিল্ট ইন ONVIF স্ক্যানার এর Shinobi. কিছু ONVIF ক্যামেরা ব্যবহারের প্রয়োজন একটি ম্যানেজমেন্ট টুল পরিবর্তন করতে তাদের অভ্যন্তরীণ সেটিংস. যদি আপনি না করতে পারেন, এটি আপনার ক্যামেরা আপনি চেষ্টা করতে পারেন, ONVIF ডিভাইস ম্যানেজার উইন্ডোজের জন্য.", + "InputText2": "
  • ফ্রেমরেট (FPS) : উচ্চ : 10 - 15 FPS কম : 2-5 FPS
  • আমি-ফ্রেম ব্যবধান : 80
  • বিট রেট টাইপ : CBR (ধ্রুবক বিট রেট)
  • বিট রেট : মধ্যে 256kbps - 500kbps
", + "InputText3": "যদি আপনি সাহায্য প্রয়োজন figuring আউট কি ইনপুট টাইপ আপনার ক্যামেরা, হয়, আপনি গ্রহণ করতে পারেন, একটি বর্ণন মধ্যে ক্যামেরা Url গুলি তালিকা উপর Shinobi ওয়েবসাইট.", + "Invalid JSON": "অবৈধ JSON", + "InvalidJSONText": "দয়া করে নিশ্চিত করুন, এটি একটি বৈধ JSON স্ট্রিং জন্য Shinobi মনিটর কনফিগারেশন.", + "JPEG": "কোন JPEG", + "JPEG (Auto Enables JPEG API)": "কোন JPEG (অটো সক্ষম হবেন, কোন JPEG, এপিআই)", + "JPEG API": "কোন JPEG এপিআই স্ন্যাপশট (cgi-bin)", + "JPEG Error": "কোন JPEG ত্রুটি", + "JPEG Mode": "কোন JPEG মোড", + "JPEGErrorText": "সেখানে ছিল একটি ইস্যু পেয়ে তথ্য আপনার ক্যামেরা থেকে.", + "Leave blank for random.": "ফাঁকা ছেড়ে দিন জন্য র্যান্ডম.", + "Left": "বাম URL ঠিকানা", + "Left Stop": "বাম বন্ধ URL ঠিকানা", + "Less Than": "কম", + "Less Than or Equal to": "কম বা সমান", + "Like": "মত", + "Lisence Plate Detector": "অনুজ্ঞাপত্র প্লেট আবিষ্কারক", + "List Toggle": "তালিকা টগল", + "Live Stream Toggle": "লাইভ স্ট্রিম টগল", + "Live View": "লাইভ দেখুন", + "Local": "স্থানীয়", + "Log Level": "লগ স্তর", + "Log Signal Event": "লগ সংকেত ইভেন্ট ক্লায়েন্ট প্রান্তের শুধুমাত্র", + "Logging": "লগিং", + "Login": "লগইন", + "Logout": "লগ আউট", + "Logs": "লগ", + "MB": "MB", + "MJPEG": "MJPEG", + "MP4 (copy, libx264, libx265)": "আছে MP4 (কপি, libx264, libx265)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4 (.আছে mp4 / .ts)", + "MailError": "মেইল ত্রুটি : যায়নি পাঠাতে ইমেইল চেক conf.json. কুঁদন কোন বৈশিষ্ট্য উপর নির্ভর মেইলিং.", + "Matches": "ম্যাচ", + "Max Storage Amount": "সর্বোচ্চ স্টোরেজ পরিমাণ মেগাবাইটের মধ্যে", + "Mode": "মোড", + "Monitor": "মনিটর", + "Monitor Added by user": "মনিটর যোগ করা হয়েছে ব্যবহারকারী দ্বারা.", + "Monitor Capture Rate": "মনিটর ক্যাপচার হার (FPS যে)", + "Monitor Groups": "মনিটর গ্রুপ", + "Monitor ID": "মনিটর আইডি", + "Monitor Idling": "মনিটর আলসে", + "Monitor Name": "মনিটর নাম", + "Monitor Settings": "মনিটর সেটিংস", + "Monitor Stopped": "মনিটর বন্ধ", + "Monitor Updated by user": "মনিটর দ্বারা আপডেট ব্যবহারকারী.", + "Monitor mode changed": "মনিটর মোড পরিবর্তন", + "Monitor mode is already": "মনিটর মোড ইতিমধ্যে", + "Monitor or Key does not exist.": "মনিটর বা কী নেই.", + "MonitorIdlingText": "মনিটর অধিবেশন করার নির্দেশ দেয়া হয়েছে অলস.", + "MonitorStoppedText": "মনিটর অধিবেশন বন্ধ করার নির্দেশ দেয়া হয়েছে.", + "Monitors": "মনিটর", + "Monitors per row": "মনিটর প্রতি সারির জন্য পূর্ণাঙ্গতা", + "Montage": "পূর্ণাঙ্গতা", + "Motion GUI": "গতি গ্রাফিক্যাল ইউজার ইন্টারফেস", + "Motion Meter": "গতি মিটার", + "Name": "নাম", + "No": "কোন", + "No Audio": "কোন অডিও", + "No Data": "কোন তথ্য", + "No Events found for this video": "কোন ঘটনা পাওয়া জন্য এই ভিডিও", + "No Group with this key exists": "কোন গ্রুপ এই কী দিয়ে বিদ্যমান", + "No Monitor Found, Ignoring Request": "কোন মনিটর পাওয়া উপেক্ষা অনুরোধ", + "No Rotation": "কোন ঘূর্ণন", + "No such file": "কোন ধরনের ফাইল", + "NoMotionEmailText1": "কোন গতি জন্য", + "NoMotionEmailText2": "সেখানে এখন পর্যন্ত হয়েছে, কোন গতি সনাক্ত ক্যামেরা জন্য", + "NoVideosFoundForDateRange": "কোন ভিডিও পাওয়া যায়, এই তারিখ পরিসীমা. চেষ্টা সেটিং আরম্ভের তারিখ আরও ফিরে.", + "Not Authorized": "অনুমোদিত না", + "Not Connected": "সংযুক্ত নয়", + "Not Equal to": "সমান না", + "Not In": "না", + "Not Matches": "না, ম্যাচ", + "Not Permitted": "অনুমতি না", + "Not an Administrator Account": "না, একজন প্রশাসক অ্যাকাউন্ট", + "NotAuthorizedText1": "না, কঠিন জমা init কমান্ড দিয়ে \"প্রমাণীকরণ\",\"কে\" এবং \"uid\"", + "Notes": "নোট", + "NotesPlacholder": "মন্তব্য, আপনি ছেড়ে দিতে চান জন্য এই ক্যামেরা সেটিংস.", + "Number of Days to keep": "দিনের সংখ্যা রাখা", + "ONVIF": "ONVIF", + "ONVIF Scanner": "ONVIF স্ক্যানার", + "ONVIFnote": "আবিষ্কার ONVIF ডিভাইসের উপর নেটওয়ার্কের বাইরে আপনার নিজের অথবা এটি ফাঁকা ছেড়ে স্ক্যান করার জন্য আপনার বর্তমান নেটওয়ার্ক.
ব্যবহারকারীর নাম এবং পাসওয়ার্ড ফাঁকা রাখা যেতে পারে.", + "OpenCV Cascades": "OpenCV ক্যাসকেড", + "Order Streams": "যাতে স্ট্রিম", + "Output Method": "আউটপুট পদ্ধতি", + "Password": "পাসওয়ার্ড", + "Password Again": "আবার পাসওয়ার্ড", + "Passwords don't match": "পাসওয়ার্ড মেলে না", + "Paste JSON here.": "পেস্ট JSON আছেন.", + "Path": "পথ", + "Permissions": "অনুমতি", + "Points": "পয়েন্ট যোগ করার সময় পয়েন্ট উপর ক্লিক করুন ধারে বহুভুজ.", + "Port": "পোর্ট", + "Position X": "অবস্থান X", + "Position Y": "অবস্থান Y", + "Power Video Viewer": "পাওয়ার ভিডিও ভিউয়ার", + "Power Viewer": "ক্ষমতা ভিউয়ার", + "Preferences": "পছন্দ", + "Preset": "প্রিসেট", + "Probe Size": "প্রোব ফাইলের আকার", + "Process Crashed for Monitor": "প্রক্রিয়া ক্র্যাশ জন্য মনিটর", + "Process Unexpected Exit": "প্রক্রিয়া অপ্রত্যাশিত প্রস্থান", + "Profile": "প্রোফাইল", + "Quality": "মান 1 উচ্চ, 23 হয় কম", + "Query": "ক্যোয়ারী", + "RAM": "র্যাম", + "RTSP": "RTSP", + "RTSP Transport": "RTSP পরিবহন", + "Range or Single": "পরিসীমা বা একক", + "Rate": "হার (FPS যে)", + "Record": "রেকর্ড", + "Record File Type": "রেকর্ড ফাইল টাইপ", + "Record Height": "রেকর্ড উচ্চতা", + "Record Video Filter": "রেকর্ড ভিডিও ফিল্টার", + "Record Width": "রেকর্ড প্রস্থ", + "Recording": "রেকর্ডিং", + "Recording Flags": "রেকর্ডিং পতাকা", + "Recording Segment Interval": "রেকর্ডিং সেগমেন্ট ব্যবধান মিনিটের মধ্যে", + "Recording Timeout": "রেকর্ডিং সময়সীমার মধ্যে মিনিট", + "Recording Timestamp": "রেকর্ডিং টাইমস্ট্যাম্প", + "Recording Watermark": "রেকর্ডিং জলছাপ", + "RecordingText": "এটা বাঞ্ছনীয় যে আপনি সেট রেকর্ড ফাইল টাইপ করতে WebM, আছে MP4 , এবং ভিডিও কোডেক করতে libvpxকপি বা libx264 , কারণ আপনার ইনপুট টাইপ সেট করা হয় .", + "Refresh List of Cascades": "রিফ্রেশ তালিকা ক্যাসকেড", + "Region Editor": "অঞ্চল সম্পাদক", + "Region Name": "অঞ্চলের নাম", + "RegionNote": "পয়েন্ট হয় শুধুমাত্র সংরক্ষিত যখন আপনি টিপুন সংরক্ষণ করে মনিটর সেটিংস উইন্ডো.", + "Regions": "অঞ্চল", + "Remember Me": "আমাকে মনে রেখো", + "Reset Timer": "রিসেট টাইমার", + "Restarting Process": "পুনরায় আরম্ভ করার প্রক্রিয়া", + "Retry Connection": "পুনরায় সংযোগ সংখ্যা বার অনুমোদিত করতে ব্যর্থ", + "Retrying...": "Retrying...", + "Right": "সঠিক URL ঠিকানা", + "Right Stop": "ডান বন্ধ URL ঠিকানা", + "Rotate": "ঘোরান", + "Save": "সংরক্ষণ করুন", + "Save Directory": "ডিরেক্টরি সংরক্ষণ করুন", + "Save Events to SQL": "সংরক্ষণ ঘটনা এসকিউএল", + "Save Log in SQL": "সংরক্ষণ লগ ইন এসকিউএল এই পূরণ করতে পারেন, দ্রুত.", + "Save as": "হিসাবে সংরক্ষণ করুন", + "Saved Filters": "সংরক্ষিত ফিল্টার", + "Scan Settings": "স্ক্যান সেটিংস", + "Search": "অনুসন্ধান", + "Send Frames": "পাঠাতে ফ্রেম ধাক্কা ফ্রেম বিশ্লেষণ করা", + "Separate with commas, no spaces": "পৃথক কমা দিয়ে কোন স্পেস", + "Set to Watch Only": "সেট দেখতে শুধুমাত্র", + "Settings": "সেটিংস", + "Settings Changed": "সেটিংস পরিবর্তন", + "SettingsChangedText": "আপনার সেটিংস সংরক্ষণ করা হয়েছে এবং প্রয়োগ.", + "Shinobi": "Shinobi", + "Shinobi Streamer": "Shinobi উজ্জ্বল আলোকরশ্মি", + "Show Logs": "শো লগ", + "Silent": "নীরব", + "Simple": "সহজ", + "Size (mb)": "মাপ (মেগাবাইট)", + "Snapshot": "স্ন্যাপশট", + "Snapshot Flags": "স্ন্যাপশট পতাকা", + "Snapshots": "স্ন্যাপশট", + "Sort By": "দ্বারা বাছাই", + "Start": "শুরু", + "Start Recording": "রেকর্ডিং শুরু", + "Start Time": "সময় শুরু", + "Started": "শুরু", + "Status Indicator": "অবস্থা সূচক", + "Stop URL": "বন্ধ URL টি", + "Stream": "স্ট্রিম", + "Stream Flags": "স্ট্রিম পতাকা", + "Stream Timestamp": "স্ট্রিম টাইমস্ট্যাম্প", + "Stream Type": "প্রবাহ টাইপ,", + "Stream Watermark": "স্ট্রিম জলছাপ", + "Stream to YouTube": "স্ট্রিম YouTube", + "Stream to YouTube Flags": "স্ট্রিম করতে ইউটিউব পতাকা", + "StreamText": "

এই বিভাগে নামকরণ করা হবে এই প্রাথমিক স্ট্রিম আউট পদ্ধতি এবং এটি এর সেটিংস. এই স্ট্রিম প্রদর্শন করা হবে ড্যাশবোর্ড. আপনি ব্যবহার করতে পছন্দ HLS, কোন JPEG, বা MJPEG, তারপর আপনি গ্রাস করতে পারেন স্ট্রিম মাধ্যমে অন্যান্য প্রোগ্রাম.

ব্যবহার কোন JPEG স্ট্রিম মূলত বন্ধ করিয়া প্রাথমিক স্ট্রিম এবং ব্যবহার স্ন্যাপশট বিন পেতে ফ্রেম.

", + "Streamer": "উজ্জ্বল আলোকরশ্মি", + "Streams": "স্ট্রিম", + "Superuser": "Superuser", + "Switch on for Still Image": "সুইচ জন্য এখনও ইমেজ", + "TCP": "TCP", + "Text Box Color": "টেক্সট বক্স রঙ", + "Text Color": "টেক্সট রঙ", + "Time-lapse": "সময় ভ্রষ্টতা", + "Time-lapse Tool": "সময় ভ্রষ্টতা টুল", + "Timeout": "সময়সীমার", + "Timeout Reset on Next Motion": "সময়সীমার রিসেট পরবর্তী গতি", + "Toggle Sidebar": "টগল পার্শ্বদন্ডে", + "Top Left": "উপরের বাম", + "Top Right": "উপরের ডান", + "Trigger Record": "ট্রিগার রেকর্ড", + "Trigger Successful": "ট্রিগার সফল", + "UDP": "এর ফলে UDP", + "URL": "URL টি", + "URL Stop Timeout": "URL বন্ধ সময়সীমার চালানো বন্ধ URL পরে এক্স মিলিসেকেন্ড", + "US": "আমাদের", + "Unable to Launch": "আরম্ভ করতে অক্ষম", + "UnabletoLaunchText": "সংরক্ষণ করুন, নতুন মনিটর প্রথম. তারপর চেষ্টা করতে আরম্ভ অঞ্চলের সম্পাদক.", + "Up": "আপ URL ঠিকানা", + "Up Stop": "আপ বন্ধ URL ঠিকানা", + "Username": "ব্যবহারকারীর নাম", + "Value": "মান", + "Video": "ভিডিও", + "Video Codec": "ভিডিও কোডেক", + "Video Filter": "ভিডিও ফিল্টার", + "Video Finished": "ভিডিও সমাপ্ত", + "Video Length (minutes) and Motion Count per video": "ভিডিও দৈর্ঘ্য (মিনিট) এবং গতি গণনা প্রতি ভিডিও", + "Video Record Rate": "ভিডিও রেকর্ড হার (FPS যে)", + "Video Status": "ভিডিও অবস্থা", + "Video and Time Span (Minutes)": "ভিডিও এবং সময় স্প্যান (মিনিট)", + "Videos": "ভিডিও", + "Videos List": "ভিডিও তালিকা", + "Watch": "ওয়াচ", + "Watch Only": "ওয়াচ শুধুমাত্র", + "WebDAV": "অম্রো", + "WebM (libvpx)": "WebM (libvpx)", + "Webdav Error": "অম্রো ত্রুটি", + "WebdavErrorText": "উদ্ধার করতে পারে না. আপনি কি করতে ক্যামেরা ফোল্ডার ভিতরে আপনার নির্বাচিত ডিরেক্টরি সংরক্ষণ করুন?", + "Webhook": "Webhook", + "Webhook URL": "Webhook URL টি", + "Width": "প্রস্থ", + "Yes": "হ্যাঁ", + "Zoom In": "জুম ইন URL ঠিকানা", + "Zoom In Stop": "জুম বন্ধ URL ঠিকানা", + "Zoom Out": "জুম আউট URL ঠিকানা", + "Zoom Out Stop": "জুম আউট বন্ধ URL ঠিকানা", + "a day": "একটি দিন", + "a few seconds": "কয়েক সেকেন্ড", + "a minute": "একটি মিনিট", + "a month": "একটি মাস", + "a year": "একটি বছর", + "aac": "এএসি", + "aac (Default)": "এএসি (ডিফল্ট)", + "ac3": "ac3", + "ago": "আগে", + "an hour": "একটি ঘন্টা", + "blankPassword": "ছেড়ে ফাঁকা রাখা একই পাসওয়ার্ড", + "calendar": "ক্যালেন্ডার", + "clientStreamFailedattemptingReconnect": "ক্লায়েন্ট সাইড ctream পরীক্ষা ব্যর্থ প্রয়াস পুনরায় সংযোগ স্থাপন.", + "confirmDeleteFilter": "আপনি চাই প্রতি মুছে ফেলা এই ফিল্টার? আপনি পুনরুদ্ধার করা সম্ভব না, এটা.", + "copy": "কপি", + "days": "দিন", + "dropBoxSuccess": "সাফল্য! ফাইল সংরক্ষণ করার জন্য আপনার ড্রপবক্স.", + "for Global Access": "গ্লোবাল এক্সেস", + "hours": "ঘন্টা", + "in": "এ", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis (ডিফল্ট)", + "libvpx (Default)": "libvpx (ডিফল্ট)", + "libvpx-vp9": "libvpx-vp9", + "libx264": "libx264", + "libx264 (Default)": "libx264 (ডিফল্ট)", + "libx265": "libx265", + "minutes": "মিনিট", + "modifyVideoText1": "পদ্ধতি বিদ্যমান নেই. পরীক্ষা নিশ্চিত করুন যে আপনি সর্বশেষ মান URL টি নয়, ফাঁকা.", + "monitorEditFailedMaxReached": "আপনার অ্যাকাউন্ট পৌঁছেছে সর্বোচ্চ সংখ্যা, যে ক্যামেরা তৈরি করা যেতে পারে. কথা বলতে একজন প্রশাসক যদি আপনি চান এই পরিবর্তন.", + "monitorEditText1": "অবৈধ তথ্য পরীক্ষা করে দেখুন, এই একটি বৈধ আমদানি স্ট্রিং.", + "monitorEditText2": "অবৈধ বিবরণ স্ট্রিং. দেখতে পরীক্ষা করুন, এটি একটি JSON স্ট্রিং এবং না একটি নিয়মিত বস্তুর অতিক্রান্ত হচ্ছে.", + "monitorGetText1": "অসম্পূর্ণ অনুরোধ অপসারণ, গত স্ল্যাশ মধ্যে URL বা করা গ্রহণযোগ্য মান.", + "months": "মাস", + "noSpecialCharacters": "কোন স্পেস বা বিশেষ অক্ষর.", + "on": "উপর", + "on Error": "উপর ত্রুটি", + "startUpText0": "আকার জন্য পরীক্ষা করে দেখুন ভিডিও", + "startUpText1": "শেষে আকার জন্য পরীক্ষা করে দেখুন ভিডিও", + "startUpText2": "সব ব্যবহারকারীদের চেক অপেক্ষা করুন, বন্ধ করতে, খোলা ফাইল এবং ফাইল মুছে ফেলুন উপর ব্যবহারকারী সীমা", + "startUpText3": "অপেক্ষা করতে দিতে অসমাপ্ত ভিডিও পরীক্ষা কিছু সময়. 3 সেকেন্ড.", + "startUpText4": "শুরু, সব মনিটর সেট দেখতে এবং রেকর্ড", + "startUpText5": "Shinobi প্রস্তুত হয়.", + "superAdminText": "\"সুপার.json\" বিদ্যমান নয়. দয়া করে নামান্তর \"সুপার.নমুনা.json\", \"সুপার.json\".", + "superAdminTitle": "Shinobi : সুপার অ্যাডমিন", + "total": "মোট", + "updateKeyText1": "\"updateKey\" থেকে অনুপস্থিত, \"conf.json\", আপডেট করতে পারবেন না এই ভাবে যতক্ষণ না আপনি এটি যোগ করুন.", + "updateKeyText2": "\"updateKey\" ভুল হয়.", + "years": "বছর" +} diff --git a/languages/de.json b/languages/de.json new file mode 100644 index 0000000..185ec88 --- /dev/null +++ b/languages/de.json @@ -0,0 +1,497 @@ +{ + "\"No Motion\" Detector": "Detektor für \"keine Bewegung\"", + "# of Allow MJPEG Clients": "Max. Anz. von MJPEG-Clients 0 = unbeschränkt", + "180 Degrees": "180 Grad", + "2-Factor Authentication": "2-Faktor-Authentifizierung", + "90 Clockwise": "90° im Uhrzeigersinn", + "90 Clockwise and Vertical Flip": "90° im Uhrzeigersinn drehen und vertikal spiegeln", + "90 Counter Clockwise and Vertical Flip (default)": "90° entgegen dem Uhrzeigersinn drehen und vertikal spiegeln (Standard)", + "API": "API", + "API Key Added": "API-Schlüssel hinzugefügt", + "API Key Deleted": "API-Schlüssel gelöscht", + "API Keys": "API-Schlüssel", + "APIKeyAddedText": "Sie können diesen API-Schlüssel nun verwenden.", + "APIKeyDeletedText": "Der API-Schlüssel wurde gelöscht. Er wird nicht mehr funktionieren.", + "ASC": "Auf", + "Account Info": "Account-Info", + "AccountEditText1": "Ändern nicht möglich. Bitte die Seite neu laden, falls das Problem weiterhin besteht.", + "Accounts": "Konten", + "Action for Selected": "Aktion für Ausgewählte", + "Add": "Hinzufügen", + "Add Monitor": "Monitor Hinzufügen", + "Add New": "Neu hinzufügen", + "Admin": "Admin", + "Advanced": "Experten", + "Again": "Erneut", + "All Monitors": "Alle Monitore", + "All Monitors and Privileges": "Alle Monitore und Privilegien", + "All Warnings": "Alle Warnungen", + "Allow Next Command": "Min. Zeitspanne zwischen zwei Befehlenin Minuten", + "Allow Next Email": "Min. Zeitspanne zwischen zwei E-Mailsin Minuten", + "Allow Next Trigger": "Min. Zeitspanne zwischen zwei Triggernin Millisekunden", + "Allowed IPs": "Erlaubte IPs", + "Analyzation Duration": "Analyse-Dauer", + "Archive": "Archiv", + "Audio Codec": "Audio-Codec", + "Authenticate": "Authentifizieren", + "Auto": "Auto", + "Autosave": "Autom. Speichern", + "Base64 over Websocket": "Base64 über Websocket", + "Bottom Left": "Unten links", + "Bottom Right": "Unten rechts", + "Browser Console Log": "Browser-Konsole", + "CPU": "CPU", + "CPU indicator will not work. Continuing...": "Die CPU-Anzeige funktioniert nicht. Weiter...", + "CSS": "CSS - Definiert eigene Styles im Dashboard", + "Calendar": "Kalender", + "Camera Password": "Kamera-Passwort", + "Camera Username": "Kamera-Benutzername", + "Camera is not recording": "Die Kamera nimmt nicht auf.", + "CameraNotRecordingText": "Die Einstellungen sind möglicherweise nicht kompatibel. Bitte die Encoder-Einstellung überprüfen.", + "Can Control Monitors": "Darf Monitore steuern", + "Can Delete Videos": "Darf Videos löschen", + "Can Delete Videos and Events": "Darf Videos und Events löschen", + "Can Edit Monitor": "Darf Monitor-Einstellungen bearbeiten", + "Can Get Logs": "Darf die Logs sehen", + "Can Get Monitors": "Darf Monitore auflisten", + "Can View Monitor": "Darf Monitore sehen", + "Can View Snapshots": "Darf Snapshots erstellen/sehen", + "Can View Streams": "Darf Streams sehen", + "Can View Videos": "Darf Videos anschauen", + "Can View Videos and Events": "Darf Videos und Events ansehen", + "Can't Connect": "Konnte nicht Verbinden.", + "Center": "Mitte - URL-Adresse", + "Chat on Discord": "Chat auf Discord", + "Check": "Überprüfen", + "Check Signal Interval": "Signal-Überprüfungsintervall in Minuten", + "Check for Motion First": "Bewegungserkennung zuerst", + "Close": "Schließen", + "Closed": "Geschlossen", + "Command": "Befehl", + "Command on Trigger": "Befehl beim Trigger", + "Complete Stream URL": "Komplette Stream-URL", + "Confirm": "Bestätigen", + "Connected": "Verbunden", + "Connection Type": "Verbindungstyp", + "Control": "Steuerung", + "Control Error": "Steuerungsfehler", + "ControlErrorText1": "Die Steuerung ist nicht aktiviert", + "Controllable": "Steuerbar", + "Country of Plates": "Kennzeichen-Land", + "Counts of Motion": "Bewegungsschwelle", + "Current": "Aktuell", + "Currently viewing": "Anzahl Beobachter", + "Custom": "Benutzerdefiniert", + "Custom Base URL": "Eigene Basis-URL leer Lassen, um Host-URL zu verwenden", + "DB Lost.. Retrying..": "Datenbank-Verbindung verloren... Erneuter Versuch...", + "DESC": "Ab", + "Dashboard": "Dashboard", + "Dashboard Language": "Dashboard-Sprache", + "Dashcam": "Dashcam", + "Dashcam (Streamer v2)": "Dashcam (Streamer v2)", + "Date Range": "Datumsbereich", + "Debug": "Debug", + "Default": "Standard", + "Delete": "Löschen", + "Delete Filter": "Filter Löschen", + "Delete Matches": "Lösche Treffer", + "Delete Monitor": "Lösche Monitor", + "Delete Motionless Video": "Videos ohne Bewegung löschen", + "Delete Motionless Videos (Record)": "Videos ohne Bewegung löschen (Aufzeichnung)", + "Delete Selected Videos": "Ausgewählte Videos löschen", + "Delete Video": "Video Löschen", + "Delete selected": "Ausgewählte löschen", + "DeleteMonitorText": "Möchten Sie diesen Monitor wirklich löschen? Sie können diese Löschung nicht mehr rückgängig machen. Die Dateien für diese Monitor-ID verbleiben im Dateisystem. Wenn Sie einen Monitor mit der gleichen ID erstellen, werden die Videos und Ereignisse wieder sichtbar.", + "DeleteSelectedVideosMsg": "Wollen Sie diese Videos löschen? Sie können diese Löschung nicht mehr rückgängig machen.", + "DeleteVideoMsg": "Wollen Sie dieses Video löschen? Sie können diese Löschung nicht mehr rückgängig machen.", + "Deleted": "Gelöscht", + "Detect Objects": "Erkennung von Objekten Siehe unten", + "Detector": "Detektor", + "Detector Flags": "Detektor-Flags", + "Detector Rate": "Detektor-Rate (Bilder pro Sekunde)", + "DetectorText": "

Die Detektor-Bildgröße sollte auf 640x480 oder kleiner eingestellt werden.. Dies optimiert die Geschwindigkeit beim Auslesen der Bilder.

", + "Disable Night Vision": "Nachtsicht deaktivieren URL-Adresse", + "Disable Nightvision": "Nachtsicht deaktivieren", + "Disabled": "Deaktiviert", + "Documentation": "Dokumentation", + "Don't show this anymore": "Nicht erneut anzeigen", + "Double Quote Directory": "Verzeichnisse doppelt quoten Z.B. bei Verzeichnissen mit Leerzeichen sinnvoll, da es bei diesen zu Abstürzen kommen kann.", + "Down": "Nach unten URL-Adresse", + "Down Stop": "Nach unten-Stopp URL-Adresse", + "Download": "Download", + "EU": "EU", + "Edit": "Bearbeiten", + "Email": "E-Mail", + "Email Details": "E-Mail-Details", + "Email on No Motion": "E-Mail bei \"Keine Bewegung\"", + "Email on Trigger": "E-Mail beim Trigger - E-Mails werden an dem Haupt-Account-Inhaber geschickt.", + "Enable Night Vision": "Nachtsicht aktivieren - URL-Adresse", + "Enable Nightvision": "Nachtsicht aktivieren", + "Enabled": "Aktiviert", + "End": "Ende", + "End Time": "Endzeit", + "Ended": "Beendet", + "Enlarge": "Vergrößern", + "Enter this code to proceed": "Geben Sie bitte diesen Code ein um fortzufahren.", + "Equal to": "Gleich", + "Error Connecting": "Fehler bei der Verbindung", + "Event": "Ereignis", + "Event Limit": "Max. Anzahl der Ereignisse", + "EventText1": "Ein Bewegungsereignis wurde ausgelöst.", + "EventText2": "Konnte die E-Mail nicht versenden, der Zugriff auf die Datei war nicht möglich.", + "Events": "Ereignisse", + "Example": "Beispiel", + "Execute Command": "Befehl ausführen", + "Executed": "Ausgeführt", + "Export": "Export", + "FFmpegCantStart": "Der FFmpeg-Prozess konnte nicht gestartet werden.", + "FFmpegCantStartText": "Die Recording-Engine (FFmpeg) für diese Kamera konnte nicht gestartet werden. Möglicherweise ist die Kamera-Konfiguration falsch. Bitte in den Logs nachschauen und diese ggf. in Issues auf Github veröffentlichen.", + "FFmpegTip": "FFprobe ist ein Multimedia-Stream-Analyser. Sie können es verwenden, um Informationen über den Streamtyp, -Dauer, -Bildrate, -Bildgröße, usw. zu erhalten.", + "FFprobe": "FFprobe", + "FactorAuthText1": "Diese Code ist 15 Minuten aktiv. Nach der Anmeldung, wird der Timer für den gleichen Code um weitere 15 Minuten verlängert.", + "Fatal": "Fatal", + "Fatal Maximum Reached": "Max. Verbindungsversuche erreicht, die Kamera wird gestoppt.", + "FatalMaximumReachedText": "Max. Verbindungsversuche erreicht.", + "Feed-in Image Height": "Feed-in-Bildhöhe", + "Feed-in Image Width": "Feed-in-Bildbreite", + "Fields cannot be empty": "Die Felder dürfen nicht leer sein.", + "File Not Exist": "Datei nicht vorhanden.", + "File Not Found": "Datei nicht gefunden.", + "File Type": "Dateityp", + "FileNotExistText": "Die Datei konnte nicht gespeichert werden, die Datei existiert nicht mehr.", + "Filename": "Dateiname", + "Filesize": "Dateigröße", + "Filter ID": "Filter-ID", + "Filter Matches": "Filter-Bedingung", + "Filter Name": "Filter-Name", + "FilterMatchesText1": "Die Filter-Bedingung war erfüllt.", + "FilterMatchesText2": "Videos gefunden.", + "Filters": "Filter", + "Filters Updated": "Filter aktualisiert", + "FiltersUpdatedText": "Ihre Änderungen wurden gespeichert und angewendet.", + "Find Where": "Suchort", + "Fix": "Reparieren", + "Fix Video": "Video reparieren", + "FixVideoMsg": "Dieses Video reparieren? Diese Aktion kann nicht rückgängig gemacht werden.", + "Font Path": "Schrift-Pfad", + "Font Size": "Schriftgröße", + "Force Port": "Port forcieren", + "Found Devices": "Gefundene Geräte", + "Frame Rate": "Bildrate (Bilder pro Sekunde)", + "Full Frame Detection": "Vollbilder erkennen", + "Fullscreen": "Vollbild", + "Greater Than": "Größer als", + "Greater Than or Equal to": "Größer als oder gleich", + "Group Key": "Gruppen-Schlüssel", + "Group Name": "Gruppenname", + "Grouping": "Gruppierung ", + "H.264 / H.265 / H.265+": "H.264 / H.265 / H.265+", + "HLS (.m3u8)": "HLS - (.m3u8)", + "HLS (includes Audio)": "HLS (mit Audio)", + "HLS Audio Encoder": "HLS-Audio-Encoder", + "HLS List Size": "HLS-Listen-Größe", + "HLS Preset": "HLS-Preset", + "HLS Segment Length": "HLS-Segment-Länge in Sekunden", + "HLS Video Encoder": "HLS-Video-Encoder", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "Height": "Höhe", + "Help": "Hilfe", + "Hide List": "Liste ausblenden", + "Hide Notes": "Meldungen auszublenden", + "Host": "Host", + "Hotswap Modes (Watch-Only)": "Hotswap-Mode (Betrachtungsmodus)", + "How to Record": "Aufnahmeart", + "IP Address": "IP-Adresse", + "Identity": "Identität", + "IdentityText1": "Mit dieser ID wird ein Monitor eindeutig identifiziert. Sie können es nicht nachträglich ändern. Tipp: Verwenden Sie für die Monitor-ID eine für Menschen gut lesbare Bezeichnung, z.B. Parkplatz.", + "IdentityText2": "Sie können einen Monitor dadurch duplizieren (klonen), indem Sie die Monitor-ID ändern und anschließend speichern. Wenn Sie hingegen eine bereits vorhandene Monitor-ID verwenden, wird der entsprechende Monitor überschrieben.", + "Idle": "Im Leerlauf", + "Image Height": "Bildhöhe", + "Image Location": "Bild-Pfad Absoluter Pfad, oder leer lassen, um die globale Einstellung zu übernehmen", + "Image Position": "Bild-Position", + "Image Width": "Bildbreite", + "Import": "Import", + "Import Monitor Configuration": "Monitor-Konfiguration importieren", + "ImportMonitorConfigurationText": "Dadurch werden nicht gespeicherte änderungen überschrieben. Importierte Änderungen werden nur dann angewendet, wenn Sie Speichern drücken.", + "In": "In", + "Incorrect Settings Chosen": "Falsche Einstellungen gewählt", + "Indifference": "Erkennungsschwelle", + "Input": "Eingang", + "Input Flags": "Eingang-Flags", + "Input Type": "Input-Typ", + "InputText1": "Hier wird festgelegt, wie der Kamera-Stream verarbeitet wird. Für eine optimale Leistung, müssen manchmal die internen Kamera-Einstellungen angepasst werden. Die Kamera kann auch über den eingebauten ONVIF-Scanner gefunden werden. Einige ONVIF-Kameras müssen im dazu Vorfeld mit einem Hersteller-Tool angepasst werden. Hilfreiches Tool: ONVIF Device Manager für Windows.", + "InputText2": "
  • Bildrate (Bilder pro Sekunde) : Hoch : 10-15 B/s, Niedrig : 2-5 B/s
  • I-frame-Interval : 80
  • Bit-Raten-Typ : CBR (Konstante Bitrate)
  • Bitrate : zwischen 256 Kbps - 500 Kbps
", + "InputText3": "Wenn Sie Hilfe bei der Bestimmung der Kamera-Parameter benötigen, werfen Sie einen Blick auf die Kamera-URL-Liste auf der Shinobi-Website.", + "Invalid JSON": "Ungültiges JSON-Fragment", + "InvalidJSONText": "Bitte sicherstellen, dass ein Gültiger JSON-Fragment mit der Shinobi-Monitor-Konfiguration benutzt wird.", + "JPEG": "JPEG", + "JPEG (Auto Enables JPEG API)": "JPEG (aktiviert die JPEG-API)", + "JPEG API": "JPEG-API - Snapshot (cgi-bin)", + "JPEG Error": "JPEG-Fehler", + "JPEG Mode": "Im JPEG-Modus", + "JPEGErrorText": "Ein Fehler beim Abrufen der Kamera-Daten ist aufgetreten.", + "Leave blank for random.": "Leer lassen für einen zufälligen Wert.", + "Left": "Nach links URL-Adresse", + "Left Stop": "Nach links-Stopp URL-Adresse", + "Less Than": "Weniger als", + "Less Than or Equal to": "Weniger als oder gleich", + "Like": "Wie", + "Lisence Plate Detector": "Kfz-Kennzeichen-Detektor", + "List Toggle": "Liste umschalten", + "Live Stream Toggle": "Live-Stream umschalten", + "Live View": "Live-Ansicht", + "Local": "Lokal", + "Log Level": "Log-Level", + "Log Signal Event": "Logge Signal-Ereignisse nur Client-Seite", + "Logging": "Logging", + "Login": "Login", + "Logout": "Logout", + "Logs": "Logs", + "MB": "MB", + "MJPEG": "MJPEG", + "MP4 (copy, libx264, libx265)": "MP4 (kopieren, libx264, libx265)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)", + "MailError": "E-Mail-Fehler: Es Konnte keine E-Mail versendet werden. Bitte die conf.json überprüfen. Alle E-Mail-Funktionen werden vorübergehend deaktiviert.", + "Matches": "Trifft zu", + "Max Storage Amount": "Max Speichermenge in MB", + "Mode": "Modus", + "Monitor": "Monitor", + "Monitor Added by user": "Monitor durch Benutzer hinzugefügt.", + "Monitor Capture Rate": "Monitor Bildrate (Bilder pro Sekunde)", + "Monitor Groups": "Monitor-Gruppen", + "Monitor ID": "Monitor-ID", + "Monitor Idling": "Monitor im Leerlauf", + "Monitor Name": "Monitor Name", + "Monitor Settings": "Monitor-Einstellungen", + "Monitor Stopped": "Monitor gestoppt", + "Monitor Updated by user": "Monitor durch den Benutzer aktualisiert.", + "Monitor mode changed": "Monitor-Modus geändert", + "Monitor mode is already": "Monitor-Modus ist bereits", + "Monitor or Key does not exist.": "Monitor oder Schlüssel nicht vorhanden.", + "MonitorIdlingText": "Der Monitor wurde in den Leerlauf geschaltet.", + "MonitorStoppedText": "Der Monitor wurde gestoppt.", + "Monitors": "Monitore", + "Monitors per row": "Monitore pro Zeile in der Montage-Ansicht", + "Montage": "Montage", + "Motion GUI": "Motion-GUI", + "Motion Meter": "Bewegungsindikator", + "Name": "Name", + "No": "Keine", + "No Audio": "Kein Audio", + "No Data": "Keine Daten", + "No Events found for this video": "Keine Ereignisse für dieses Video gefunden.", + "No Group with this key exists": "Keine Gruppe mit diesem Schlüssel vorhanden.", + "No Monitor Found, Ignoring Request": "Kein Monitor gefunden, ignoriere Anfrage.", + "No Rotation": "Keine Rotation", + "No such file": "Keine solche Datei", + "NoMotionEmailText1": "Keine Bewegung", + "NoMotionEmailText2": "Es wurden keine Bewegungen für die Kamera erkannt für", + "NoVideosFoundForDateRange": "Keine Videos in diesem Zeitraum gefunden. Eventuell das Start-Datum weiter zurück stellen.", + "Not Authorized": "Nicht autorisiert", + "Not Connected": "Nicht verbunden", + "Not Equal to": "Ungleich", + "Not In": "Nicht in", + "Not Matches": "Trifft nicht zu", + "Not Permitted": "Nicht erlaubt", + "Not an Administrator Account": "Kein Administrator-Konto", + "NotAuthorizedText1": "Sie sind nicht berechtigt, init-Befehle mit \"auth\",\"ke\" und \"uid\" zu senden.", + "Notes": "Hinweise", + "NotesPlacholder": "Ihre Kommentare zu diesen Kamera-Einstellungen", + "Number of Days to keep": "Für die Anzahl von Tagen behalten", + "ONVIF": "ONVIF", + "ONVIF Scanner": "ONVIF-Scanner", + "ONVIFnote": "Leer lassen, um ONVIF-Geräte im eigenen Netzwerk zu suchen. Netzwerk spezifizieren, für Suchen außerhalb des eigenen Netzwerks.
Benutzername und Kennwort können leer gelassen werden.", + "OpenCV Cascades": "OpenCV-Kaskaden", + "Order Streams": "Streams ordnen", + "Output Method": "Ausgabe-Methode", + "Password": "Passwort", + "Password Again": "Passwort (Wiederh.)", + "Passwords don't match": "Die Passwörter stimmen nicht überein.", + "Paste JSON here.": "Fügen Sie hier ein JSON-Fragment ein.", + "Path": "Pfad", + "Permissions": "Berechtigungen", + "Points": "Punkte Um weitere Punkte hinzuzufügen, klicken Sie bitte auf den Rand des Polygons.", + "Port": "Port", + "Position X": "Position X", + "Position Y": "Position Y", + "Power Video Viewer": "Power-Video-Viewer", + "Power Viewer": "Power-Viewer", + "Preferences": "Einstellungen", + "Preset": "Voreinstellung", + "Probe Size": "Probe-Größe", + "Process Crashed for Monitor": "Der Prozess für den Monitor ist abgestürzt", + "Process Unexpected Exit": "Der Prozess wurde unerwartet beendet.", + "Profile": "Profil", + "Quality": "Qualität 1 = hoch, 23 = gering", + "Query": "Query", + "RAM": "RAM", + "RTSP": "RTSP", + "RTSP Transport": "RTSP-Transport", + "Range or Single": "Bereich oder Einzeln", + "Rate": "Bildrate (Bilder pro Sekunde)", + "Record": "Aufnahme", + "Record File Type": "Datei-Typ (Aufnahme)", + "Record Height": "Bidhöhe (Aufnahme)", + "Record Video Filter": "Video-Filter (Aufnahme)", + "Record Width": "Bildbreite (Aufnahme)", + "Recording": "Aufnahme", + "Recording Flags": "Aufnahme-Flags", + "Recording Segment Interval": "Aufnahme-Dauer pro Segment in Minuten", + "Recording Timeout": "Aufnahme-Timeout in Minuten", + "Recording Timestamp": "Aufnahme-Zeitstempel", + "Recording Watermark": "Aufnahme-Wasserzeichen", + "RecordingText": "", + "Refresh List of Cascades": "Liste der Kaskaden einlesen", + "Region Editor": "Region-Editor", + "Region Name": "Name der Region", + "RegionNote": "Die hier definierten Punkte werden erst dann gespeichert, wenn Sie auf Speichern im Fenster Monitor-Einstellungen klicken.", + "Regions": "Regionen", + "Remember Me": "Merken", + "Reset Timer": "Reset-Timer", + "Restarting Process": "Der Prozess wird neu gestartet.", + "Retry Connection": "Verbindungsversuche Maximale Anzahl von Verbindungsversuchen. 0 = unendlich", + "Retrying...": "Erneuter Versuch...", + "Right": "Nach rechts URL-Adresse", + "Right Stop": "Nach rechts-Stopp URL-Adresse", + "Rotate": "Drehen", + "Save": "Speichern", + "Save Directory": "Verzeichnis Speichern", + "Save Events to SQL": "Ereignisse in der Datenbank speichern", + "Save Log in SQL": "Log in der Datenbank speichernAchtung: Die Datenbank kann dabei sehr schnell groß werden.", + "Save as": "Speichern als", + "Saved Filters": "Gespeicherte Filter", + "Scan Settings": "Scan-Einstellungen", + "Search": "Suche", + "Send Frames": "Bilddaten zum Detektor senden Bilddaten werden analysiert", + "Separate with commas, no spaces": "Getrennt mit Kommas, ohne Leerzeichen", + "Set to Watch Only": "Aufnahme beenden", + "Settings": "Einstellungen", + "Settings Changed": "Einstellungen geändert", + "SettingsChangedText": "Die Einstellungen wurden gespeichert und angewendet.", + "Shinobi": "Shinobi", + "Shinobi Streamer": "Shinobi-Streamer", + "Show Logs": "Logs anzeigen", + "Silent": "Still", + "Simple": "Einfach", + "Size (mb)": "Größe (MB)", + "Snapshot": "Snapshot", + "Snapshot Flags": "Snapshot-Flags", + "Snapshots": "Snapshots", + "Sort By": "Sortieren nach", + "Start": "Starten", + "Start Recording": "Aufnahme starten", + "Start Time": "Startzeit", + "Started": "Gestartet", + "Status Indicator": "Statusanzeige", + "Stop URL": "Stop-URL", + "Stream": "Stream", + "Stream Flags": "Stream-Flags", + "Stream Timestamp": "Stream-Timestamp", + "Stream Type": "Stream-Typ", + "Stream Watermark": "Stream-Wasserzeichen", + "Stream to YouTube": "Stream zu YouTube schicken", + "Stream to YouTube Flags": "YouTube-Flags", + "StreamText": "

Dieser Abschnitt legt die primäre Stream-Methode und ihre Einstellungen fest. Dieser Stream wird im Dashboard angezeigt. Wenn Sie HLS, JPEG oder MJPEG verwenden, können Sie den Stream durch andere Programme nutzen.

Beim JPEG-Stream wird der primäre Stream abgeschaltet und stattdessen den Snapshot-Modus verwendet.

", + "Streamer": "Streamer", + "Streams": "Streams", + "Superuser": "Superuser", + "Switch on for Still Image": "Schalter für Standbild", + "TCP": "TCP", + "Text Box Color": "Textbox-Farbe", + "Text Color": "Textfarbe", + "Time-lapse": "Zeitraffer", + "Time-lapse Tool": "Zeitraffer-Werkzeug", + "Timeout": "Timeout", + "Timeout Reset on Next Motion": "Timeout-Zähler bei nächster Bewegung zurücksetzen", + "Toggle Sidebar": "Sidebar umschalten", + "Top Left": "Oben links", + "Top Right": "Oben rechts", + "Trigger Record": "Aufzeichnung triggern", + "Trigger Successful": "Trigger erfolgreich", + "UDP": "UDP", + "URL": "URL", + "URL Stop Timeout": "Stopp-URL-Timeout Ruft die Stopp-URL nach X Millisekunden auf", + "US": "US", + "Unable to Launch": "Konnte nicht starten", + "UnabletoLaunchText": "Bitte speichern Sie zuerst die neuen Monitor-Einstellungen. Danach steht der Region-Editor zur Verfügung.", + "Up": "Nach oben URL-Adresse", + "Up Stop": "Nach oben-Stopp URL-Adresse", + "Username": "Benutzername", + "Value": "Wert", + "Video": "Video", + "Video Codec": "Video-Codec", + "Video Filter": "Video-Filter", + "Video Finished": "Das Video ist fertig.", + "Video Length (minutes) and Motion Count per video": "Video-Länge (in Minuten) und Bewegungsanzahl pro video", + "Video Record Rate": "Video-Aufnahme-Rate (Bilder pro Sekunde)", + "Video Status": "Video-Status", + "Video and Time Span (Minutes)": "Video und Zeitspanne (in Minuten)", + "Videos": "Videos", + "Videos List": "Video-Liste", + "Watch": "Anschauen", + "Watch Only": "Nur Anschauen", + "WebDAV": "WebDAV", + "WebM (libvpx)": "WebM (libvpx)", + "Webdav Error": "WebDAV-Fehler", + "WebdavErrorText": "Kann nicht speichern. Bitte überprüfen, ob die Kamera-Ordner im gewählten Verzeichnis angelegt sind.", + "Webhook": "Webhook", + "Webhook URL": "Webhook-URL", + "Width": "Breite", + "Yes": "Ja", + "Zoom In": "Zoom-In URL-Adresse", + "Zoom In Stop": "Zoom-In Stopp URL-Adresse", + "Zoom Out": "Zoom-Out URL-Adresse", + "Zoom Out Stop": "Zoom-Out Stopp URL-Adresse", + "a day": "einen Tag", + "a few seconds": "ein paar Sekunden", + "a minute": "eine Minute", + "a month": "einen Monat", + "a year": "ein Jahr", + "aac": "aac", + "aac (Default)": "aac (Standard)", + "ac3": "ac3", + "ago": "vor", + "an hour": "eine Stunde", + "blankPassword": "Leer lassen, um das gleiche Passwort zu verwenden.", + "calendar": "Kalender", + "clientStreamFailedattemptingReconnect": "Client-seitiger Stream-Check fehlgeschlagen. Erneuter Versuch...", + "confirmDeleteFilter": "Wollen Sie diesen Filter wirklich löschen? Sie können ihn nicht mehr wiederherstellen.", + "copy": "kopieren", + "days": "Tage", + "dropBoxSuccess": "Die Dateien wurden erfolgreich in der Dropbox gespeichert.", + "for Global Access": "Für den weltweiten Zugriff", + "hours": "Stunden", + "in": "in", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis (Standard)", + "libvpx (Default)": "libvpx (Standard)", + "libvpx-vp9": "libvpx-vp9", + "libx264": "libx264", + "libx264 (Default)": "libx264 (Standard)", + "libx265": "libx265", + "minutes": "Minuten", + "modifyVideoText1": "Die Methode ist nicht vorhanden. Bitte sicherstellen, dass der letzte Wert der URL nicht leer ist.", + "monitorEditFailedMaxReached": "Die maximale Anzahl von Kameras wurde erreicht. Zum Erhöhen des Wertes wenden Sie sich an Ihren Administrator.", + "monitorEditText1": "Ungültige Daten. Bitte einen gültigen Import-String eingeben.", + "monitorEditText2": "Ungültiger Details-String. Bitte einen gültigen JSON-String eingeben.", + "monitorGetText1": "Unvollständiger Request. Entweder den Schrägstrich am Ende entfernen oder einen gültigen Wert setzen.", + "months": "Monate", + "noSpecialCharacters": "Es dürfen keine Leerzeichen oder Sonderzeichen enthalten sein.", + "on": "auf", + "on Error": "bei Fehlern", + "startUpText0": "Größe der Videos überprüfen", + "startUpText1": "Größe der Videos überprüft", + "startUpText2": "Alle Benutzer überprüft. Bitte warten, geöffnete Dateien werden geschlossen und Dateien über Benutzer-Limit werden entfernt.", + "startUpText3": "Warte weitere 3 Sekunden auf den Abschluss der Überprüfung.", + "startUpText4": "Starte alle Monitore.", + "startUpText5": "Shinobi ist bereit.", + "superAdminText": "\"super.json\" ist nicht vorhanden. Die Datei \"super.Probe.json\" kann als Vorlage für \"super.json\" verwendet werden.", + "superAdminTitle": "Shinobi : Super Admin", + "total": "insgesamt", + "undefined": "nicht definiert", + "updateKeyText1": "Kein \"updateKey\" in \"conf.json\" vorhanden. Es werden keine Updates durchgeführt.", + "updateKeyText2": "\"updateKey\" ist falsch.", + "years": "Jahre" +} diff --git a/languages/en_CA.json b/languages/en_CA.json new file mode 100644 index 0000000..5fed55e --- /dev/null +++ b/languages/en_CA.json @@ -0,0 +1,695 @@ +{ + "Shinobi": "Shinobi", + "superAdminTitle": "Shinobi : Super Admin", + "Login": "Login", + "Authenticate": "Authenticate", + "Dashboard": "Dashboard", + "Streamer": "Streamer", + "Admin": "Admin", + "Superuser": "Superuser", + "Dashcam": "Dashcam", + "Email": "Email", + "Username": "Username", + "Profile": "Profile", + "Password": "Password", + "Password Again": "Password Again", + "Remember Me": "Remember Me", + "RAM": "RAM", + "CPU": "CPU", + "on": "on", + "Power Viewer": "Power Viewer", + "Power Video Viewer": "Power Video Viewer", + "Time-lapse": "Time-lapse", + "Montage": "Montage", + "Accounts": "Accounts", + "Settings": "Settings", + "Recording FPS": "Recording FPS", + "Input Selector": "Input Selector", + "Input Settings": "Input Settings", + "Connection": "Connection", + "API": "API", + "ONVIF": "ONVIF", + "FFprobe": "Probe", + "Filters": "Filters", + "Full URL Path": "Full URL Path", + "Logs": "Logs", + "Full Stream URL": "Full Stream URL", + "Manual": "Manual", + "List Toggle": "List Toggle", + "Hide List": "Hide List", + "Motion GUI": "Motion GUI", + "Motion": "Motion", + "Global Detector Settings": "Global Detector Settings", + "Motion Detection": "Motion Detection", + "Object Detection": "Object Detection", + "JPEG Mode": "JPEG Mode", + "Order Streams": "Order Streams", + "Hide Notes": "Hide Notes", + "Example": "Example", + "Logout": "Logout", + "Closed": "Closed", + "Ended": "Ended", + "Options": "Options", + "Started": "Started", + "Monitor": "Monitor", + "Filename": "Filename", + "Size (mb)": "Size (mb)", + "Watch": "Watch", + "Download": "Download", + "Delete": "Delete", + "Fix": "Fix", + "Use HTML5 Play Method": "Use HTML5 Play Method", + "Connection timed out": "Connection timed out", + "skipPingText1": "Try setting \"Skip Ping\" to Yes.", + "Ping Failed": "Ping Failed", + "Zoom In": "Zoom In URL Address", + "Zoom Out": "Zoom Out URL Address", + "Enable Nightvision": "Enable Nightvision", + "Disable Nightvision": "Disable Nightvision", + "Current": "Current", + "Monitors": "Monitors", + "Video": "Video", + "Themes": "Themes", + "Videos": "Videos", + "Events": "Events", + "Streams": "Streams", + "Snapshot": "Snapshot", + "Snapshots": "Snapshots", + "Date Range": "Date Range", + "Event Limit": "Event Limit", + "No Data": "No Data", + "Live View": "Live View", + "New Monitor": "New Monitor", + "Please Check Your Settings": "Please Check Your Settings", + "migrateText1": "Input Type could not be parsed. Please set it manually.", + "Add": "Add", + "Save": "Save", + "Close": "Close", + "Secure": "Secure", + "Check": "Check", + "Stop": "Stop", + "Confirm": "Confirm", + "Enable": "Enable", + "Enabled": "Enabled", + "API Key": "API Key", + "API Keys": "API Keys", + "Group Key": "Group Key", + "Allowed IPs": "Allowed IPs", + "Separate with commas, no spaces": "Separate with commas, no spaces", + "Can Get Monitors": "Can Get Monitors", + "Can Get Logs": "Can Get Logs", + "Can Authenticate Websocket": "Can Authenticate Websocket", + "Can Control Monitors": "Can Control Monitors", + "Can View Snapshots": "Can View Snapshots", + "Can View Streams": "Can View Streams", + "Can View Videos": "Can View Videos", + "Can View Monitor": "Can View Monitor", + "Can Edit Monitor": "Can Edit Monitor", + "Can Delete Videos": "Can Delete Videos", + "Delete Video": "Delete Video", + "Can View Videos and Events": "Can View Videos and Events", + "Can Delete Videos and Events": "Can Delete Videos and Events", + "Saved Filters": "Saved Filters", + "Filter Name": "Filter Name", + "Find Where": "Find Where", + "Sort By": "Sort By", + "Start Time": "Start Time", + "End Time": "End Time", + "Monitor ID": "Monitor ID", + "File Type": "File Type", + "Filesize": "Filesize", + "Video Status": "Video Status", + "Preferences": "Preferences", + "Equal to": "Equal to", + "Not Equal to": "Not Equal to", + "Greater Than or Equal to": "Greater Than or Equal to", + "Greater Than": "Greater Than", + "Less Than": "Less Than", + "Less Than or Equal to": "Less Than or Equal to", + "Like": "Like", + "Matches": "Matches", + "Not Matches": "Not Matches", + "In": "In", + "Not In": "Not In", + "ASC": "ASC", + "DESC": "DESC", + "Action for Selected": "Action for Selected", + "Search": "Search", + "No": "No", + "Yes": "Yes", + "Start": "Start", + "End": "End", + "Archive": "Archive", + "Email Details": "Email Details", + "Delete Matches": "Delete Matches", + "Delete selected": "Delete selected", + "Execute Command": "Execute Command", + "for Global Access": "for Global Access", + "Help": "Help", + "Don't show this anymore": "Don't show this anymore", + "Chat on Discord": "Chat on Discord", + "Documentation": "Documentation", + "All Monitors": "All Monitors", + "Motion Meter": "Motion Meter", + "FFmpegTip": "FFprobe is a simple multimedia streams analyzer. You can use it to output all kinds of information about an input including duration, frame rate, frame size, etc.", + "Complete Stream URL": "Complete Stream URL", + "ONVIF Scanner": "ONVIF Scanner", + "Scan Settings": "Scan Settings", + "ONVIFnote": "Discover ONVIF devices on networks outside your own or leave it blank to scan your current network.
Username and Password can be left blank.", + "Range or Single": "Range or Single", + "IP Address": "IP Address", + "Port": "Port", + "Camera Username": "Camera Username", + "Camera Password": "Camera Password", + "Found Devices": "Found Devices", + "Switch on for Still Image": "Switch on for Still Image", + "Live Stream Toggle": "Live Stream Toggle", + "RegionNote": "Points are only saved when you press Save on the Monitor Settings window.", + "Points": "Points When adding points click on the edge of the polygon.", + "Indifference": "Indifference", + "Region Name": "Region Name", + "Regions": "Regions", + "Again": "Again", + "Account Info": "Account Info", + "blankPassword": "Leave blank to keep same password", + "2-Factor Authentication": "2-Factor Authentication", + "Max Storage Amount": "Max Storage Amount in Megabytes", + "Number of Days to keep": "Number of Days to keep", + "Monitor Groups": "Monitor Groups", + "Group Name": "Group Name", + "WebDAV": "WebDAV", + "URL": "URL", + "Autosave": "Autosave", + "Save Directory": "Save Directory", + "CSS": "CSS Style your dashboard.", + "Force Monitors Per Row": "Force Monitors Per Row", + "Monitors per row": "Monitors per row for Montage", + "Browser Console Log": "Browser Console Log", + "All Monitors and Privileges": "All Monitors and Privileges", + "Permissions": "Permissions", + "Time-lapse Tool": "Time-lapse Tool", + "total": "total", + "MB": "MB", + "Calendar": "Calendar", + "Leave blank for random.": "Leave blank for random.", + "Currently viewing": "Currently viewing", + "Status Indicator": "Status Indicator", + "Show Logs": "Show Logs", + "Videos List": "Videos List", + "Monitor Settings": "Monitor Settings", + "Enlarge": "Enlarge", + "Fullscreen": "Fullscreen", + "Value": "Value", + "Idle": "Idle", + "Disabled": "Disabled", + "Record": "Record", + "Watch Only": "Watch Only", + "Toggle Sidebar": "Toggle Sidebar", + "Add Monitor": "Add Monitor", + "Start Recording": "Start Recording", + "Set to Watch Only": "Set to Watch Only", + "Save as": "Save as", + "Add New": "Add New", + "Delete Selected Videos": "Delete Selected Videos", + "DeleteSelectedVideosMsg": "Do you want to delete these videos? You cannot recover them.", + "clientStreamFailedattemptingReconnect": "Client side ctream check failed, attempting reconnect.", + "Delete Filter": "Delete Filter", + "confirmDeleteFilter": "Do you want to delete this filter? You cannot recover it.", + "Fix Video": "Fix Video", + "FixVideoMsg": "Do you want to fix this video? You cannot undo this action.", + "DeleteVideoMsg": "Do you want to delete this video? You cannot recover it.", + "dropBoxSuccess": "Success! Files saved to your Dropbox.", + "API Key Deleted": "API Key Deleted", + "APIKeyDeletedText": "Key has been deleted. It will no longer work.", + "API Key Added": "API Key Added", + "APIKeyAddedText": "You may use this key now.", + "Update": "Update", + "Update to Master": "Update to Master", + "Update to Development": "Update to Development", + "Filters Updated": "Filters Updated", + "FiltersUpdatedText": "Your changes have been saved and applied.", + "Settings Changed": "Settings Changed", + "SettingsChangedText": "Your settings have been saved and applied. Some settings may require a refresh of this page.", + "Are you sure?": "Are you sure?", + "Import Monitor Configuration": "Import Monitor Configuration", + "ImportMultiMonitorConfigurationText": "Doing this will overrwrite any monitors with IDs existing in the import file.", + "ImportMonitorConfigurationText": "Doing this will overrwrite any changes currently not saved. Imported changes will only be applied when you press Save.", + "Paste JSON here.": "Paste JSON here.", + "Delete Monitor": "Delete Monitor", + "DeleteMonitorText": "Do you want to delete this monitor? You cannot recover it. The files for this ID will remain in the filesystem. If you choose to recreate a monitor with the same ID the videos and events will become visible in the dashboard.", + "DeleteMonitorsText": "Do you want to delete these monitors? You cannot recover them. The files for these IDs will remain in the filesystem. If you choose to recreate a monitor with one of the IDs the videos and events will become visible in the dashboard.", + "Invalid JSON": "Invalid JSON", + "InvalidJSONText": "Please ensure this is a valid JSON string for Shinobi monitor configuration.", + "Passwords don't match": "Passwords don't match", + "No Events found for this video": "No Events found for this video", + "Video and Time Span (Minutes)": "Video and Time Span (Minutes)", + "Video Length (minutes) and Motion Count per video": "Video Length (minutes) and Motion Count per video", + "Counts of Motion": "Counts of Motion", + "Unable to Launch": "Unable to Launch", + "UnabletoLaunchText": "Please save new monitor first. Then attempt to launch the region editor.", + "NoVideosFoundForDateRange": "No Videos found in this date range. Try setting the start date further back.", + "monitorEditFailedMaxReached": "Your account has reached the maximum number of cameras that can be created. Speak to an administrator if you would like this changed.", + "in": "in", + "ago": "ago", + "a few seconds": "a few seconds", + "a minute": "a minute", + "minutes": "minutes", + "an hour": "an hour", + "hours": "hours", + "a day": "a day", + "days": "days", + "a month": "a month", + "months": "months", + "a year": "a year", + "years": "years", + "Identity": "Identity", + "Input": "Input", + "Input Feed": "Input Feed", + "Stream": "Stream", + "Stream Timestamp": "Stream Timestamp", + "Stream Watermark": "Stream Watermark", + "JPEG API": "JPEG API Snapshot (cgi-bin)", + "Raw H.264 Stream": "Raw H.264 Stream", + "Recording": "Recording", + "Recording Timestamp": "Recording Timestamp", + "Recording Watermark": "Recording Watermark", + "Region Editor": "Region Editor", + "Custom": "Custom", + "Detector": "Detector", + "Connected": "Connected", + "Not Saved": "Not Saved", + "Not Connected": "Not Connected", + "Lisence Plate Detector": "Lisence Plate Detector", + "OpenCV Cascades": "OpenCV Cascades", + "Refresh List of Cascades": "Refresh List of Cascades", + "\"No Motion\" Detector": "\"No Motion\" Detector", + "Control": "Control", + "Grouping": "Grouping Add groups in Settings", + "Detector Grouping": "Detector Grouping Add groups in Settings", + "Logging": "Logging", + "IdentityText1": "This is how the system will identify the data for this stream. You cannot change the Monitor ID once you have pressed save. If you want you can make the Monitor ID more human readable before you continue.", + "IdentityText2": "You can duplicate a monitor by modifying the Monitor ID then pressing save. You cannot use the ID of a monitor that already exists or it will save over that monitor's database information.", + "noSpecialCharacters": "No spaces or special characters.", + "NotesPlacholder": "Comments you want to leave for this cameras settings.", + "InputText1": "This section tells Shinobi how to consume a stream. For optimal performance try tuning your camera's internal settings. Find the following options and set them as shown. To find your camera you can use the built in ONVIF Scanner of Shinobi. Some ONVIF cameras require the use of a management tool to modify their internal settings. If you can't find your cameras you can try ONVIF Device Manager for Windows.", + "InputText2": "
  • Framerate (FPS) : High : 10 - 15 FPS, Low : 2-5 FPS
  • I-frame interval : 80
  • Bit Rate Type : CBR (Constant Bit Rate)
  • Bit Rate : between 256kbps - 500kbps
", + "InputText3": "If you need help figuring out what input type your camera is you can take a look in the Camera URLs List on the Shinobi website.", + "StreamText": "

This section will designate the primary method of streaming out and its settings. This stream will be displayed in the dashboard. If you choose to use HLS, JPEG, or MJPEG then you can consume the stream through other programs.

Using JPEG stream essentially turns off the primary stream and uses the snapshot bin to get frames.

", + "DetectorText": "

When the Width and Height boxes are shown you should set them to 640x480 or below. This will optimize the read speed of frames.

", + "RecordingText": "It is recommended that you set Record File Type to WebMMP4 and Video Codec to libvpxcopy or libx264 because your Input Type is set to .", + "Mode": "Mode", + "Name": "Name", + "Skip Ping": "Skip Ping", + "Retry Connection": "Retry Connection Number of times allowed to fail", + "Notes": "Notes", + "Input Type": "Input Type", + "Connection Type": "Connection Type", + "RTSP Transport": "RTSP Transport", + "Host": "Host", + "Force Port": "Force Port", + "Path": "Path", + "Monitor Capture Rate": "Monitor Capture Rate (FPS)", + "Analyzation Duration": "Analyzation Duration", + "Probe Size": "Probe Size", + "Stream Type": "Stream Type", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "HLS Video Encoder": "Video Encoder", + "HLS Audio Encoder": "Audio Encoder", + "HLS Segment Length": "Segment Length in Seconds", + "HLS Preset": "Preset Template", + "HLS List Size": "List Size", + "Traditional Recording": "Traditional Recording", + "Buffer Preview": "Buffer Preview", + "HLS Start Number": "HLS Start Number", + "HLS Live Start Index": "HLS Live Start Index", + "Check Signal Interval": "Check Signal Interval in Minutes", + "Log Signal Event": "Log Signal Event Client side only", + "Quality": "Quality 1 is High, 23 is Low", + "Rate": "Rate (FPS)", + "Width": "Width", + "Height": "Height", + "Rotate": "Rotate", + "Primary Engine": "Primary Engine", + "Video Filter": "Video Filter", + "Font Path": "Font Path", + "Font Size": "Font Size", + "Text Color": "Text Color", + "Text Box Color": "Text Box Color", + "Position X": "Position X", + "Position Y": "Position Y", + "Image Location": "Image Location Absolute Path or leave blank to use global", + "Image Position": "Image Position", + "Frame Rate": "Frame Rate (FPS)", + "Image Width": "Image Width", + "Image Height": "Image Height", + "Record File Type": "Record File Type", + "Video Codec": "Video Codec", + "Preset": "Preset", + "Audio Codec": "Audio Codec", + "Video Record Rate": "Video Record Rate (FPS)", + "Record Width": "Record Width", + "Record Height": "Record Height", + "Double Quote Directory": "Double Quote Directory Some directories have spaces. Using this may crash some cameras.", + "Recording Segment Interval": "Recording Segment Interval in minutes", + "Record Video Filter": "Record Video Filter", + "Input Flags": "Input Flags", + "Snapshot Flags": "Snapshot Flags", + "Detector Flags": "Detector Flags", + "Stream Flags": "Stream Flags", + "Stream to YouTube": "Stream to YouTube", + "Stream to YouTube Flags": "Stream to YouTube Flags", + "Recording Flags": "Recording Flags", + "Output Method": "Output Method", + "Webhook": "Webhook", + "Webhook URL": "Webhook URL", + "Command on Trigger": "Command on Trigger", + "Command": "Command", + "Allow Next Command": "Allow Next Command in Minutes", + "Allow Next Trigger": "Allow Next Trigger in Milliseconds", + "Save Events to SQL": "Save Events to SQL", + "Email on Trigger": "Email on Trigger Emails go to the main account holder's login address.", + "Allow Next Email": "Allow Next Email in Minutes", + "How to Record": "How to Record", + "Trigger Record": "Trigger Record", + "Recording Timeout": "Recording Timeout in Minutes", + "Timeout Reset on Next Motion": "Timeout Reset on Next Motion", + "Timeout Reset on Next Event": "Timeout Reset on Next Event", + "Delete Motionless Video": "Delete Motionless Video", + "Send Frames": "Send Frames Push frames to be analyzed", + "Detector Rate": "Detector Rate (FPS)", + "Feed-in Image Width": "Feed-in Image Width", + "Feed-in Image Height": "Feed-in Image Height", + "Check for Motion First": "Check for Motion First", + "Detect Objects": "Detect Objects See below", + "Full Frame Detection": "Full Frame Detection", + "Country of Plates": "Country of Plates", + "Email on No Motion": "Email on \"No Motion\"", + "Timeout": "Timeout", + "Controllable": "Controllable", + "Custom Base URL": "Custom Base URL Leave blank to use Host URL", + "Stop URL": "Stop URL", + "Stop Command": "Stop Command", + "Digest Authentication": "Digest Authentication", + "URL Stop Timeout": "URL Stop Timeout Run stop URL after X milliseconds", + "Center": "Center URL Address", + "Left": "Left URL Address", + "Left Stop": "Left Stop URL Address", + "Right": "Right URL Address", + "Right Stop": "Right Stop URL Address", + "Up": "Up URL Address", + "Up Stop": "Up Stop URL Address", + "Down": "Down URL Address", + "Down Stop": "Down Stop URL Address", + "Enable Night Vision": "Enable Night Vision URL Address", + "Disable Night Vision": "Disable Night Vision URL Address", + "Zoom Out Stop": "Zoom Out Stop URL Address", + "Zoom In Stop": "Zoom In Stop URL Address", + "Log Level": "Log Level", + "Save Log in SQL": "Save Log in SQL This can fill up quickly.", + "JPEG": "JPEG", + "MJPEG": "MJPEG", + "H.264 / H.265 / H.265+": "H.264 / H.265 / H.265+", + "HLS (.m3u8)": "HLS (.m3u8)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)", + "Shinobi Streamer": "Shinobi Streamer", + "Dashcam (Streamer v2)": "Dashcam (Streamer v2)", + "Local": "Local", + "Raw": "Raw", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "RTSP": "RTSP", + "RTMP": "RTMP", + "RTMPS": "RTMPS", + "UDP": "UDP", + "Auto": "Auto", + "TCP": "TCP", + "Base64 over Websocket": "Base64 over Websocket", + "Websocket": "Websocket", + "JPEG (Auto Enables JPEG API)": "JPEG (Auto Enables JPEG API)", + "HLS (includes Audio)": "HLS (includes Audio)", + "MPEG-DASH (includes Audio)": "MPEG-DASH (includes Audio)", + "libx264": "libx264", + "libx265": "libx265", + "copy": "copy", + "No Audio": "No Audio", + "aac": "aac", + "ac3": "ac3", + "libmp3lame": "libmp3lame", + "No Rotation": "No Rotation", + "180 Degrees": "180 Degrees", + "90 Counter Clockwise and Vertical Flip (default)": "90 Counter Clockwise and Vertical Flip (default)", + "90 Clockwise": "90 Clockwise", + "90 Clockwise and Vertical Flip": "90 Clockwise and Vertical Flip", + "Top Right": "Top Right", + "Top Left": "Top Left", + "Bottom Right": "Bottom Right", + "Bottom Left": "Bottom Left", + "WebM (libvpx)": "WebM (libvpx)", + "Poseidon": "Poseidon", + "MP4 (copy, libx264, libx265)": "MP4 (copy, libx264, libx265)", + "Default": "Default", + "libvpx (Default)": "libvpx (Default)", + "libvpx-vp9": "libvpx-vp9", + "libx264 (Default)": "libx264 (Default)", + "libvorbis (Default)": "libvorbis (Default)", + "libopus": "libopus", + "aac (Default)": "aac (Default)", + "Traditional (Watch-Only, Includes Buffer)": "Traditional (Watch-Only, Includes Buffer)", + "Hotswap Modes (Watch-Only)": "Hotswap Modes (Watch-Only)", + "Delete Motionless Videos (Record)": "Delete Motionless Videos (Record)", + "US": "US", + "EU": "EU", + "Silent": "Silent", + "Fatal": "Fatal", + "on Error": "on Error", + "All Warnings": "All Warnings", + "Warning": "Warning", + "Debug": "Debug", + "Export": "Export", + "Import": "Import", + "Simple": "Simple", + "Advanced": "Advanced", + "Error Connecting": "Error Connecting", + "DB Lost.. Retrying..": "Database Lost.. Retrying..", + "Retrying...": "Retrying...", + "Filter Matches": "Filter Matches", + "FilterMatchesText1": "This filter has met conditions.", + "FilterMatchesText2": "videos found.", + "Executed": "Executed", + "Deleted": "Deleted", + "Query": "Query", + "Request": "Request", + "System": "System", + "Restart Core": "Restart Core", + "Restart CRON": "Restart CRON", + "Flush PM2 Logs": "Flush PM2 Logs", + "Filter ID": "Filter ID", + "Webdav Error": "Webdav Error", + "WebdavErrorText": "Cannot save. Did you make the camera folders inside your chosen save directory?", + "File Not Exist": "File Not Exist", + "No Videos Found": "No Videos Found", + "FileNotExistText": "Cannot save non existant file. Something went wrong.", + "CameraNotRecordingText": "Settings may be incompatible. Check encoders. Restarting...", + "Camera is not recording": "Camera is not recording", + "Camera is not streaming": "Camera is not streaming", + "Restarting Process": "Restarting Process", + "Restart": "Restart", + "Monitor Stopped": "Monitor Stopped", + "MonitorStoppedText": "Monitor session has been ordered to stop.", + "Monitor Idling": "Monitor Idling", + "MonitorIdlingText": "Monitor session has been ordered to idle.", + "NoMotionEmailText1": "No Motion for", + "NoMotionEmailText2": "There hasn't been any motion detected on camera for", + "Monitor Name": "Monitor Name", + "Process Unexpected Exit": "Process Unexpected Exit", + "Process Crashed for Monitor": "Process Crashed for Monitor", + "FFmpegCantStart": "FFmpeg Couldn't Start", + "FFmpegCantStartText": "The recording engine for this camera could not start. There may be something wrong with your camera configuration. If there are any logs other than this one please post them in the Issues on Github.", + "JPEG Error": "JPEG Error", + "JPEGErrorText": "There was an issue getting data from your camera.", + "Fatal Maximum Reached": "Fatal Maximum Reached, Stopping Camera.", + "FatalMaximumReachedText": "JPEG Error was fatal.", + "Incorrect Settings Chosen": "Incorrect Settings Chosen", + "Can't Connect": "Can't Connect", + "Video Finished": "Video Finished", + "No Monitors Selected": "No Monitors Selected", + "monSavedButNotCopied": "Your monitor was saved but not copied to any other monitor.", + "No Monitor Found, Ignoring Request": "No Monitor Found, Ignoring Request", + "Event": "Event", + "Detector Buffer": "Detector Buffer", + "EventText1": "Triggered a motion event at", + "EventText2": "Could not email image, file was not accessible", + "MailError": "MAIL ERROR : Could not send email, Check conf.json. Skipping any features relying on mailing.", + "updateKeyText1": "\"updateKey\" is missing from \"conf.json\", cannot do updates this way until you add it.", + "updateKeyText2": "\"updateKey\" is incorrect.", + "Control Error": "Control Error", + "ControlErrorText1": "Control is not enabled", + "ControlErrorText2": "Check your connection details. You may need to point the Base URL at port 8000 or 80. Check your authentication info.", + "NotAuthorizedText1": "Not Authorized, Submit init command with \"auth\",\"ke\", and \"uid\"", + "Fields cannot be empty": "Fields cannot be empty", + "AccountEditText1": "Could not edit. Refresh page if problem continues.", + "Not an Administrator Account": "Not an Administrator Account", + "superAdminText": "\"super.json\" does not exist. Please rename \"super.sample.json\" to \"super.json\".", + "Enter this code to proceed": "Enter this code to proceed", + "FactorAuthText1": "The code will only be active for 15 minutes. If you login again the timer will be reset to 15 minutes with the same code.", + "monitorEditText1": "Invalid Data, Check to see this is a valid import string.", + "monitorEditText2": "Invalid Details String. Check to see it is a JSON string and not a regular object being passed.", + "Monitor Updated by user": "Monitor Updated by user.", + "Monitor Added by user": "Monitor Added by user.", + "monitorGetText1": "incomplete request, remove last slash in URL or put acceptable value.", + "Monitor mode changed": "Monitor mode changed", + "Reset Timer": "Reset Timer", + "Monitor mode is already": "Monitor mode is already", + "Monitor or Key does not exist.": "Monitor or Key does not exist.", + "No Group with this key exists": "No Group with this key exists", + "Trigger Successful": "Trigger Successful", + "No such file": "No such file", + "modifyVideoText1": "Method doesn't exist. Check to make sure that the last value of the URL is not blank.", + "CPU indicator will not work. Continuing...": "CPU indicator will not work. Continuing...", + "startUpText0": "size check for videos", + "startUpText1": "end of size check for videos", + "startUpText2": "all users checked, wait to close open files and remove files over user limit", + "startUpText3": "waiting to give unfinished video check some time. 3 seconds.", + "startUpText4": "starting all monitors set to watch and record", + "startUpText5": "Shinobi is ready.", + "Migrator": "Migrator", + "Host Type": "Host Type", + "Edit": "Edit", + "Dashboard Language": "Dashboard Language", + "File Not Found": "File Not Found", + "File Not Found in Filesystem": "File Not Found in Filesystem", + "File Not Found in Database": "File Not Found in Database", + "No Monitor Exists with this ID.": "No Monitor Exists with this ID.", + "Cannot watch a monitor that isn't running.": "Cannot watch a monitor that isn't running.", + "Not Permitted": "Not Permitted", + "notPermitted1": "This action is not permitted by the administrator of your account.'", + "Not Authorized": "Not Authorized", + "Generate Subtitles": "Generate Subtitles", + "Video Limit":"Video Limit", + "Preview":"Preview", + "Websocket Connected":"Websocket Connected", + "Websocket Disconnected":"Websocket Disconnected", + "New Authentication Token":"New Authentication Token", + "All Logs":"All Logs", + "For Group":"For Group", + "Basic Authentication":"Basic Authentication", + "Superuser Logs":"Superuser Logs", + "Authentication Failed":"Authentication Failed", + "Max Number of Cameras":"Max Number of Cameras", + "Can edit Max Storage":"Can edit Max Storage", + "Can edit Max Days":"Can edit Max Days", + "in Days":"in Days", + "Can edit how long to keep Logs":"Can edit how long to keep Logs", + "Can use Admin Panel":"Can use Admin Panel", + "Can use WebDAV":"Can use WebDAV", + "Can use LDAP":"Can use LDAP", + "Can edit how long to keep Events":"Can edit how long to keep Events", + "Leave blank for unlimited":"Leave blank for unlimited", + "Limited":"Limited", + "All Privileges":"All Privileges", + "LDAP":"LDAP", + "LDAP Success":"LDAP Success", + "LDAP User Authenticated":"LDAP User Authenticated", + "LDAP User is New":"LDAP User is New", + "Creating New Account":"Creating New Account", + "bindDN":"bindDN", + "Bind Credentials":"Bind Credentials (Password)", + "Search Base":"Search Base", + "Configuration":"Configuration", + "Blank for No Change":"Blank for No Change", + "Pop":"Pop", + "Recording FPS Change on Start":"Recording FPS Change on Start", + "Save Frames to Events":"Save Frames to Events", + "Search Filter":"Search Filter", + "h264_cuvid": "H.264 CUVID", + "hevc_cuvid": "H.265 CUVID", + "mjpeg_cuvid": "MJPEG CUVID", + "mpeg4_cuvid": "MPEG4 CUVID", + "h264_qsv": "H.264 (Quick Sync Video)", + "hevc_qsv": "H.265 (Quick Sync Video)", + "vp8_qsv": "VP8 (Quick Sync Video)", + "mpeg2_qsv": "MPEG2 (Quick Sync Video)", + "h264_vaapi": "H.264 VA-API (Intel HW Accel)", + "h264_nvenc": "H.264 NVENC (NVIDIA HW Accel)", + "hevc_nvenc": "H.265 NVENC (NVIDIA HW Accel)", + "hevc_vaapi": "H.265 VA-API (Intel HW Accel)", + "vp8_cuvid": "VP8 NVENC (NVIDIA HW Accel)", + "vp9_cuvid": "VP9 NVENC (NVIDIA HW Accel)", + "hwaccel": "Acceleration Engine", + "hwaccel_vcodec": "Video Decoder", + "hwaccel_device": "HWAccel Device", + "Get Logs to Client": "Get Logs to Client", + "Hardware Accelerated": "Hardware Accelerated", + "Accelerator": "Accelerator", + "qsv": "qsv", + "dxva2": "dxva2 (DirectX Video, Windows)", + "vdpau": "vdpau", + "vaapi": "vaapi (VA-API)", + "vda": "vda (Apple VDA Hardware Acceleration)", + "videotoolbox": "videotoolbox", + "cuvid": "cuvid (NVIDIA NVENC)", + "Main": "Main", + "Storage Location": "Storage Location", + "Recommended": "Recommended", + "Please Wait for Completion": "Please Wait for Completion, Depending on the number of files selected this may take some time. Refresh to check again.", + "flv": "flv", + "FLV": "FLV", + "FLV Stream Type": "FLV Stream Type", + "Link Shinobi": "Link Shinobi", + "Show Stream HUD":"Show Stream HUD", + "Call Method":"Call Method", + "Gender":"Gender", + "Emotion":"Emotion", + "Age":"Age", + "Object":"Object", + "Uniform":"Uniform", + "Pose":"Pose", + "Male":"Male", + "Female":"Female", + "Channel":"Channel", + "Stream Key":"Stream Key", + "Server URL":"Server URL", + "Video Bit Rate":"Video Bit Rate", + "Audio Bit Rate":"Audio Bit Rate", + "RTMP Stream Flags":"RTMP Stream Flags", + "RTMP Stream":"RTMP Stream", + "Stream Channel":"Stream Channel", + "Confidence":"Confidence", + "Map":"Map", + "Add Map":"Add Map", + "Add Input Feed":"Add Input Feed", + "Add Channel":"Add Channel", + "Automatic":"Automatic", + "Max Latency":"Max Latency", + "Loop Stream":"Loop Stream", + "Object Tag":"Object Tag", + "Noise Filter":"Noise Filter", + "Noise Filter Range":"Noise Filter Range", + "TV Channel":"TV Channel", + "Channel ID":"Channel ID", + "TV Channel ID":"TV Channel ID", + "TV Channel Group":"TV Channel Group", + "Emotion Average":"Emotion Average", + "Show Regions of Interest":"Show Regions of Interest", + "Confidence of Detection":"Confidence of Detection", + "Edit Selected":"Edit Selected", + "Copy Settings":"Copy Settings", + "Copy to Settings":"Copy to Settings", + "Copy Group Settings":"Copy Group Settings", + "Copy Connection Settings":"Copy Connection Settings", + "Copy Custom Settings":"Copy Custom Settings", + "Copy Logging Settings":"Copy Logging Settings", + "Copy JPEG API Settings":"Copy JPEG API Settings", + "Copy Input Settings":"Copy Input Settings", + "Copy Stream Settings":"Copy Stream Settings", + "Copy Stream Channel Settings":"Copy Stream Channel Settings", + "Copy Recording Settings":"Copy Recording Settings", + "Copy Detector Settings":"Copy Detector Settings", + "Monitors to Copy to":"Monitors to Copy to", + "Notification Sound":"Notification Sound", + "Alert Sound":"Alert Sound", + "Alert Sound Delay":"Alert Sound Delay", + "powerVideoEventLimit":"You have set a high event limit. Are you sure you want to make this request?", + "There are no monitors that you can view with this account.":"There are no monitors that you can view with this account.", + "Use Built-In":"Use Built-In" +} diff --git a/languages/fr.json b/languages/fr.json new file mode 100644 index 0000000..41b0358 --- /dev/null +++ b/languages/fr.json @@ -0,0 +1,666 @@ +{ + "\"No Motion\" Detector": "\"Aucun Mouvement\" Détecteur De", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "180 Degrees": "180 Degrés", + "2-Factor Authentication": "Une Authentification À 2 Facteurs", + "90 Clockwise": "90 dans le sens des Aiguilles", + "90 Clockwise and Vertical Flip": "90 vers la gauche et Vertical Flip", + "90 Counter Clockwise and Vertical Flip (default)": "90 dans le sens antihoraire et la rotation Verticale (par défaut)", + "API": "API", + "API Key": "Clé API", + "API Key Added": "Clé API Ajouté", + "API Key Deleted": "API Clé Supprimée", + "API Keys": "Clés API", + "APIKeyAddedText": "Vous pouvez utiliser cette clé maintenant.", + "APIKeyDeletedText": "Clé a été supprimé. Elle ne fonctionnera plus.", + "ASC": "ASC", + "Accelerator": "Accélérateur", + "Account Info": "Les Informations De Compte", + "AccountEditText1": "Ne pouvait pas modifier. Actualiser la page si le problème persiste.", + "Accounts": "Comptes", + "Action for Selected": "Action Sélectionnés", + "Add": "Ajouter", + "Add Channel": "Ajouter Un Canal", + "Add Input Feed": "Ajoutez D'Entrée D'Alimentation", + "Add Map": "Ajouter La Carte", + "Add Monitor": "Ajouter Moniteur", + "Add New": "Ajouter De Nouveaux", + "Admin": "Admin", + "Advanced": "Avancé", + "Again": "Encore", + "Age": "L'âge", + "All Logs": "Tous Les Journaux", + "All Monitors": "Tous Les Moniteurs", + "All Monitors and Privileges": "Tous les Moniteurs et Privilèges", + "All Privileges": "Tous Les Privilèges", + "All Warnings": "Tous Les Avertissements", + "Allow Next Command": "Permettre Prochaine Commande en quelques Minutes", + "Allow Next Email": "Permettre Prochain Email en quelques Minutes", + "Allow Next Trigger": "Permettre à Côté de Déclenchement en Millisecondes", + "Allowed IPs": "Permis IPs", + "Analyzation Duration": "Analyzation Durée", + "Archive": "Archive", + "Are you sure?": "Êtes-vous sûr?", + "Audio Bit Rate": "Le Débit Binaire Audio", + "Audio Codec": "Codec Audio", + "Authenticate": "Authentifier", + "Authentication Failed": "Échec De L'Authentification", + "Auto": "Auto", + "Automatic": "Automatique", + "Autosave": "Autosave", + "Base64 over Websocket": "Base64 sur Websocket", + "Basic Authentication": "L'Authentification De Base", + "Bind Credentials": "Lier Les Informations D'Identification (Mot De Passe)", + "Blank for No Change": "Vide pour Pas Changer", + "Bottom Left": "En Bas À Gauche", + "Bottom Right": "En Bas À Droite", + "Browser Console Log": "Le Navigateur De La Console De Log", + "Buffer Preview": "Tampon Aperçu", + "CPU": "CPU", + "CPU indicator will not work. Continuing...": "CPU indicateur ne fonctionnera pas. Continue...", + "CSS": "CSS Style de votre tableau de bord.", + "Calendar": "Calendrier", + "Call Method": "Appel De La Méthode", + "Camera Password": "Mot De Passe De La Caméra", + "Camera Username": "Nom D'Utilisateur De La Caméra", + "Camera is not recording": "Appareil photo n'est pas de l'enregistrement", + "Camera is not streaming": "La caméra n'est pas en streaming", + "CameraNotRecordingText": "Les paramètres peuvent être incompatibles. Vérifier les encodeurs. Le redémarrage...", + "Can Authenticate Websocket": "Peut Authentifier Websocket", + "Can Control Monitors": "Peut Moniteurs De Contrôle", + "Can Delete Videos": "Pouvez Supprimer Des Vidéos", + "Can Delete Videos and Events": "Pouvez Supprimer des Vidéos et des Événements", + "Can Edit Monitor": "Pouvez Modifier Moniteur", + "Can Get Logs": "Pouvez Obtenir Les Journaux", + "Can Get Monitors": "Pouvez Obtenir Des Moniteurs", + "Can View Monitor": "Peut Moniteur De Vue", + "Can View Snapshots": "Peut Afficher Des Instantanés", + "Can View Streams": "Peut Afficher Des Flux", + "Can View Videos": "Peut Visionner Des Vidéos", + "Can View Videos and Events": "Pouvez Visualiser des Vidéos et des Événements", + "Can edit Max Days": "Pouvez éditer Max Jours", + "Can edit Max Storage": "Pouvez éditer Max de Stockage", + "Can edit how long to keep Events": "Pouvez modifier la durée de conservation des Événements", + "Can edit how long to keep Logs": "Pouvez modifier la durée de conservation des Journaux d'", + "Can use Admin Panel": "Pouvez utiliser le Panneau d'administration", + "Can use LDAP": "Peut utiliser le protocole LDAP", + "Can use WebDAV": "Pouvez utiliser WebDAV", + "Can't Connect": "Ne peut pas se Connecter", + "Cannot watch a monitor that isn't running.": "Impossible de regarder un moniteur qui n'est pas en cours d'exécution.", + "Center": "Centre d' Adresse URL", + "Channel": "Canal", + "Channel ID": "ID de canal", + "Chat on Discord": "Chat sur la Discorde", + "Check": "Vérifier", + "Check Signal Interval": "Vérifier le Signal de l'Intervalle en Minutes", + "Check for Motion First": "Vérifier le Mouvement de la Première", + "Close": "Fermer", + "Closed": "Fermé", + "Command": "Commande", + "Command on Trigger": "Commande sur la Gâchette", + "Complete Stream URL": "Compléter l'URL du Flux", + "Confidence": "La confiance", + "Confidence of Detection": "La confiance de Détection", + "Configuration": "Configuration", + "Confirm": "Confirmer", + "Connected": "Connecté", + "Connection": "Connexion", + "Connection Type": "Type De Connexion", + "Control": "Contrôle", + "Control Error": "Erreur De Contrôle De La", + "ControlErrorText1": "Le contrôle n'est pas activé", + "Controllable": "Contrôlable", + "Copy Connection Settings": "Copie Des Paramètres De Connexion", + "Copy Custom Settings": "Copie Des Paramètres Personnalisés", + "Copy Detector Settings": "Copie Réglages Du Détecteur", + "Copy Group Settings": "Copier Les Paramètres De Groupe", + "Copy Input Settings": "Copier Les Paramètres D'Entrée", + "Copy Logging Settings": "Copie Des Paramètres De Journalisation", + "Copy Recording Settings": "Copier Les Paramètres D'Enregistrement", + "Copy Settings": "Paramètres De Copie", + "Copy Stream Channel Settings": "Copie De Flux De Paramètres De Canal", + "Copy Stream Settings": "Copier Les Paramètres De Flux", + "Copy to Settings": "Copie des Paramètres de", + "Country of Plates": "Pays de Plaques", + "Counts of Motion": "Comtes de Mouvement", + "Creating New Account": "La Création D'Un Nouveau Compte", + "Current": "Actuel", + "Currently viewing": "Visualisez actuellement", + "Custom": "Personnalisé", + "Custom Base URL": "Base d'URL personnalisée Laissez le champ vide pour utiliser l'Hôte de l'URL", + "DB Lost.. Retrying..": "Base De Données Perdues.. Réessayer..", + "DESC": "DESC", + "Dashboard": "Tableau de bord", + "Dashboard Language": "Langue Du Tableau De Bord", + "Dashcam": "Dashcam", + "Dashcam (Streamer v2)": "Dashcam (Streamer v2)", + "Date Range": "La Plage De Dates", + "Debug": "Debug", + "Default": "Par défaut", + "Delete": "Supprimer", + "Delete Filter": "Supprimer Le Filtre", + "Delete Matches": "Supprimer Les Matchs", + "Delete Monitor": "Supprimer Moniteur", + "Delete Motionless Video": "Supprimer Immobile Vidéo", + "Delete Motionless Videos (Record)": "Supprimer Immobile Vidéos (Enregistrement)", + "Delete Selected Videos": "Supprimer La Sélection Des Vidéos", + "Delete Video": "Supprimer La Vidéo", + "Delete selected": "Supprimer la sélection", + "DeleteMonitorText": "Voulez-vous supprimer ce moniteur? Vous ne pouvez pas le récupérer. Les fichiers de cet ID restera dans le système de fichiers. Si vous choisissez de recréer un moniteur avec le même ID, les vidéos et les événements deviennent visibles dans le tableau de bord.", + "DeleteMonitorsText": "Voulez-vous supprimer ces moniteurs? Vous ne pouvez pas les récupérer. Les fichiers de ces Identifiants de rester dans le système de fichiers. Si vous choisissez de recréer un moniteur avec un de l'IDs, les vidéos et les événements deviennent visibles dans le tableau de bord.", + "DeleteSelectedVideosMsg": "Voulez-vous supprimer ces vidéos? Vous ne pouvez pas les récupérer.", + "DeleteVideoMsg": "Voulez-vous supprimer cette vidéo? Vous ne pouvez pas le récupérer.", + "Deleted": "Supprimé", + "Detect Objects": "Détecter les Objets Voir ci-dessous", + "Detector": "Détecteur de", + "Detector Buffer": "Détecteur De Tampon", + "Detector Flags": "Détecteur De Drapeaux", + "Detector Grouping": "Détecteur de Groupement d'Ajouter des groupes de Paramètres", + "Detector Rate": "Détecteur de Taux (FPS)", + "DetectorText": "

Lorsque les zones Largeur et Hauteur sont affichés, vous devriez les mettre à 640x480 ou ci-dessous. Cela permettra d'optimiser la vitesse de lecture d'images.

", + "Disable Night Vision": "Désactiver la Vision de Nuit Adresse URL", + "Disable Nightvision": "Désactiver Nightvision", + "Disabled": "Désactivé", + "Documentation": "La Documentation", + "Don't show this anymore": "Ne pas afficher plus", + "Double Quote Directory": "Devis Double Répertoire de Certains répertoires sont séparés par des espaces. L'utilisation de ce peut se bloquer certains appareils photo.", + "Down": "Bas Adresse URL", + "Down Stop": "Vers le bas Arrêter Adresse URL", + "Download": "Télécharger", + "EU": "L'UE", + "Edit": "Modifier", + "Edit Selected": "Modifier Les", + "Email": "E-mail", + "Email Details": "E-Mail Les Détails", + "Email on No Motion": "E-mail sur \"Aucun Mouvement\"", + "Email on Trigger": "E-mail sur la Gâchette e-Mails passent à la principale du titulaire de compte de connexion l'adresse.", + "Emotion": "L'émotion", + "Emotion Average": "L'Émotion De La Moyenne", + "Enable": "Activer", + "Enable Night Vision": "Activer la Vision Nocturne Adresse URL", + "Enable Nightvision": "Activer La Vision Nocturne", + "Enabled": "Activé", + "End": "Fin", + "End Time": "Heure De Fin", + "Ended": "Terminé", + "Enlarge": "Agrandir", + "Enter this code to proceed": "Entrez ce code pour procéder", + "Equal to": "Égal à", + "Error Connecting": "Erreur Lors De La Connexion", + "Event": "L'événement", + "Event Limit": "Cas Limite", + "EventText1": "Déclenché un mouvement à", + "EventText2": "Pourrait pas l'email de l'image, le fichier n'est pas accessible", + "Events": "Les événements", + "Example": "Exemple", + "Execute Command": "Exécuter La Commande", + "Executed": "Exécuté", + "Export": "L'exportation", + "FFmpegCantStart": "FFmpeg ne Pouvait pas Commencer", + "FFmpegCantStartText": "Le moteur d'enregistrement pour cette caméra n'a pas pu démarrer. Il y a peut être quelque chose de mal avec votre configuration de la caméra. S'il y a des journaux autres que celui-ci, veuillez les poster dans les Questions sur Github.", + "FFmpegTip": "FFprobe est un simple flux multimédias de l'analyseur. Vous pouvez l'utiliser pour afficher toutes sortes d'informations sur les intrants, y compris la durée, taux d'armature, taille de l'image, etc.", + "FFprobe": "Sonde", + "FLV": "FLV", + "FLV Stream Type": "FLV Type de Flux", + "FactorAuthText1": "Le code ne sera actif pendant 15 minutes. Si vous vous connectez de nouveau la minuterie est réinitialisée à 15 minutes avec le même code.", + "Fatal": "Fatale", + "Fatal Maximum Reached": "Fatale Maximum Atteint, L'Arrêt De La Caméra.", + "FatalMaximumReachedText": "JPEG Erreur a été fatale.", + "Feed-in Image Height": "De rachat à la Hauteur de l'Image", + "Feed-in Image Width": "Alimentation sur la Largeur de l'Image", + "Female": "Femelle", + "Fields cannot be empty": "Les champs ne peut pas être vide", + "File Not Exist": "Le Fichier N'Existe Pas", + "File Not Found": "Fichier Non Trouvé", + "File Type": "Type De Fichier", + "FileNotExistText": "Impossible d'enregistrer non existant fichier. Quelque chose s'est mal passé.", + "Filename": "Filename", + "Filesize": "La taille du fichier", + "Filter ID": "Filtre ID", + "Filter Matches": "Filtre Correspond", + "Filter Name": "Nom Du Filtre", + "FilterMatchesText1": "Ce filtre a rencontré des conditions.", + "FilterMatchesText2": "les vidéos trouvées.", + "Filters": "Les filtres", + "Filters Updated": "Les Filtres Mis À Jour", + "FiltersUpdatedText": "Vos modifications ont été enregistrées et appliquées.", + "Find Where": "Trouver Où", + "Fix": "Fix", + "Fix Video": "Corriger La Vidéo", + "FixVideoMsg": "Voulez-vous corriger cette vidéo? Vous ne pouvez pas annuler cette action.", + "Flush PM2 Logs": "Rincer les PM2 Journaux", + "Font Path": "Le Chemin De Police", + "Font Size": "Taille De La Police", + "For Group": "Pour Le Groupe", + "Force Port": "La Force De Port", + "Found Devices": "Appareils Trouvés", + "Frame Rate": "Le Taux d'image par seconde(FPS)", + "Full Frame Detection": "Plein Cadre La Détection", + "Full Stream URL": "Complet de l'URL du Flux", + "Full URL Path": "Plein Chemin d'accès d'URL", + "Fullscreen": "Plein écran", + "Gender": "Genre", + "Generate Subtitles": "Générer Des Sous-Titres", + "Get Logs to Client": "Obtenir les Journaux du Client", + "Greater Than": "Plus De", + "Greater Than or Equal to": "Supérieure ou Égale à", + "Group Key": "La Clé De Groupe", + "Group Name": "Nom Du Groupe", + "Grouping": "Groupement d'Ajouter des groupes de Paramètres", + "H.264 / H.265 / H.265+": "H. 264 / H. 265 / H. 265 ", + "HLS (.m3u8)": "HLS (.m3u8)", + "HLS (includes Audio)": "HLS (Audio)", + "HLS Audio Encoder": "Encodeur Audio", + "HLS List Size": "La Taille De La Liste", + "HLS Live Start Index": "HLS Vivre Index de Début", + "HLS Preset": "Modèle Préréglé", + "HLS Segment Length": "La Longueur du Segment en quelques Secondes", + "HLS Start Number": "HLS Nombre de Départ", + "HLS Video Encoder": "Encodeur Vidéo", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "Hardware Accelerated": "L'Accélération Matérielle", + "Height": "Hauteur", + "Help": "Aider", + "Hide List": "Masquer La Liste", + "Hide Notes": "Masquer Les Notes", + "Host": "Accueil", + "Hotswap Modes (Watch-Only)": "Hotswap Modes (Watch)", + "How to Record": "Comment faire pour Enregistrer", + "IP Address": "Adresse IP", + "Identity": "Identité", + "IdentityText1": "C'est la façon dont le système permettra d'identifier les données pour ce flux. Vous ne pouvez pas modifier le Moniteur ID une fois que vous avez appuyé sur la touche enregistrer. Si vous le souhaitez, vous pouvez faire le Moniteur ID plus lisible par l'homme avant de continuer.", + "IdentityText2": "Vous pouvez dupliquer l'écran en modifiant le Moniteur ID , puis appuyez sur save. Vous ne peut pas utiliser l'ID d'un moniteur qui existe déjà ou qu'il permettra d'économiser plus que surveiller les informations de base de données.", + "Idle": "Inactif", + "Image Height": "La Hauteur De L'Image", + "Image Location": "Emplacement de l'Image de Chemin d'accès Absolu ou laissez le champ vide pour utiliser mondiale", + "Image Position": "La Position De L'Image", + "Image Width": "La Largeur De L'Image", + "Import": "L'importation", + "Import Monitor Configuration": "L'Importation De Configuration Du Moniteur De", + "ImportMonitorConfigurationText": "En faisant cela, vous overrwrite toutes les modifications ne sont pas enregistrées. Les modifications importées ne sera appliquée que lorsque vous appuyez sur Enregistrer.", + "ImportMultiMonitorConfigurationText": "En faisant cela, vous overrwrite tous les moniteurs avec des Id existant dans le fichier d'importation.", + "In": "Dans", + "Incorrect Settings Chosen": "Des Paramètres Incorrects Choisi", + "Indifference": "L'indifférence", + "Input": "Entrée", + "Input Feed": "Entrée D'Alimentation", + "Input Flags": "Entrée Des Drapeaux", + "Input Selector": "Sélecteur D'Entrée", + "Input Settings": "Les Paramètres D'Entrée", + "Input Type": "Type D'Entrée", + "InputText1": "Cette section indique Shinobi comment utiliser un flux. Pour des performances optimales, essayez de régler votre appareil photo les réglages internes. Trouvez les options suivantes et de les définir comme illustré. Pour trouver votre appareil photo vous pouvez utiliser le construit en ONVIF Scanner de Shinobi. Certaines caméras ONVIF nécessitent l'utilisation d'un outil de gestion pour modifier leurs paramètres internes. Si vous ne trouvez pas votre appareil, vous pouvez essayer ONVIF le Gestionnaire de Périphériques de Windows.", + "InputText2": "
  • Framerate (FPS) : Haut : 10 - 15 FPS, Faible : 2 à 5 FPS
  • I-frame interval : 80
  • Taux de bits Type : CBR (Constant Bit rate)
  • Débit binaire : entre 256kbps - 500kbps
", + "InputText3": "Si vous avez besoin d'aide pour déterminer ce type d'entrée de votre appareil photo vous pouvez prendre un coup d'oeil à la Caméra Liste d'URLs sur le Shinobi site web.", + "Invalid JSON": "Invalid JSON", + "InvalidJSONText": "Veuillez vous assurer que c'est une chaîne JSON valide pour les Shinobi de configuration du moniteur.", + "JPEG": "JPEG", + "JPEG (Auto Enables JPEG API)": "JPEG (Auto Permet JPEG API)", + "JPEG API": "JPEG API Instantané (cgi-bin)", + "JPEG Error": "JPEG Erreur", + "JPEG Mode": "Le Mode JPEG", + "JPEGErrorText": "Il y avait un problème dans l'obtention de données de votre appareil photo.", + "LDAP": "LDAP", + "LDAP Success": "LDAP Succès", + "LDAP User Authenticated": "LDAP de l'Utilisateur Authentifié", + "LDAP User is New": "Utilisateur LDAP est Nouveau", + "Leave blank for random.": "Laissez vide pour aléatoire.", + "Leave blank for unlimited": "Laissez vide pour un nombre illimité de", + "Left": "Gauche Adresse URL", + "Left Stop": "Butée gauche, Adresse URL", + "Less Than": "Moins De", + "Less Than or Equal to": "Inférieure ou Égale à", + "Like": "Comme", + "Limited": "Limitée", + "Link Shinobi": "Lien Shinobi", + "Lisence Plate Detector": "Lisence Détecteur De Plaque", + "List Toggle": "Liste De Bascule", + "Live Stream Toggle": "Live Stream De La Bascule", + "Live View": "Vue En Direct", + "Local": "Local", + "Log Level": "Le Niveau De Journal", + "Log Signal Event": "Journal du Signal d'Événements côté Client seulement", + "Logging": "La journalisation", + "Login": "Connexion", + "Logout": "Déconnexion", + "Logs": "Les journaux", + "Loop Stream": "Boucle De Flux", + "MB": "MO", + "MJPEG": "MJPEG", + "MP4 (copy, libx264, libx265)": "MP4 (copie, libx264, libx265)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)", + "MPEG-DASH (includes Audio)": "MPEG-DASH (Audio)", + "MailError": "MAIL d'ERREUR : impossible d'envoyer des e-mail, Vérifiez conf.json. En ignorant toutes les fonctionnalités en s'appuyant sur l'envoi.", + "Main": "Principal", + "Male": "Mâle", + "Manual": "Manuel", + "Map": "Carte", + "Matches": "Matchs", + "Max Latency": "Max Latence", + "Max Number of Cameras": "Le Nombre maximum de Caméras", + "Max Storage Amount": "Max de la Quantité de Stockage en mo", + "Mode": "Mode", + "Monitor": "Moniteur", + "Monitor Added by user": "Moniteur Ajoutés par l'utilisateur.", + "Monitor Capture Rate": "Surveiller les Taux de Capture (FPS)", + "Monitor Groups": "La Surveillance De Groupes", + "Monitor ID": "Moniteur ID", + "Monitor Idling": "Surveiller La Marche Au Ralenti", + "Monitor Name": "Nom De Moniteur", + "Monitor Settings": "Paramètres Du Moniteur", + "Monitor Stopped": "Moniteur Arrêté", + "Monitor Updated by user": "Surveiller les mises à Jour par l'utilisateur.", + "Monitor mode changed": "Le mode moniteur changé", + "Monitor mode is already": "Le mode Monitor est déjà", + "Monitor or Key does not exist.": "Le moniteur ou la Clé n'existe pas.", + "MonitorIdlingText": "Surveiller la session a été commandé au ralenti.", + "MonitorStoppedText": "Surveiller la session a été ordonné d'arrêter.", + "Monitors": "Les moniteurs", + "Monitors per row": "Surveille par ligne de Montage", + "Monitors to Copy to": "Les moniteurs de Copie à", + "Montage": "Montage", + "Motion GUI": "Motion GUI", + "Motion Meter": "Motion Compteur", + "Name": "Nom", + "New Authentication Token": "Nouveau Jeton D'Authentification", + "New Monitor": "Nouveau Moniteur", + "No": "Pas de", + "No Audio": "Pas D'Audio", + "No Data": "Pas De Données", + "No Events found for this video": "Aucun événement trouvé pour cette vidéo", + "No Group with this key exists": "Pas de Groupe avec cette clé existe", + "No Monitor Exists with this ID.": "Pas de Moniteur Existe à cet ID.", + "No Monitor Found, Ignoring Request": "Pas De Moniteur Trouvé, En Ignorant La Demande", + "No Monitors Selected": "Pas De Moniteurs Sélectionnés", + "No Rotation": "Pas De Rotation", + "No Videos Found": "Pas De Vidéos Trouvées", + "No such file": "Pas de tel fichier", + "NoMotionEmailText1": "Pas de Mouvement pour", + "NoMotionEmailText2": "Il n'y a pas été de tout mouvement détecté sur l'appareil photo pour", + "NoVideosFoundForDateRange": "Pas de Vidéos trouvées dans cette plage de dates. Essayez de définir la date de début de la plus en arrière.", + "Noise Filter": "Filtre De Bruit", + "Not Authorized": "Pas Autorisé", + "Not Connected": "Pas Connecté", + "Not Equal to": "Pas Égal à", + "Not In": "Pas Dans", + "Not Matches": "Pas De Matchs", + "Not Permitted": "Pas Autorisés", + "Not Saved": "Pas Enregistrées", + "Not an Administrator Account": "Pas un Compte d'Administrateur", + "NotAuthorizedText1": "Pas Autorisé, Soumettre commande init avec \"auth\",\"ke\", et \"uid\"", + "Notes": "Notes", + "NotesPlacholder": "Les commentaires que vous voulez quitter pour ce caméras de paramètres.", + "Number of Days to keep": "Nombre de Jours de conservation", + "ONVIF": "ONVIF", + "ONVIF Scanner": "ONVIF Scanner", + "ONVIFnote": "Découvrez ONVIF appareils sur les réseaux à l'extérieur de votre propre ou la laisser vide pour analyser votre réseau actuel.
Nom d'utilisateur et le Mot de passe peut être laissé en blanc.", + "Object": "Objet", + "Object Tag": "Balise Object", + "OpenCV Cascades": "OpenCV Cascades", + "Options": "Options", + "Order Streams": "Afin De Ruisseaux", + "Output Method": "Méthode De Sortie", + "Password": "Mot de passe", + "Password Again": "Mot De Passe À Nouveau", + "Passwords don't match": "Les mots de passe ne correspondent pas", + "Paste JSON here.": "Coller JSON ici.", + "Path": "Chemin", + "Permissions": "Les autorisations", + "Please Wait for Completion": "Veuillez Attendre la fin, Selon le nombre de fichiers sélectionnés, cela peut prendre un certain temps. Actualiser pour vérifier de nouveau.", + "Points": "Des Points Lors de l'ajout de points de cliquer sur le bord du polygone.", + "Pop": "Pop", + "Port": "Port", + "Pose": "Poser", + "Poseidon": "Poseidon", + "Position X": "Position X", + "Position Y": "Position Y", + "Power Video Viewer": "La Puissance Du Visualiseur Vidéo", + "Power Viewer": "Visionneuse De L'Alimentation", + "Preferences": "Préférences", + "Preset": "Preset", + "Preview": "Aperçu", + "Probe Size": "Longueur De La Sonde", + "Process Crashed for Monitor": "Le processus s'est Écrasé pour Surveiller", + "Process Unexpected Exit": "Processus Inattendu De Sortie", + "Profile": "Profil", + "Quality": "La qualité de l' 1 est Élevée, 23 est Faible", + "Query": "Requête", + "RAM": "RAM", + "RTMP Stream": "Flux RTMP", + "RTMP Stream Flags": "Flux RTMP Drapeaux", + "RTSP": "RTSP", + "RTSP Transport": "RTSP de Transport", + "Range or Single": "Gamme ou Seul", + "Rate": "Taux (FPS)", + "Raw": "Raw", + "Raw H.264 Stream": "Raw H. 264 Flux", + "Recommended": "Recommandé", + "Record": "Enregistrement", + "Record File Type": "Enregistrement De Type De Fichier", + "Record Height": "Record De Hauteur", + "Record Video Filter": "Enregistrement Vidéo De Filtre", + "Record Width": "Enregistrement De Largeur", + "Recording": "Enregistrement", + "Recording FPS": "L'enregistrement de FPS", + "Recording FPS Change on Start": "Enregistrement FPS Changement sur Démarrer", + "Recording Flags": "L'Enregistrement Des Drapeaux", + "Recording Segment Interval": "Enregistrement Segment de l'Intervalle en minutes", + "Recording Timeout": "L'enregistrement de Délai d'attente en Minutes", + "Recording Timestamp": "L'Enregistrement D'Horodatage", + "Recording Watermark": "Enregistrement Filigrane", + "RecordingText": "Il est recommandé que vous définissez Enregistrement de Type de Fichier pour WebMMP4 et Vidéo Codec pour libvpxcopie ou libx264 parce que votre Type d'Entrée est définie sur .", + "Refresh List of Cascades": "Actualiser la Liste des Cascades", + "Region Editor": "Région De L'Éditeur", + "Region Name": "Nom De La Région", + "RegionNote": "Les Points ne sont enregistrées que lorsque vous appuyez sur Enregistrer sur les Paramètres du Moniteur de la fenêtre.", + "Regions": "Les régions", + "Remember Me": "Se Souvenir De Moi", + "Request": "Demande", + "Reset Timer": "Réinitialiser La Minuterie", + "Restart": "Redémarrer", + "Restart CRON": "Redémarrage du CRON", + "Restart Core": "Le Redémarrage De Base", + "Restarting Process": "Le Redémarrage Du Processus De", + "Retry Connection": "Nouvelle tentative de Connexion Nombre de fois que le droit à l'échec", + "Retrying...": "Réessayer...", + "Right": "Droit de l' Adresse URL", + "Right Stop": "Droit d'Arrêter Adresse URL", + "Rotate": "Faites tourner", + "Save": "Enregistrer", + "Save Directory": "Répertoire De Sauvegarde", + "Save Events to SQL": "Enregistrer les Événements dans le SQL", + "Save Frames to Events": "D'enregistrer les Images des Événements", + "Save Log in SQL": "Enregistrer le Journal dans SQL Cela peut se remplir rapidement.", + "Save as": "Enregistrer sous", + "Saved Filters": "Enregistré Filtres", + "Scan Settings": "Paramètres De Numérisation", + "Search": "Recherche", + "Search Base": "La Base De Recherche", + "Search Filter": "Filtre De Recherche", + "Secure": "Sécurisé", + "Send Frames": "Envoyer des Images Pousser images à analyser", + "Separate with commas, no spaces": "Séparés par des virgules, sans espace", + "Server URL": "URL du serveur", + "Set to Watch Only": "Mis à Regarder Seulement", + "Settings": "Paramètres", + "Settings Changed": "La Modification Des Réglages", + "SettingsChangedText": "Vos paramètres sont enregistrés et appliqués. Certains paramètres peuvent nécessiter une actualisation de cette page.", + "Shinobi": "Shinobi", + "Shinobi Streamer": "Shinobi Streamer", + "Show Logs": "Afficher Les Journaux D'", + "Show Regions of Interest": "Montrer les Régions d'Intérêt", + "Show Stream HUD": "Afficher les Flux de PALETTE", + "Silent": "Silencieux", + "Simple": "Simple", + "Size (mb)": "Taille (mo)", + "Snapshot": "Instantané", + "Snapshot Flags": "Instantané De Drapeaux", + "Snapshots": "Instantanés", + "Sort By": "Trier Par", + "Start": "Démarrer", + "Start Recording": "Démarrer L'Enregistrement", + "Start Time": "Heure De Début", + "Started": "Commencé", + "Status Indicator": "Indicateur De L'État De", + "Stop": "Arrêter", + "Stop URL": "Arrêter URL", + "Storage Location": "Emplacement De Stockage", + "Stream": "Flux", + "Stream Channel": "Canal De Flux De Données", + "Stream Flags": "Flux De Drapeaux", + "Stream Key": "Flux De Clé", + "Stream Timestamp": "Flux D'Horodatage", + "Stream Type": "Type De Flux", + "Stream Watermark": "Flux De Filigrane", + "Stream to YouTube": "Stream sur YouTube", + "Stream to YouTube Flags": "Stream sur YouTube Drapeaux", + "StreamText": "

Cette section permettra de désigner le flux primaire, de méthode et de ses paramètres. Ce flux sera affiché dans le tableau de bord. Si vous choisissez d'utiliser HLS, JPEG, MJPEG, alors vous pouvez consommer du courant à travers d'autres programmes.

JPEG flux essentiellement désactive le principal cours d'eau et les utilisations de l'instantané bin pour obtenir des images.

", + "Streamer": "Streamer", + "Streams": "Flux", + "Superuser": "Superutilisateur", + "Superuser Logs": "Superuser Journaux", + "Switch on for Still Image": "Interrupteur pour Toujours à l'Image", + "System": "Système", + "TCP": "TCP", + "TV Channel": "Chaîne de TÉLÉVISION", + "TV Channel Group": "Chaîne de TÉLÉVISION du Groupe", + "TV Channel ID": "Chaîne de TÉLÉVISION ID", + "Text Box Color": "Texte De La Boîte De Couleur", + "Text Color": "La Couleur Du Texte", + "Themes": "Thèmes", + "There are no monitors that you can view with this account.": "Il n'y a pas les moniteurs que vous pouvez afficher avec ce compte.", + "Time-lapse": "Time-lapse", + "Time-lapse Tool": "Time-lapse de l'Outil", + "Timeout": "Timeout", + "Timeout Reset on Next Motion": "Délai de Réinitialisation sur le Prochain Mouvement", + "Toggle Sidebar": "Basculer La Barre Latérale", + "Top Left": "En Haut À Gauche", + "Top Right": "En Haut À Droite", + "Traditional (Watch-Only, Includes Buffer)": "Traditionnel (Watch-Seulement, Comprend Tampon)", + "Traditional Recording": "Traditionnelle Enregistrement", + "Trigger Record": "Déclencheur D'Enregistrement", + "Trigger Successful": "Déclencheur De Succès", + "UDP": "UDP", + "URL": "URL", + "URL Stop Timeout": "URL Arrêter Délai Run stop URL après X millisecondes", + "US": "NOUS", + "Unable to Launch": "Impossible de Lancer", + "UnabletoLaunchText": "Veuillez enregistrer le nouveau moniteur en premier. Tentez ensuite de lancer la région de l'éditeur.", + "Uniform": "Uniforme", + "Up": "Jusqu' Adresse URL", + "Up Stop": "D'Arrêter Adresse URL", + "Update": "Mise à jour", + "Update to Development": "Mise à jour pour le Développement", + "Update to Master": "Mise à jour de Maître", + "Use Built-In": "Utilisez La Fonction De", + "Username": "Nom d'utilisateur", + "Value": "Valeur", + "Video": "Vidéo", + "Video Bit Rate": "Le Débit Binaire Vidéo", + "Video Codec": "Codec Vidéo", + "Video Filter": "Filtre Vidéo", + "Video Finished": "Vidéo Fini", + "Video Length (minutes) and Motion Count per video": "Durée de la vidéo (en minutes) et le Mouvement Comte par vidéo", + "Video Limit": "Vidéo Limite", + "Video Record Rate": "Vidéo vitesse d'Enregistrement (IPS)", + "Video Status": "État De La Vidéo", + "Video and Time Span (Minutes)": "La vidéo et la Durée (en Minutes)", + "Videos": "Vidéos", + "Videos List": "Liste Des Vidéos", + "Warning": "Avertissement", + "Watch": "Regarder", + "Watch Only": "Regarder Seulement", + "WebDAV": "WebDAV", + "WebM (libvpx)": "WebM (libvpx)", + "Webdav Error": "Webdav Erreur", + "WebdavErrorText": "Impossible d'enregistrer. Avez-vous rendre l'appareil dossiers à l'intérieur de votre choisi répertoire de sauvegarde?", + "Webhook": "Webhook", + "Webhook URL": "Webhook URL", + "Websocket": "Websocket", + "Websocket Connected": "Websocket Connecté", + "Websocket Disconnected": "Websocket Déconnecté", + "Width": "Largeur", + "Yes": "Oui", + "Zoom In": "Zoom Dans l' Adresse URL", + "Zoom In Stop": "Zoom Arrêter Adresse URL", + "Zoom Out": "Zoom Adresse URL", + "Zoom Out Stop": "Zoom Arrêter Adresse URL", + "a day": "un jour", + "a few seconds": "quelques secondes", + "a minute": "une minute", + "a month": "un mois", + "a year": "un an", + "aac": "aac", + "aac (Default)": "aac (par Défaut)", + "ac3": "ac3", + "ago": "il y a", + "an hour": "une heure", + "bindDN": "bindDN", + "blankPassword": "Laissez le champ vide pour garder le même mot de passe", + "clientStreamFailedattemptingReconnect": "Côté Client ctream échec de la vérification, d'essayer de se reconnecter.", + "confirmDeleteFilter": "Voulez-vous supprimer ce filtre? Vous ne pouvez pas le récupérer.", + "copy": "copie", + "cuvid": "cuvid (NVIDIA NVENC)", + "days": "jours", + "dropBoxSuccess": "Succès! Les fichiers enregistrés sur votre Dropbox.", + "dxva2": "dxva2 (Vidéo DirectX, Windows)", + "flv": "flv", + "for Global Access": "pour l'Accès Mondial", + "h264_cuvid": "H. 264 CUVID", + "h264_nvenc": "H. 264 NVENC (NVIDIA HW Accel)", + "h264_qsv": "H. 264 (Quick Sync Video)", + "h264_vaapi": "H. 264 VA-API (Intel HW Accel)", + "hevc_cuvid": "H. 265 CUVID", + "hevc_nvenc": "H. 265 NVENC (NVIDIA HW Accel)", + "hevc_qsv": "H. 265 (Quick Sync Video)", + "hevc_vaapi": "H. 265 VA-API (Intel HW Accel)", + "hours": "heures", + "hwaccel": "L'Accélération Du Moteur", + "hwaccel_device": "HWAccel Appareil", + "hwaccel_vcodec": "Décodeur Vidéo", + "in": "dans", + "in Days": "dans les Jours", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis (par Défaut)", + "libvpx (Default)": "libvpx (par Défaut)", + "libvpx-vp9": "libvpx-vp9", + "libx264": "libx264", + "libx264 (Default)": "libx264 (par Défaut)", + "libx265": "libx265", + "minutes": "minutes", + "mjpeg_cuvid": "MJPEG CUVID", + "modifyVideoText1": "La méthode n'existe pas. Assurez-vous que la dernière valeur de l'URL n'est pas vide.", + "monSavedButNotCopied": "Votre moniteur a été sauvé, mais pas copié sur un autre moniteur.", + "monitorEditFailedMaxReached": "Votre compte a atteint le nombre maximum de caméras qui peuvent être créés. Parler à un administrateur si vous souhaitez que cela a changé.", + "monitorEditText1": "Des Données non valides, Vérifiez la validité de l'importation de la chaîne.", + "monitorEditText2": "Non Valide Les Détails De La Chaîne. Vérifiez pour voir c'est une chaîne JSON et non pas un objet normal d'être passé.", + "monitorGetText1": "demande incomplète, supprimer le dernier slash dans l'URL ou mettre valeur acceptable.", + "months": "mois", + "mpeg2_qsv": "MPEG2 (Quick Sync Video)", + "mpeg4_cuvid": "MPEG4 CUVID", + "noSpecialCharacters": "Pas d'espaces ni de caractères spéciaux.", + "notPermitted1": "Cette action n'est pas autorisée par l'administrateur de votre compte\".", + "on": "sur", + "on Error": "en cas d'Erreur", + "powerVideoEventLimit": "Vous avez une grande manifestation limite. Êtes-vous sûr que vous voulez faire cette demande?", + "qsv": "qsv", + "startUpText0": "vérification de la taille pour les vidéos", + "startUpText1": "fin de la vérification de la taille pour les vidéos", + "startUpText2": "tous les utilisateurs vérifiés, attendre pour fermer les fichiers ouverts et supprimer les fichiers de plus de limite de l'utilisateur", + "startUpText3": "d'attente pour donner inachevé vidéo de vérifier un certain temps. 3 secondes.", + "startUpText4": "départ tous les moniteurs ensemble pour regarder et enregistrer", + "startUpText5": "Shinobi est prêt.", + "superAdminText": "\"super.json\" n'existe pas. Veuillez renommer \"super.de l'échantillon.json\" à \"super.json\".", + "total": "total", + "updateKeyText1": "\"updateKey\" est manquant à partir de \"conf.json\", ne peut pas faire les mises à jour de cette façon jusqu'à ce que vous l'ajouter.", + "updateKeyText2": "\"updateKey\" est incorrecte.", + "vaapi": "vaapi (VA-API)", + "vda": "vda (Apple VDA l'Accélération Matérielle)", + "vdpau": "vdpau", + "videotoolbox": "videotoolbox", + "vp8_cuvid": "VP8 NVENC (NVIDIA HW Accel)", + "vp8_qsv": "VP8 (Quick Sync Video)", + "vp9_cuvid": "VP9 NVENC (NVIDIA HW Accel)", + "years": "ans" +} diff --git a/languages/ja.json b/languages/ja.json new file mode 100644 index 0000000..d6e692a --- /dev/null +++ b/languages/ja.json @@ -0,0 +1,496 @@ +{ + "\"No Motion\" Detector": "\"動き\"の検出器", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "180 Degrees": "180度", + "2-Factor Authentication": "2要素認証", + "90 Clockwise": "時計回りに90", + "90 Clockwise and Vertical Flip": "90右回転、上下反転", + "90 Counter Clockwise and Vertical Flip (default)": "90反時計方向に回し、上下反転(デフォルト)", + "API": "API", + "API Key Added": "APIキーの追加", + "API Key Deleted": "APIキーの削除", + "API Keys": "APIキー", + "APIKeyAddedText": "にお使いいただけキーです。", + "APIKeyDeletedText": "キーが削除されました。 ではなくなります。", + "ASC": "ASC", + "Account Info": "アカウント情報", + "AccountEditText1": "な編集できるようになります。 リフレッシュページの場合は問題が続きます。", + "Accounts": "座", + "Action for Selected": "行動選択", + "Add": "追加", + "Add Monitor": "追加モニター", + "Add New": "新規追加", + "Admin": "Admin", + "Advanced": "先進", + "Again": "再", + "All Monitors": "すべてのモニター", + "All Monitors and Privileges": "すべての監視および権限", + "All Warnings": "すべての警告", + "Allow Next Command": "を次のコマンド ", + "Allow Next Email": "を次のメール に分", + "Allow Next Trigger": "を次のトリガ をミリ秒単位", + "Allowed IPs": "可IPs", + "Analyzation Duration": "解析期間", + "Archive": "アーカイブ", + "Audio Codec": "オーディオコーデック", + "Authenticate": "認証", + "Auto": "オート", + "Autosave": "ぜ", + "Base64 over Websocket": "Base64上Websocket", + "Bottom Left": "左下", + "Bottom Right": "右下", + "Browser Console Log": "ブラウザコンソールのログ", + "CPU": "CPU", + "CPU indicator will not work. Continuing...": "CPU表示できません。 続きを---", + "CSS": "CSS スタイルダッシュボードです。", + "Calendar": "カレンダー", + "Camera Password": "カメラのパスワード", + "Camera Username": "カメラのユーザー名", + "Camera is not recording": "カメラは記録", + "CameraNotRecordingText": "設定の場合は相容れないものがある。 チェックエンコーダです。 再...", + "Can Control Monitors": "を制御できるモニター", + "Can Delete Videos": "で削除できる動画", + "Can Delete Videos and Events": "削除が可能でのビデオやイベント", + "Can Edit Monitor": "編集できるモニター", + "Can Get Logs": "でログ", + "Can Get Monitors": "できるモニター", + "Can View Monitor": "できるビューモニター", + "Can View Snapshots": "でスナップショット", + "Can View Streams": "での流れ", + "Can View Videos": "できるビュー動画", + "Can View Videos and Events": "できるビュービデオやイベント", + "Can't Connect": "ですね", + "Center": "センター のURLアドレス", + "Chat on Discord": "チャット上の不和", + "Check": "チェック", + "Check Signal Interval": "チェック信号の間隔 ", + "Check for Motion First": "チェックモーションの最初", + "Close": "近", + "Closed": "閉鎖", + "Command": "コマンド", + "Command on Trigger": "コマンドをトリガー", + "Complete Stream URL": "完全なストリームURL", + "Confirm": "確認", + "Connected": "接続", + "Connection Type": "接続タイプ", + "Control": "制御", + "Control Error": "制御エラー", + "ControlErrorText1": "制御が有効にならない", + "Controllable": "制御可能", + "Country of Plates": "国板", + "Counts of Motion": "カウントの運動", + "Current": "現在の", + "Currently viewing": "現在閲覧", + "Custom": "カスタム", + "Custom Base URL": "カスタムベースURL は空欄で結構使ホストのURL", + "DB Lost.. Retrying..": "データベース失われた..再試行す。", + "DESC": "お得に!", + "Dashboard": "ダッシュボード", + "Dashboard Language": "ダッシュボードの言語", + "Dashcam": "Dashcam", + "Dashcam (Streamer v2)": "Dashcam(ストリーマv2)", + "Date Range": "日付の範囲", + "Debug": "デバッグ", + "Default": "デフォルト", + "Delete": "削除", + "Delete Filter": "削除フィルター", + "Delete Matches": "チ削除", + "Delete Monitor": "モニター削除", + "Delete Motionless Video": "削除静止画", + "Delete Motionless Videos (Record)": "削除静止画録画", + "Delete Selected Videos": "削除選択した動画", + "Delete Video": "ビデオ削除", + "Delete selected": "削除を選択", + "DeleteMonitorText": "い削除したいことがわか? はできません回復します。 ファイルのためにこのIDをファイルシステムです。 を選択の場合は再現モニターで同じIDのビデオやイベントが可視のダッシュボードです。", + "DeleteSelectedVideosMsg": "に削除しますこれらの動画です。 はできません回復しています。", + "DeleteVideoMsg": "に削除しますこの動画です。 はできません回復します。", + "Deleted": "削除", + "Detect Objects": "検出物体 以下参照", + "Detector": "検出器", + "Detector Flags": "検出フラグ", + "Detector Rate": "検出率 (FPS)", + "DetectorText": "

の幅と高さのボックス表示設定すべきであるし640x480以下になりました。 この最適化とともに、これまでの読取速度のフレームです。

", + "Disable Night Vision": "除夜のビジョン のURLアドレス", + "Disable Nightvision": "Disable Nightvision", + "Disabled": "障害者", + "Documentation": "文書", + "Don't show this anymore": "いこう", + "Double Quote Directory": "ダブルクォートディレクトリ の一部のディレクトリしています。 この場合クラッシュカメラです。", + "Down": "下 のURLアドレス", + "Down Stop": "ダウン停止 URLアドレス", + "Download": "ダウンロード", + "EU": "EU", + "Edit": "編集", + "Email": "メール", + "Email Details": "メールの詳細", + "Email on No Motion": "メールでの\"動き\"", + "Email on Trigger": "メールでのトリガー のメールのページ内移動用のメニュー口座のログインアドレスです。", + "Enable Night Vision": "するナイトビジョン のURLアドレス", + "Enable Nightvision": "をNightvision", + "Enabled": "有効な", + "End": "終了", + "End Time": "終了時間", + "Ended": "終了", + "Enlarge": "拡大", + "Enter this code to proceed": "コードを入力して登録へ", + "Equal to": "等しい", + "Error Connecting": "接続エラー", + "Event": "イベント", + "Event Limit": "イベントに制限", + "EventText1": "起動イベント", + "EventText2": "はメールに画像ファイルにアクセスできないか、または", + "Events": "イベント", + "Example": "例", + "Execute Command": "コマンドを実行し", + "Executed": "実行され", + "Export": "輸出", + "FFmpegCantStart": "Gpartedっ開始", + "FFmpegCantStartText": "の記録エンジン本カメラが起動しません。 あかカメラの設定をします。 の場合はログ以外にこだ後の 課題を Githubです。", + "FFmpegTip": "FFprobeが簡単なマルチメディアの流れの測定を行いました。 利用できる出力のすべての種類に関する情報の入力を含む期間には、フレームレートは、フレームサイズ等", + "FFprobe": "プローブ", + "FactorAuthText1": "このコードのみで活躍する15分間とさせていただきます。 場合は再度ログインしますタイマーをリセットされます15分と同じコードです。", + "Fatal": "致命的な", + "Fatal Maximum Reached": "死亡の最大に達し、停止ます。", + "FatalMaximumReachedText": "JPEGエラー致命的にするかもしれない。", + "Feed-in Image Height": "飼料-画像の高さ", + "Feed-in Image Width": "飼料-画像の幅", + "Fields cannot be empty": "分野できない空", + "File Not Exist": "ファイルが存在しない", + "File Not Found": "ファイルが見つかりません", + "File Type": "ファイルの種類", + "FileNotExistText": "登録できない不existantファイルです。 何かが分かります。", + "Filename": "ファイル名", + "Filesize": "Filesize", + "Filter ID": "フィルタのID", + "Filter Matches": "フィルターの試合", + "Filter Name": "フィルター名", + "FilterMatchesText1": "このフィルタを満たす条件です。", + "FilterMatchesText2": "動画で見つかります。", + "Filters": "フィル", + "Filters Updated": "フィ更新", + "FiltersUpdatedText": "ご変更して保存され、適用されます。", + "Find Where": "見所", + "Fix": "Fix", + "Fix Video": "修正ビデオ", + "FixVideoMsg": "したい着この動画です。 元に戻せませんこの行動します。", + "Font Path": "フォントのパス", + "Font Size": "文字サイズ", + "Force Port": "力ポート", + "Found Devices": "たデバイス", + "Frame Rate": "フレームレート (FPS)", + "Full Frame Detection": "フルフレーム検出", + "Fullscreen": "フルスクリーン", + "Greater Than": "以上", + "Greater Than or Equal to": "以上", + "Group Key": "パブリックグループ", + "Group Name": "グループ名", + "Grouping": "グループ化 ", + "H.264 / H.265 / H.265+": "H.264/H.265/H.265 ", + "HLS (.m3u8)": "HLS(します。m3u8)", + "HLS (includes Audio)": "HLS(オーディオ)", + "HLS Audio Encoder": "HLSオーディオエンコーダ", + "HLS List Size": "HLSリストのサイズ", + "HLS Preset": "HLSプリセット", + "HLS Segment Length": "HLSセグメント長 ", + "HLS Video Encoder": "HLSビデオエンコーダ", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "Height": "高さ", + "Help": "助", + "Hide List": "Hide一覧", + "Hide Notes": "Hide注", + "Host": "ホスト", + "Hotswap Modes (Watch-Only)": "Hotswapモード時のみ)", + "How to Record": "その記録", + "IP Address": "IPアドレス", + "Identity": "ティ", + "IdentityText1": "このシステムを特定のデータをこのストリームです。 大きさを変えることはできませんの モニタIDを 一度押すと保存されます。 したい場合はしないように注意してください モニタID をより人間が読める形式だけます。", + "IdentityText2": "また複数のモニターを変更することにより、 モニタID を押すと保存されます。 す 利用のIDのモニターするにあたりまえるモニターのデータベースの情報です。", + "Idle": "アイドル", + "Image Height": "画像の高さ", + "Image Location": "画像の位置 を絶対パスまたは空欄で結構使用グローバル", + "Image Position": "画像の位置", + "Image Width": "画像の幅", + "Import": "輸入", + "Import Monitor Configuration": "輸入モニターの設定", + "ImportMonitorConfigurationText": "そうするとoverrwriteの変更は、現在保存されません。 輸入の変化のみに適用される場合を押すと 保存します。", + "In": "に", + "Incorrect Settings Chosen": "誤った設定を選択", + "Indifference": "無関心", + "Input": "入力", + "Input Flags": "入力フラグ", + "Input Type": "入力タイプ", + "InputText1": "これ忍どのように消費するストリームです。 最適な性能チューニングしてみカメラの内部設定します。 として以下のようなオプションセットとして表示します。 ディスカメラで利用できます 内蔵ONVIFスキャナー の向きを変えて走り出した。 一部のONVIFカメラの使用を必要とする管理ツールの変更を内部設定します。 できない場合は空のカメラをお試しいただ ONVIFデバイスマネージャー Windowsます。", + "InputText2": "
  • Framerate(FPS): 高さ:10-15FPS、低:2-5FPS
  • Iフレーム間隔: 80
  • ビットレート: CBR(定ビットレート)
  • ビットレート: 間256kbps-500kbps
", + "InputText3": "困ったときにはコーヒーに飽きたら寿司にどのような入力インターネットにアクセスでカメラをご覧になることができる カメラのUrlリスト の商品につけられます。", + "Invalid JSON": "無効なJSON", + "InvalidJSONText": "ご確認くださいここは有効なJSON文字列のための商品につけられたモニターを設定します。", + "JPEG": "JPEG", + "JPEG (Auto Enables JPEG API)": "JPEG(自動車をJPEG API)", + "JPEG API": "JPEG APIの スナップショット(cgi-bin)", + "JPEG Error": "JPEGエラー", + "JPEG Mode": "JPEGモード", + "JPEGErrorText": "が課題となった取得データからカメラです。", + "Leave blank for random.": "空白の場合ランダムです。", + "Left": "左 のURLアドレス", + "Left Stop": "左停 URLアドレス", + "Less Than": "以上", + "Less Than or Equal to": "以下の", + "Like": "のように", + "Lisence Plate Detector": "ライセンプレート検出器", + "List Toggle": "リストを切り替え", + "Live Stream Toggle": "ライブストリームを切り替え", + "Live View": "ライブビュー", + "Local": "地", + "Log Level": "ログレベル", + "Log Signal Event": "ログ信号のイベント クライアント側のみ", + "Logging": "ログイン", + "Login": "ログイン", + "Logout": "アウト", + "Logs": "ログ", + "MB": "MB", + "MJPEG": "MJPEG", + "MP4 (copy, libx264, libx265)": "MP4(コピー、libx264は、libx265)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4(い。mp4ます。ts)", + "MailError": "メールエラーがない送信メールは、チェックconfです。jsonです。 飛び他の特徴に依存のメーリングします。", + "Matches": "試合", + "Max Storage Amount": "最大の貯蔵量を 、メガバイト", + "Mode": "モード", + "Monitor": "モニター", + "Monitor Added by user": "モニター追加によりユーザーです。", + "Monitor Capture Rate": "モニター捕捉率 (FPS)", + "Monitor Groups": "モニター集団", + "Monitor ID": "モニタID", + "Monitor Idling": "モニターアイドリング", + "Monitor Name": "モニタ名称", + "Monitor Settings": "モニタ設定", + "Monitor Stopped": "モニターを停止", + "Monitor Updated by user": "モニターを更新します。", + "Monitor mode changed": "モニタモード変更", + "Monitor mode is already": "モニターモードで", + "Monitor or Key does not exist.": "モニターやキーが存在しません。", + "MonitorIdlingText": "モニターセッションが命じられた。", + "MonitorStoppedText": "モニターセッションの中止を命じます。", + "Monitors": "モニター", + "Monitors per row": "モニター当行 のためのモンタージュ", + "Montage": "モンタージュ", + "Motion GUI": "動GUI", + "Motion Meter": "運動メーター", + "Name": "名称", + "No": "No", + "No Audio": "オーディオ", + "No Data": "データなし", + "No Events found for this video": "イベントはありませんがこの動画", + "No Group with this key exists": "グループはこの鍵が存在する", + "No Monitor Found, Ignoring Request": "なモニター、要請を無視して", + "No Rotation": "回転無し", + "No such file": "なファイル", + "NoMotionEmailText1": "不動", + "NoMotionEmailText2": "あなたの運動検知のためのカメラ", + "NoVideosFoundForDateRange": "ない映像がこの日付範囲から選びます。 う設定の開始日は\"まだ完全に回復してます。", + "Not Authorized": "権限がない", + "Not Connected": "接続されていない", + "Not Equal to": "と等しくない", + "Not In": "ない", + "Not Matches": "ない試合", + "Not Permitted": "許可されない", + "Not an Administrator Account": "な管理者のアカウント", + "NotAuthorizedText1": "認証されていないの提出からinitコマンド\"auth\"は、\"ke\"、\"uid\"", + "Notes": "注記", + "NotesPlacholder": "コメントするため、このカメラを設定します。", + "Number of Days to keep": "数日間の保", + "ONVIF": "ONVIF", + "ONVIF Scanner": "ONVIFのスキャナー", + "ONVIFnote": "発見ONVIFのデバイスネットワーク以外はと思われる項目に関しては、空白をスキャン現在のネットワークです。
ユーザー名とパスワードを選択することも可能です。", + "OpenCV Cascades": "OpenCVンアプリケーション", + "Order Streams": "注文の流れ", + "Output Method": "出力方法", + "Password": "パスワード", + "Password Again": "パスワードを再", + "Passwords don't match": "パスワードと一致しません", + "Paste JSON here.": "ペーストはJSONです。", + "Path": "パス", + "Permissions": "アクセス権", + "Points": "ポイント が加算ポイントをクリックの端にポリゴンです。", + "Port": "港", + "Position X": "X位置", + "Position Y": "位置Y", + "Power Video Viewer": "電動画ビューワー", + "Power Viewer": "電力ビューア", + "Preferences": "設定", + "Preset": "プリセット", + "Probe Size": "プローブサイズ", + "Process Crashed for Monitor": "工程ぶためのモニター", + "Process Unexpected Exit": "過程で予想外の出口", + "Profile": "概要", + "Quality": "品質の 1が高く、23日には低", + "Query": "クエリ", + "RAM": "RAM", + "RTSP": "RTSP", + "RTSP Transport": "RTSP輸送", + "Range or Single": "範囲またはシングル", + "Rate": "率 (FPS)", + "Record": "記録", + "Record File Type": "録音ファイルの種類", + "Record Height": "記録の高さ", + "Record Video Filter": "ビデオをフィルター", + "Record Width": "記録幅", + "Recording": "記録", + "Recording Flags": "記録フラグ", + "Recording Segment Interval": "録音のセグメント間隔 ", + "Recording Timeout": "を記録タイムアウト ", + "Recording Timestamp": "を記録タイムスタンプ", + "Recording Watermark": "録画透かし", + "RecordingText": "であることをおすすめの設定 を記録ファイルの種類WebMMP4 - ビデオコーデックlibvpxコピーまたは libx264 でご 入力タイプ に設定し ます。", + "Refresh List of Cascades": "リフレッシュリストンアプリケーション", + "Region Editor": "地域のエディタ", + "Region Name": "地域名", + "RegionNote": "ポイントのみ保存を押すと 保存モニター設定 ウインドウです。", + "Regions": "地域", + "Remember Me": "グイン情報を記憶させ", + "Reset Timer": "リセットタイマー", + "Restarting Process": "再稼働プロセスの加", + "Retry Connection": "再接続 回数許されな", + "Retrying...": "リトライ動作中に---", + "Right": "右 のURLアドレス", + "Right Stop": "右停止 のURLアドレス", + "Rotate": "回転", + "Save": "保存", + "Save Directory": "保存ディレクトリ", + "Save Events to SQL": "保存イベントへSQL", + "Save Log in SQL": "ログの保存アプリケーションで この事がございます。", + "Save as": "として保存", + "Saved Filters": "保存したフィルター", + "Scan Settings": "スキャン設定", + "Search": "検索", + "Send Frames": "送信フレーム プするフレームの解析", + "Separate with commas, no spaces": "分離をカンマ区切りで入力し、空間", + "Set to Watch Only": "設定時のみ", + "Settings": "設定", + "Settings Changed": "設定変更", + "SettingsChangedText": "設定して適用されます。", + "Shinobi": "忍", + "Shinobi Streamer": "商品につけられたストリーマ", + "Show Logs": "ショーログ", + "Silent": "黙", + "Simple": "簡単な", + "Size (mb)": "サイズ(mb)", + "Snapshot": "スナップショット", + "Snapshot Flags": "スナップショットフラグ", + "Snapshots": "スナップショット", + "Sort By": "並べ替え", + "Start": "開始", + "Start Recording": "録音を開始", + "Start Time": "開始時間", + "Started": "を開始", + "Status Indicator": "ステータスインジケータ", + "Stop URL": "停URL", + "Stream": "ストリーム", + "Stream Flags": "ストリームフラグ", + "Stream Timestamp": "ストリームにタイムスタンプ", + "Stream Type": "ストリームタイプ", + "Stream Watermark": "ストリームゾート", + "Stream to YouTube": "ストリームをYouTube", + "Stream to YouTube Flags": "ストリームをYouTube旗", + "StreamText": "

ここでは指定のストリーム出方法で設定します。 このストリームに表示されるので、ダッシュボードです。 ご利用にHLS、JPEG、MJPEGきを摂取することができ、ストリームを通じてその他のプログラムです。

使用JPEGストリームは本質的にoffのストリームを使用してスナップショットの原材料へのコンタミ防止のフレームを取得します。

", + "Streamer": "ストリーマ", + "Streams": "渓流", + "Superuser": "Superuser", + "Switch on for Still Image": "スイッチのための画像", + "TCP": "TCP", + "Text Box Color": "テキストボックスの色", + "Text Color": "テキストカラーを設定します。", + "Time-lapse": "時間", + "Time-lapse Tool": "インターバル撮ツール", + "Timeout": "タイムアウト", + "Timeout Reset on Next Motion": "タイムアウトリセットは次の運動", + "Toggle Sidebar": "サイドバーを切り替え", + "Top Left": "トップ左", + "Top Right": "トップ右", + "Trigger Record": "トリガ記録", + "Trigger Successful": "トリガー成功", + "UDP": "UDP", + "URL": "URL", + "URL Stop Timeout": "URLを停止タイムアウトの 実行を停止URLの後にXをミリ秒", + "US": "米", + "Unable to Launch": "できない開始", + "UnabletoLaunchText": "保存しておいてください新しいモニターします。 その試みを開始、地域のエディタです。", + "Up": "Up URLアドレス", + "Up Stop": "最大停止 のURLアドレス", + "Username": "ユーザー名", + "Value": "値", + "Video": "ビデオ", + "Video Codec": "ビデオコーデック", + "Video Filter": "映像フィルター", + "Video Finished": "ビデオ完成", + "Video Length (minutes) and Motion Count per video": "動画の長さ(分)運動回数の映像", + "Video Record Rate": "デジタルビデオ入出力率 (FPS)", + "Video Status": "ビデオの状況", + "Video and Time Span (Minutes)": "映時間(分)", + "Videos": "ビデオ", + "Videos List": "動画一覧", + "Watch": "腕時計", + "Watch Only": "時計のみ", + "WebDAV": "WebDAV", + "WebM (libvpx)": "WebM(libvpx)", + "Webdav Error": "Webdavエラー", + "WebdavErrorText": "登録できないます。 ただ、カメラ内のフォルダ選択保存ディレクトリのか?", + "Webhook": "Webhook", + "Webhook URL": "Webhook URL", + "Width": "幅", + "Yes": "あり", + "Zoom In": "ズーム のURLアドレス", + "Zoom In Stop": "ズーム停止 のURLアドレス", + "Zoom Out": "縮小 URLアドレス", + "Zoom Out Stop": "表示が自動的に切り替わり止め のURLアドレス", + "a day": "日", + "a few seconds": "数秒", + "a minute": "分", + "a month": "月", + "a year": "年", + "aac": "デスクトップ、エンタープライズ", + "aac (Default)": "デスクトップ、エンタープライズ(デフォルト)", + "ac3": "ac3", + "ago": "前", + "an hour": "時間", + "blankPassword": "空欄で結構いパスワード", + "calendar": "カレンダー", + "clientStreamFailedattemptingReconnect": "クライアント側ctreamチェックに失敗したとしてもう一度接続してください。", + "confirmDeleteFilter": "に削除しますこのフィルタすか? はできません回復します。", + "copy": "コピー", + "days": "日", + "dropBoxSuccess": "あなた方の成功を意味する。 ファイルをDropboxに保存されます。", + "for Global Access": "グローバルアクセス", + "hours": "時間", + "in": "に", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis(デフォルト)", + "libvpx (Default)": "libvpx(デフォルト)", + "libvpx-vp9": "libvpx-vp9", + "libx264": "libx264", + "libx264 (Default)": "libx264(デフォルト)", + "libx265": "libx265", + "minutes": "分", + "modifyVideoText1": "方法は存在しないます。 よって実行されていることを確認する最後の値はURLではない空白にします。", + "monitorEditFailedMaxReached": "アカウントの最大数のカメラが作成できます。 話管理者の体力があれば誰でも楽しめます。", + "monitorEditText1": "無効なデータを確認する有効なインポート文字列になります。", + "monitorEditText2": "無効な内容の文字列です。 確認でJSON文字列ではなく通常のオブジェクトに渡されます。", + "monitorGetText1": "不完全な要求の削除、最後のスラッシュのURLまたは許容値です。", + "months": "ヶ月", + "noSpecialCharacters": "なし空間または特殊文字です。", + "on": "月", + "on Error": "エラー時", + "startUpText0": "サイズのチェックビデオ", + "startUpText1": "末サイズをチェックビデオ", + "startUpText2": "すべてのユーザーがチェックに近いファイルを開く削除ファイルはユーザー制限", + "startUpText3": "待ちに未完成の映像チェックします。 3秒です。", + "startUpText4": "すべてのモニタ設定時記録", + "startUpText5": "忍びのご用意もあります。", + "superAdminText": "\"スーパーです。json\"は存在しない。 お名前を変更する\"スーパーです。サンプルです。json\"\"スーパーです。json\"です。", + "superAdminTitle": "世界一のスーパー管理者", + "total": "合計", + "updateKeyText1": "\"updateKey\"が\"confです。json\"になるんで更新するまでに追加します。", + "updateKeyText2": "\"updateKey\"が間違っています。", + "years": "年" +} diff --git a/languages/pt_BR.json b/languages/pt_BR.json new file mode 100644 index 0000000..34b64f4 --- /dev/null +++ b/languages/pt_BR.json @@ -0,0 +1,531 @@ +{ + "Shinobi": "Shinobi", + "superAdminTitle": "Shinobi : Super Admin", + "Login": "Entrar", + "Authenticate": "Autenticar", + "Dashboard": "Painel de Controle", + "Streamer": "Transmissor", + "Admin": "Admin", + "Superuser": "Superusuário", + "Dashcam": "Dashcam", + "Email": "E-mail", + "Username": "Usuário", + "Profile": "Perfil", + "Password": "Senha", + "Password Again": "Senha novamente", + "Remember Me": "Lembrar", + "RAM": "RAM", + "CPU": "CPU", + "on": "ligado", + "Power Viewer": "Ligar visualizador", + "Power Video Viewer": "Ligar visualizador de vídeo", + "Time-lapse": "Time-lapse", + "Montage": "Montagem", + "Accounts": "Contas", + "Settings": "Configurações", + "API": "API", + "ONVIF": "ONVIF", + "FFprobe": "Probe", + "Filters": "Filtros", + "Logs": "Logs", + "List Toggle": "Mostrar lista", + "Hide List": "Esconder Lista", + "Motion GUI": "GUI de Movimento", + "JPEG Mode": "Modo JPEG", + "Order Streams": "Ordenar transmissões", + "Hide Notes": "Esconder Notas", + "Example": "Exemplo", + "Logout": "Sair", + "Closed": "Fechado", + "Ended": "Finalizado", + "Started": "Iniciado", + "Monitor": "Monitor", + "Filename": "Nome do Arquivo", + "Size (mb)": "Tamanho (mb)", + "Watch": "Assistir", + "Download": "Baixar", + "Delete": "Deletar", + "Fix": "Corrigir", + "Zoom In": "Mais Zoom URL Address", + "Zoom Out": "Menos Zoom URL Address", + "Enable Nightvision": "Ativar Visão Noturna", + "Disable Nightvision": "Desativar Visão Noturna", + "Current": "Atual", + "Monitors": "Monitors", + "Video": "Video", + "Videos": "Videos", + "Events": "Eventos", + "Streams": "Transmissões", + "Snapshot": "Snapshot", + "Snapshots": "Snapshots", + "Date Range": "Intervalo de Data", + "Event Limit": "Limite de Evento", + "No Data": "Sem Dados", + "Live View": "Visualização ao vivo", + "Add": "Adicionar", + "Save": "Salvar", + "Close": "Fechar", + "Check": "Verificar", + "Confirm": "Confirmar", + "Enable": "Habilitar", + "Enabled": "Habilitado", + "API Keys": "Chaves da API", + "Group Key": "Chave do Grupo", + "Allowed IPs": "IPs Permitidos", + "Separate with commas, no spaces": "Separar com vírgulas, sem espaços", + "Can Get Monitors": "Pode Obter Monitores", + "Can Get Logs": "Pode Obter Logs", + "Can Control Monitors": "Pode Controlar Monitores", + "Can View Snapshots": "Pode Visualizar Snapshots", + "Can View Streams": "Pode Visualizar Transmissões", + "Can View Videos": "Pode Visualizar Vídeos", + "Can View Monitor": "Pode Visualizar Monitores", + "Can Edit Monitor": "Pode Editar Monitores", + "Can Delete Videos": "Pode Deletar Vídeos", + "Delete Video": "Deletar Vídeo", + "Can View Videos and Events": "Pode Visualizar Vídeos e Eventos", + "Can Delete Videos and Events": "Pode Deletar Vídeos e Eventos", + "Saved Filters": "Filtros Salvos", + "Filter Name": "Filtrar Nome", + "Find Where": "Encontrar Onde", + "Sort By": "Ordenar Por", + "Start Time": "Hora de Início", + "End Time": "Hora de Término", + "Monitor ID": "ID do Monitor", + "File Type": "Tipo de Arquivo", + "Filesize": "Tamanho do Arquivo", + "Video Status": "Status do Vídeo", + "Preferences": "Preferências", + "Equal to": "Igual a", + "Not Equal to": "Não Igual a", + "Greater Than or Equal to": "Maior ou Igual a", + "Greater Than": "Maior que", + "Less Than": "Menor que", + "Less Than or Equal to": "Menor ou Igual a", + "Like": "Como", + "Matches": "Combina", + "Not Matches": "Não Combina", + "In": "Em", + "Not In": "Não Em", + "ASC": "ASC", + "DESC": "DESC", + "Action for Selected": "Ação para Selecionado", + "Search": "Procurar", + "No": "Não", + "Yes": "Sim", + "Start": "Iniciar", + "End": "Finalizar", + "Archive": "Arquivar", + "Email Details": "Detalhes do E-mail", + "Delete Matches": "Deletar Combinações", + "Delete selected": "Deletar Selecionado", + "Execute Command": "Executar Comando", + "for Global Access": "para Acesso Global", + "Help": "Ajuda", + "Don't show this anymore": "Não mostre isso mais", + "Chat on Discord": "Conversar no Discord", + "Documentation": "Documentação", + "All Monitors": "Todos Monitores", + "Motion Meter": "Medidos de Movimento", + "FFmpegTip": "FFprobe is a simple multimedia streams analyzer. You can use it to output all kinds of information about an input including duration, frame rate, frame size, etc.", + "Complete Stream URL": "URL de transmissão completa", + "ONVIF Scanner": "ONVIF Scanner", + "Scan Settings": "Configurações de digitalização", + "ONVIFnote": "Descubra os dispositivos ONVIF em redes fora da sua ou deixe em branco para escanear sua rede atual.
O nome de usuário e a senha podem ser deixados em branco.", + "Range or Single": "Range or Single", + "IP Address": "Endereço IP", + "Port": "Porta", + "Camera Username": "Usuário da câmera", + "Camera Password": "Senha da câmera", + "Found Devices": "Dispositivos encontrados", + "Switch on for Still Image": "Ligar para manter imagem", + "Live Stream Toggle": "Mostrar transmissão ao vivo", + "RegionNote": "Os pontos só são salvos quando você pressiona Salvar na janela de Configurações do Monitor.", + "Points": "Pontos Ao adicionar pontos, clique na borda do polígono.", + "Indifference": "Indiferença", + "Region Name": "Nome da região", + "Regions": "Regiões", + "Again": "De novo", + "Account Info": "Informações da conta", + "blankPassword": "Deixe em branco para manter a mesma senha", + "2-Factor Authentication": "Autenticação de 2 fatores", + "Max Storage Amount": "Montante máximo de armazenamento em Megabytes", + "Number of Days to keep": "Número de dias para manter", + "Monitor Groups": "Grupos de monitores", + "Group Name": "Nome do grupo", + "WebDAV": "WebDAV", + "URL": "URL", + "Autosave": "Auto salvar", + "Save Directory": "Salvar diretório", + "CSS": "CSS Personalize seu painel de controle.", + "Monitors per row": "Monitores por linha para montagem", + "Browser Console Log": "Navegador de logs", + "All Monitors and Privileges": "Todos monitores e privilégios", + "Permissions": "Permissões", + "Time-lapse Tool": "Ferramenta Time-laps", + "total": "total", + "MB": "MB", + "Calendar": "Calendário", + "Leave blank for random.": "Deixe em branco para aleatório.", + "Currently viewing": "Visualizando atualmente", + "Status Indicator": "Indicador de status", + "Show Logs": "Mostrar logs", + "Videos List": "Lista de vídeos", + "Monitor Settings": "Configurações do monitor", + "Enlarge": "Prolongar", + "Fullscreen": "Tela cheia", + "Value": "Valor", + "Idle": "Inativo", + "Disabled": "Desabilitado", + "Record": "Gravar", + "Watch Only": "Visualizar apenas", + "Toggle Sidebar": "Mostrar barra lateral", + "Add Monitor": "Adicionar monitor", + "Start Recording": "Iniciar gravação", + "Set to Watch Only": "Definir para apenas visualizar", + "Save as": "Salvar como", + "Add New": "Adicionar novo", + "Delete Selected Videos": "Excluir vídeos selecionados", + "DeleteSelectedVideosMsg": "Deseja excluir esses vídeos? Você não poderá recuperá-los.", + "clientStreamFailedattemptingReconnect": "A verificação ctream do lado do cliente falhou, tentando reconectar.", + "Delete Filter": "Excluir filtro", + "confirmDeleteFilter": "Deseja excluir este filtro? Você não poderá recuperá-lo.", + "Fix Video": "Corrigir Vídeo", + "FixVideoMsg": "Você deseja corrigir esse vídeo? Você não poderá desfazer essa ação..", + "DeleteVideoMsg": "Deseja excluir este vídeo? Você não poderá recuperá-lo.", + "dropBoxSuccess": "Sucesso! Arquivos salvos em seu Dropbox.", + "API Key Deleted": "Chave da API excluída", + "APIKeyDeletedText": "A chave foi excluída. Não funcionará mais.", + "API Key Added": "Chave da API adicionada", + "APIKeyAddedText": "Você pode usar essa chave agora", + "Filters Updated": "Filtros atualizados", + "FiltersUpdatedText": "Suas alterações foram salvas e aplicadas.", + "Settings Changed": "Configurações Alteradas", + "SettingsChangedText": "Suas configurações foram salvas e aplicadas.", + "Import Monitor Configuration": "Importar Configuração do Monitor", + "ImportMonitorConfigurationText": "Fazer isso substituirá todas as alterações atualmente não salvas. As mudanças importadas só serão aplicadas quando você pressionar Salvar.", + "Paste JSON here.": "Cole o JSON aqui.", + "Delete Monitor": "Deletar Monitor", + "DeleteMonitorText": "Deseja excluir este monitor? Você não pode recuperá-lo. Os arquivos para essa ID permanecerão no sistema de arquivos. Se você optar por recriar um monitor com a mesma identificação, os vídeos e eventos tornar-se-ão visíveis no painel de controle.", + "Invalid JSON": "JSON inválido", + "InvalidJSONText": "Certifique-se de que esta seja uma string JSON válida para a configuração do monitor Shinobi.", + "Passwords don't match": "As senhas não combinam", + "No Events found for this video": "Nenhum evento encontrado para este vídeo", + "Video and Time Span (Minutes)": "Vídeo e intervalo de tempo (minutos)", + "Video Length (minutes) and Motion Count per video": "Comprimento do vídeo (minutos) e Contagem de movimento por vídeo", + "Counts of Motion": "Contagem de movimento", + "Unable to Launch": "Incapaz de executar", + "UnabletoLaunchText": "Salve primeiro o monitor novo. Em seguida, tente iniciar o editor da região.", + "NoVideosFoundForDateRange": "Nenhum vídeo encontrado neste intervalo de datas. Tente definir a data de início mais adiante.", + "monitorEditFailedMaxReached": "Sua conta atingiu o número máximo de câmeras que podem ser criadas. Fale com um administrador se você gostaria que isso mudasse.", + "in": "em", + "ago": "atrás", + "a few seconds": "alguns segundos", + "a minute": "um minuto", + "minutes": "minutos", + "an hour": "uma hora", + "hours": "horas", + "a day": "um dia", + "days": "dias", + "a month": "um mês", + "months": "meses", + "a year": "um ano", + "years": "anos", + "Identity": "Identidade", + "Input": "Entrada", + "Stream": "Transmissão", + "Stream Timestamp": "Transmitindo horário", + "Stream Watermark": "Transmitindo marca d'água", + "JPEG API": "JPEG API Snapshot (cgi-bin)", + "Recording": "Gravando", + "Recording Timestamp": "Gravando horário", + "Recording Watermark": "Gravando marca d'água", + "Region Editor": "Editor de região", + "Custom": "Customizado", + "Detector": "Detector", + "Connected": "Conectado", + "Not Connected": "Não conectado", + "Lisence Plate Detector": "Detector de placas", + "OpenCV Cascades": "OpenCV Cascatas", + "Refresh List of Cascades": "Atualizar Lista de Cascatas", + "\"No Motion\" Detector": "\"Sem movimento\" Detector", + "Control": "Controle", + "Grouping": "Agrupando   Adicione grupos em Configurações", + "Logging": "Logging", + "IdentityText1": "É assim que o sistema irá identificar os dados para este fluxo. Você não pode alterar o ID do Monitor uma vez que você pressionou salvar. Se você quiser, você pode fazer o ID do Monitor mais legível para humanos antes de continuar.", + "IdentityText2": "Você pode duplicar um monitor modificando o ID do Monitor e depois pressionando salvar. Você não pode usar o ID de um monitor que já existe ou ele economizará sobre as informações do banco de dados desse monitor.", + "noSpecialCharacters": "Sem espaços ou caracteres especiais.", + "NotesPlacholder": "Comentários que você quer deixar para as configurações desta câmera.", + "InputText1": "Esta seção diz a Shinobi como consumir um fluxo. Para um desempenho ideal, tente ajustar as configurações internas da sua câmera. Encontre as seguintes opções e defina-as como mostrado. Para encontrar sua câmera, você pode usar o ONVIF Scanner embarcado do Shinobi. Algumas câmeras ONVIF requerem o uso de uma ferramenta de gerenciamento para modificar suas configurações internas. Se você não consegue encontrar suas câmeras, você pode tentar Gerenciador de dispositivos ONVIF para Windows.", + "InputText2": "
  • Taxa de quadros por segundo (FPS) : High : 10 - 15 FPS, Low : 2-5 FPS
  • I-frame interval : 80
  • Bit Rate Type : CBR (Constant Bit Rate)
  • Bit Rate : entre 256kbps - 500kbps
", + "InputText3": "Se você precisar de ajuda para descobrir o tipo de entrada que sua câmera é, você pode dar uma olhada no Camera URLs List na página do Shinobi.", + "StreamText": "

Esta seção designará o método do fluxo primário e as configurações. Este fluxo será exibido no painel. Se você optar por usar HLS, JPEG ou MJPEG, então você pode consumir o fluxo através de outros programas.

Usar o fluxo de JPEG essencialmente desativa o fluxo primário e usa o compartimento de instantâneos para obter quadros.

", + "DetectorText": "

Quando as caixas de Largura e Altura são mostradas, você deve configurá-las para 640x480 ou abaixo. Isso otimizará a velocidade de leitura dos quadros.

", + "RecordingText": "Recomenda-se que você defina Tipo de arquivo de gravação para WebMMP4 e Video Codec para libvpxcopie ou libx264 porque seu Tipo de Entrada está definido para .", + "Name": "Nome", + "Retry Connection": "Tentar novamente a conexão Número de vezes permitido falhar", + "Notes": "Notas", + "Input Type": "Tipo de entrada", + "Connection Type": "Tipo de conexão", + "RTSP Transport": "Transporte RTSP", + "Host": "Host", + "Force Port": "Forçar porta", + "Path": "Caminho", + "Monitor Capture Rate": "Taxa de captura do monitor (FPS)", + "Analyzation Duration": "Duração da análise", + "Probe Size": "Probe Size", + "Stream Type": "Tipo de transmissão", + "# of Allow MJPEG Clients": "# para permitir clientes MJPEG 0 para infinito", + "HLS Video Encoder": "Codificador de vídeo HLS", + "HLS Audio Encoder": "Codificador de áudio HLS", + "HLS Segment Length": "Comprimento do segmento HLS em segundos", + "HLS Preset": "Pré-definição HLS", + "HLS List Size": "Tamanho da lista HLS", + "Check Signal Interval": "Verifique o intervalo do sinal em minutos", + "Log Signal Event": "Evento de sinal de registro Apenas cliente", + "Quality": "Qualidade 1 para alta, 23 para Low", + "Rate": "Taxa (FPS)", + "Width": "Largura", + "Height": "Altura", + "Rotate": "Rotação", + "Video Filter": "Filtro de vídeo", + "Font Path": "Caminho da fonte", + "Font Size": "Tamanho da fonte", + "Text Color": "Cor do texto", + "Text Box Color": "Cor da caixa de texto", + "Position X": "Posição X", + "Position Y": "Posição Y", + "Image Location": "Localização da imagem Caminho Absoluto ou deixar em branco para usar global", + "Image Position": "Posição da imagem", + "Frame Rate": "Taxa de quadros (FPS)", + "Image Width": "Largura da imagem", + "Image Height": "Altura da imagem", + "Record File Type": "Tipo de arquivo de gravação", + "Video Codec": "Video Codec", + "Preset": "Pré-definição", + "Audio Codec": "Audio Codec", + "Video Record Rate": "Taxa de gravação de vídeo (FPS)", + "Record Width": "Largura da gravação", + "Record Height": "Altura da gravação", + "Double Quote Directory": "Diretório com aspas duplas Alguns diretórios têm espaços. Usar isso pode bloquear algumas câmeras.", + "Recording Segment Interval": "Intervalo de Segmento de Gravação em minutos", + "Record Video Filter": "Gravar filtro de vídeo", + "Input Flags": "Flags de entrada", + "Snapshot Flags": "Snapshot Flags", + "Detector Flags": "Detector de Flags", + "Stream Flags": "Flags de Transmissão", + "Stream to YouTube": "Transmitir para o YouTube", + "Stream to YouTube Flags": "Transmitir para o YouTube Flags", + "Recording Flags": "Gravando Flags", + "Output Method": "Método de saída", + "Webhook": "Webhook", + "Webhook URL": "Webhook URL", + "Command on Trigger": "Comando quando acionado", + "Command": "Comando", + "Allow Next Command": "Habilitar próximo comando em minutos", + "Allow Next Trigger": "Habilitar próxima ação em milissegundos", + "Save Events to SQL": "Salvar eventos no SQL", + "Email on Trigger": "E-mail quando acionado Emails vão para o endereço de login do titular da conta principal.", + "Allow Next Email": "Permitir próximo e-mail em minutos", + "How to Record": "Como gravar", + "Trigger Record": "Acionar registro", + "Recording Timeout": "Gravando Timeout em minutos", + "Timeout Reset on Next Motion": "Timeout reiniciará no próximo movimento", + "Delete Motionless Video": "Deletar vídeos sem movimento", + "Send Frames": "Enviar quadros Envie os quadros a serem analisados", + "Detector Rate": "Taxa do detector (FPS)", + "Feed-in Image Width": "Largura da imagem de entrada", + "Feed-in Image Height": "Altura da imagem de entrada", + "Check for Motion First": "Verifique primeiro o movimento", + "Detect Objects": "Detectar objetos Veja abaixo", + "Full Frame Detection": "Detecção de quadro completo", + "Country of Plates": "País das placas", + "Email on No Motion": "E-mail em \"Sem movimento\"", + "Timeout": "Timeout", + "Controllable": "Controlável", + "Custom Base URL": "URL Customizada Deixe em branco para usar URL do Host", + "Stop URL": "Parar URL", + "URL Stop Timeout": "URL timeout máximo Parar URL depois de X milissegundos", + "Center": "Centro URL Address", + "Left": "Esquerda URL Address", + "Left Stop": "Esquerda máxima URL Address", + "Right": "Direita URL Address", + "Right Stop": "Direita máxima URL Address", + "Up": "Cima URL Address", + "Up Stop": "Cima máximo URL Address", + "Down": "Baixo URL Address", + "Down Stop": "Baixo máximo URL Address", + "Enable Night Vision": "Ativar visão noturna URL Address", + "Disable Night Vision": "Desativar visão noturna URL Address", + "Zoom Out Stop": "Parar menos zoom URL Address", + "Zoom In Stop": "Parar mais zoom URL Address", + "Log Level": "Nível de registro", + "Save Log in SQL": "Salvar log em SQL Isso pode encher rapidamente.", + "JPEG": "JPEG", + "MJPEG": "MJPEG", + "H.264 / H.265 / H.265+": "H.264 / H.265 / H.265+", + "HLS (.m3u8)": "HLS (.m3u8)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)", + "Shinobi Streamer": "Shinobi Streamer", + "Dashcam (Streamer v2)": "Dashcam (Streamer v2)", + "Local": "Local", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "RTSP": "RTSP", + "UDP": "UDP", + "Auto": "Auto", + "TCP": "TCP", + "Base64 over Websocket": "Base64 sobre Websocket", + "JPEG (Auto Enables JPEG API)": "JPEG (Auto habilitado JPEG API)", + "HLS (includes Audio)": "HLS (inclui áudio)", + "libx264": "libx264", + "libx265": "libx265", + "copy": "copiar", + "No Audio": "Sem áudio", + "aac": "aac", + "ac3": "ac3", + "libmp3lame": "libmp3lame", + "No Rotation": "Sem rotação", + "180 Degrees": "180 Graus", + "90 Counter Clockwise and Vertical Flip (default)": "90 no sentido anti-horário e vertical (Padrão)", + "90 Clockwise": "90 no sentido horário", + "90 Clockwise and Vertical Flip": "90 no sentido horário e vertical", + "Top Right": "Superior direito", + "Top Left": "Superior esquerdo", + "Bottom Right": "Inferior direito", + "Bottom Left": "Inferior esquerdo", + "WebM (libvpx)": "WebM (libvpx)", + "MP4 (copy, libx264, libx265)": "MP4 (copy, libx264, libx265)", + "Default": "Padrão", + "libvpx (Default)": "libvpx (Padrão)", + "libvpx-vp9": "libvpx-vp9", + "libx264 (Default)": "libx264 (Padrão)", + "libvorbis (Default)": "libvorbis (Padrão)", + "libopus": "libopus", + "aac (Default)": "aac (Padrão)", + "Hotswap Modes (Watch-Only)": "Hotswap Modes (Visualizar Apenas)", + "Delete Motionless Videos (Record)": "Eliminar vídeos sem movimento (Gravação)", + "US": "US", + "EU": "EU", + "Silent": "Silencioso", + "Fatal": "Fatal", + "on Error": "em Erro", + "All Warnings": "Todos avisos", + "Debug": "Debugar", + "Export": "Exportar", + "Import": "Importar", + "Simple": "Simples", + "Advanced": "Avançado", + "Error Connecting": "Erro ao conectar", + "DB Lost.. Retrying..": "Banco de dados perdido... Repetindo...", + "Retrying...": "Repetindo...", + "Filter Matches": "Combinações de filtro", + "FilterMatchesText1": "Este filtro atingiu as condições.", + "FilterMatchesText2": "vídeos encontrados.", + "Executed": "Executado", + "Deleted": "Deletado", + "Query": "Pesquisa", + "Filter ID": "Filtrar ID", + "Webdav Error": "Erro Webdav", + "WebdavErrorText": "Não é possível salvar. Você criou os diretórios da câmera dentro do seu diretório de escolhido para isso?", + "File Not Exist": "Arquivo inexistente", + "FileNotExistText": "Não é possível salvar o arquivo inexistente. Algo deu errado.", + "CameraNotRecordingText": "As configurações podem ser incompatíveis. Verifique os encoders. Reiniciando...", + "Camera is not recording": "Câmera não está gravando", + "Camera is not streaming": "Câmera não está transmitindo", + "Restarting Process": "Reiniciado processo", + "Monitor Stopped": "Monitor parado", + "MonitorStoppedText": "A sessão do monitor foi ordenada a parar.", + "Monitor Idling": "Monitor ocioso", + "MonitorIdlingText": "A sessão do monitor foi ordenada para ocioso.", + "NoMotionEmailText1": "Nenhum movimento para", + "NoMotionEmailText2": "Não houve nenhum movimento detectado na câmera para", + "Monitor Name": "Nome do monitor", + "Process Unexpected Exit": "Saída inesperado do processo", + "Process Crashed for Monitor": "Processo de Monitor quebrado", + "FFmpegCantStart": "FFmpeg não pôde iniciar", + "FFmpegCantStartText": "O mecanismo de gravação para esta câmera não pôde começar. Pode haver algo errado com a configuração da sua câmera. Se houver algum registro diferente deste, por favor, coloque-os em Problemas no Github.", + "JPEG Error": "Erro JPEG", + "JPEGErrorText": "Houve um problema ao obter dados da sua câmera.", + "Fatal Maximum Reached": "Máximo atingido, parando câmera.", + "FatalMaximumReachedText": "Erro JPEG fatal.", + "Incorrect Settings Chosen": "Configuração incorreta escolhida", + "Can't Connect": "Não pode conectar", + "Video Finished": "Vídeo finalizado", + "No Monitor Found, Ignoring Request": "Monitor não encontrado, ignorando requisição", + "Event": "Evento", + "EventText1": "Disparou um evento de movimento", + "EventText2": "Não foi possível enviar imagem de e-mail, o arquivo não foi acessado", + "MailError": "MAIL ERROR : Não foi possível enviar e-mail, verifique conf.json. Ignorando qualquer recurso que dependa do envio", + "updateKeyText1": "\"updateKey\" faltando em \"conf.json\", não é possível atualizar dessa maneira até você adicionar", + "updateKeyText2": "\"updateKey\" incorreta", + "Control Error": "Erro de controle", + "ControlErrorText1": "Controle não está ativado", + "NotAuthorizedText1": "Não autorizado, envie o comando inicial com \"auth\",\"ke\", e \"uid\"", + "Fields cannot be empty": "Campos não podem estar vazios", + "AccountEditText1": "Não foi possível editar. Atualize a página se o problema continuar", + "Not an Administrator Account": "Não é uma conta de Administrador", + "superAdminText": "\"super.json\" não existe. Por favor, renomeie \"super.sample.json\" para \"super.json\".", + "Enter this code to proceed": "Informe este código para prosseguir", + "FactorAuthText1": "O código vai estar ativo somente por 15 minutos. Se você entrar novamente o temporizador será reiniciado para 15 minutos com o mesmo código", + "monitorEditText1": "Dados inválidos. Verifique se esta é uma string de importação válida.", + "monitorEditText2": "String de detalhes inválida. Certifique-se de ser uma string JSON e não um objeto comum que está sendo informado", + "Monitor Updated by user": "Monitor atualizado pelo usuário", + "Monitor Added by user": "Monitor adicionado pelo usuário", + "monitorGetText1": "Requisição incompleta. Remova a última barra da URL ou informe um valor válido", + "Monitor mode changed": "Modo de monitor mudou", + "Reset Timer": "Temporizador de reinicialização", + "Monitor mode is already": "Modo de monitor já está em uso", + "Monitor or Key does not exist.": "Monitor ou chave não existe", + "No Group with this key exists": "Nenhum grupo com esta chave foi encontrado", + "Trigger Successful": "Disparou bem sucedido", + "No such file": "Arquivo inexistente", + "modifyVideoText1": "Método não existe. Verifique se o último valor da URL não está em branco", + "CPU indicator will not work. Continuing...": "Indicador de CPU não irá funcionar. Continuando...", + "startUpText0": "Verificação de tamanho para vídeos", + "startUpText1": "Verificação de fim de tamanho para vídeos", + "startUpText2": "Todos usuário verificados. Aguarde para fechar arquivos abertos e remover arquivos por limite de usuário", + "startUpText3": " Esperando dar uma verificação de vídeo inacabada algum tempo. 3 segundos", + "startUpText4": "Iniciando todos os monitores para assistir e gravar", + "startUpText5": "Shinobi está pronto.", + "Edit": "Editar", + "Dashboard Language": "Idioma do Painel de Controle", + "File Not Found": "Arquivo não encontrado", + "No Monitor Exists with this ID.": "Não existem monitores com esse ID.", + "Cannot watch a monitor that isn't running.": "Não pode assistir um monitor que não está rodando.", + "Not Permitted": "Não permitidos", + "Not Authorized": "Não autorizados", + "Generate Subtitles": "Gerar legendas", + "Video Limit":"Limite de vídeo", + "Preview":"Visualização", + "Websocket Connected":"Websocket conectado", + "Websocket Disconnected":"Websocket desconectado", + "New Authentication Token":"Novo token de autenticação", + "All Logs":"Todos logs", + "For Group":"Para grupo", + "Basic Authentication":"Autenticação básica", + "Superuser Logs":"Logs do Superusuário", + "Authentication Failed":"Autenticação falhou", + "Max Number of Cameras":"Número máximo de câmeras", + "Can edit Max Storage":"Pode editar Armazenamento Máximo", + "Can edit Max Days":"Pode editar Máximo de Dias", + "in Days":"em Dias", + "Can edit how long to keep Logs":"Pode editar por quanto tempo maneter logs", + "Can use Admin Panel":"Pode usar Painel Administrativo", + "Can use WebDAV":"Pode usar WebDAV", + "Can use LDAP":"Pode usar LDAP", + "Can edit how long to keep Events":"Pode editar quanto tempo manter eventos", + "Leave blank for unlimited":"Deixe em branco para ilimitado", + "Limited":"Limitado", + "All Privileges":"Todos Privilégios", + "LDAP":"LDAP", + "LDAP Success":"LDAP Sucesso", + "LDAP User Authenticated":"Usuário LDAP Usuário Autenticado", + "LDAP User is New":"Usuário LDAP é Novo", + "Creating New Account":"Criando Nova Conta", + "bindDN":"Vincular DN", + "Bind Credentials":"Vincular Credenciais (Senha)", + "Search Base":"Base de Pesquisa", + "Mode": "Modo", + "Search Filter":"Procurar Filtro" +} diff --git a/languages/ru.json b/languages/ru.json new file mode 100644 index 0000000..79063d4 --- /dev/null +++ b/languages/ru.json @@ -0,0 +1,496 @@ +{ + "\"No Motion\" Detector": "\"Нет Движения\" Детектор", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "180 Degrees": "180 градусов", + "2-Factor Authentication": "2-Факторной Аутентификации", + "90 Clockwise": "90 по часовой стрелке", + "90 Clockwise and Vertical Flip": "90 по часовой стрелке и вертикальный флип", + "90 Counter Clockwise and Vertical Flip (default)": "90 против часовой стрелки и по вертикали (по умолчанию)", + "API": "API-интерфейс", + "API Key Added": "Ключ API добавлены", + "API Key Deleted": "API-ключ удален", + "API Keys": "Ключи API", + "APIKeyAddedText": "Вы можете использовать этот ключ сейчас.", + "APIKeyDeletedText": "Ключ был удален. Он больше не будет работать.", + "ASC": "АСК", + "Account Info": "Счета Информация", + "AccountEditText1": "Не мог изменить. Обновить страницу, если проблема продолжается.", + "Accounts": "Счетов", + "Action for Selected": "Действие для выбранных", + "Add": "Добавить", + "Add Monitor": "Добавить Монитор", + "Add New": "Добавить Новый", + "Admin": "Админ", + "Advanced": "Расширенный", + "Again": "Снова", + "All Monitors": "Все Мониторы", + "All Monitors and Privileges": "Все мониторы и привилегии", + "All Warnings": "Все Предупреждения", + "Allow Next Command": "Разрешить следующей команды в течение нескольких минут", + "Allow Next Email": "Разрешить следующей электронной почте в течение нескольких минут", + "Allow Next Trigger": "Допустить следующего триггера в Миллисекундах", + "Allowed IPs": "Допускается ИПС", + "Analyzation Duration": "Продолжительность Анализа", + "Archive": "Архив", + "Audio Codec": "Аудио Кодек", + "Authenticate": "Аутентифицировать", + "Auto": "Авто", + "Autosave": "Автосохранение", + "Base64 over Websocket": "В base64 через websocket", + "Bottom Left": "Внизу Слева", + "Bottom Right": "Нижний Правый", + "Browser Console Log": "Консоли Браузера Войти", + "CPU": "Процессор", + "CPU indicator will not work. Continuing...": "Индикатор процессора не будет работать. Продолжение...", + "CSS": "В CSS Стиль вашей приборной панели.", + "Calendar": "Календарь", + "Camera Password": "Пароль Камеры", + "Camera Username": "Имя Пользователя Камеры", + "Camera is not recording": "Камера не записывает", + "CameraNotRecordingText": "Параметры могут быть несовместимы. Проверить датчики. Перезапуск...", + "Can Control Monitors": "Может Управлять Мониторами", + "Can Delete Videos": "Можно Удалять Видео", + "Can Delete Videos and Events": "Можно удалять видео и событий", + "Can Edit Monitor": "Можете Редактировать Монитор", + "Can Get Logs": "Можете Сделать Логи", + "Can Get Monitors": "Можете Сделать Мониторы", + "Can View Monitor": "Можно Посмотреть Монитор", + "Can View Snapshots": "Можете Посмотреть Снимки", + "Can View Streams": "Можете Посмотреть Потоков", + "Can View Videos": "Можете Посмотреть Видео", + "Can View Videos and Events": "Можете посмотреть видео и событий", + "Can't Connect": "Не могу подключиться", + "Center": "Центр URL-Адрес", + "Chat on Discord": "Чат на раздор", + "Check": "Проверить", + "Check Signal Interval": "Проверка сигнала интервал в минутах", + "Check for Motion First": "Проверить в первую очередь для движения", + "Close": "Закрыть", + "Closed": "Закрытые", + "Command": "Команда", + "Command on Trigger": "Команду на триггер", + "Complete Stream URL": "Полный URL-адрес потока", + "Confirm": "Подтвердить", + "Connected": "Подключен", + "Connection Type": "Тип Подключения", + "Control": "Контроль", + "Control Error": "Ошибка Контроля", + "ControlErrorText1": "Контроль не включен", + "Controllable": "Управляема", + "Country of Plates": "Страна пластин", + "Counts of Motion": "Подсчитывает движения", + "Current": "Тока", + "Currently viewing": "В настоящее время просмотр", + "Custom": "Заказ", + "Custom Base URL": "Базовый пользовательский URL-адрес оставить пустым, чтобы использовать URL-адрес узла", + "DB Lost.. Retrying..": "База Данных Потеряла.. Повтор..", + "DESC": "Описание", + "Dashboard": "Приборной панели", + "Dashboard Language": "Язык Приборной Панели", + "Dashcam": "Автомобильный видеорегистратор", + "Dashcam (Streamer v2)": "Автомобильный видеорегистратор (Стример П2)", + "Date Range": "Диапазон Дат", + "Debug": "Отлаживать", + "Default": "По умолчанию", + "Delete": "Удалить", + "Delete Filter": "Удалить Фильтр", + "Delete Matches": "Удалить Играм", + "Delete Monitor": "Удалить Монитор", + "Delete Motionless Video": "Удалить Недвижно Видео", + "Delete Motionless Videos (Record)": "Удалить Неподвижными Видео (Запись)", + "Delete Selected Videos": "Удаление Выбранного Видео", + "Delete Video": "Удалить Видео", + "Delete selected": "Удалить выбранные", + "DeleteMonitorText": "Вы действительно хотите удалить этот монитор? Нельзя восстановить. Файлы для этот идентификатор будет оставаться в файловой системе. Если вы решили воссоздать монитора с одинаковым кодом видео и события станут видны в личном кабинете.", + "DeleteSelectedVideosMsg": "Вы действительно хотите удалить эти видео? Вы не сможете восстановить их.", + "DeleteVideoMsg": "Вы действительно хотите удалить это видео? Нельзя восстановить.", + "Deleted": "Удален", + "Detect Objects": "Обнаруживать объекты ниже", + "Detector": "Детектор", + "Detector Flags": "Флаги Детектор", + "Detector Rate": "Детектор скорости (ФПС)", + "DetectorText": "

Когда показана Ширина и Высота коробки, вы должны установить их до 640х480 или ниже. Это позволит оптимизировать скорость чтения кадров.

", + "Disable Night Vision": "Отключить ночное видение URL-Адрес", + "Disable Nightvision": "Отключение Ночного Видения", + "Disabled": "Отключен", + "Documentation": "Документация", + "Don't show this anymore": "Больше не показывать это", + "Double Quote Directory": "Двойная Кавычка каталога у некоторых каталогов есть пробелы. С помощью этого может произойти сбой некоторых камер.", + "Down": "Вниз URL-Адрес", + "Down Stop": "Вниз стоп URL-Адрес", + "Download": "Скачать", + "EU": "ЕС", + "Edit": "Редактировать", + "Email": "Электронной почты", + "Email Details": "Подробности По Электронной Почте", + "Email on No Motion": "Электронной почты на \"нет движения\"", + "Email on Trigger": "Электронной почты на Триггерных писем перейти к главной владельца счета адрес для входа.", + "Enable Night Vision": "Включение ночного видения URL-Адрес", + "Enable Nightvision": "Включение Ночного Видения", + "Enabled": "Включен", + "End": "Конец", + "End Time": "Время Окончания", + "Ended": "Закончился", + "Enlarge": "Увеличить", + "Enter this code to proceed": "Введите этот код, чтобы продолжить", + "Equal to": "Равна", + "Error Connecting": "Ошибка Подключения", + "Event": "Событие", + "Event Limit": "Лимит Событие", + "EventText1": "Срабатывает событие движения в", + "EventText2": "Не мог изображения по электронной почте, файл не был доступен", + "Events": "События", + "Example": "Пример", + "Execute Command": "Выполнить Команду", + "Executed": "Выполнен", + "Export": "Экспорт", + "FFmpegCantStart": "Видео не смог запустить", + "FFmpegCantStartText": "Запись двигатель для этой камеры не удалось запустить. Там может быть что-то не так с настройкой камеры. Если есть какие-либо другие журналы, чем этот, пожалуйста, пишите в вопросы на github.", + "FFmpegTip": "FFprobe-простой мультимедийный анализатор потоков. Вы можете использовать его для вывода всевозможной информации о входных данных, включая Продолжительность, частоту кадров, Размер кадра и т. д.", + "FFprobe": "Зонд", + "FactorAuthText1": "Код будет активна только в течение 15 минут. Если вы войти снова, Таймер будет сброшен до 15 минут с тем же кодом.", + "Fatal": "Роковой", + "Fatal Maximum Reached": "Роковой Максимальным Достигнутым, Останавливая Камеру.", + "FatalMaximumReachedText": "Ошибка JPEG был смертельным.", + "Feed-in Image Height": "Кормить-в Высота изображения", + "Feed-in Image Width": "Кормить-в изображения Ширина", + "Fields cannot be empty": "Поля не могут быть пустыми", + "File Not Exist": "Файл Не Существует", + "File Not Found": "Файл Не Найден", + "File Type": "Тип Файла", + "FileNotExistText": "Не удается сохранить файл не существует. Что-то пошло не так.", + "Filename": "Именем", + "Filesize": "Размер", + "Filter ID": "Идентификатор фильтра", + "Filter Matches": "Фильтра", + "Filter Name": "Название Фильтра", + "FilterMatchesText1": "Этот фильтр имеет условия.", + "FilterMatchesText2": "видео нашли.", + "Filters": "Фильтры", + "Filters Updated": "Фильтры Обновлены", + "FiltersUpdatedText": "Ваши изменения были сохранены и применены.", + "Find Where": "Найти Где", + "Fix": "Исправить", + "Fix Video": "Исправить Видео", + "FixVideoMsg": "Вы хотите, чтобы удалить это видео? Вы не можете отменить это действие.", + "Font Path": "Путь Шрифта", + "Font Size": "Размер Шрифта", + "Force Port": "Сила Порта", + "Found Devices": "Найденные Устройства", + "Frame Rate": "Частота кадров (кадров / с)", + "Full Frame Detection": "Полное Обнаружение Кадра", + "Fullscreen": "Полноэкранный", + "Greater Than": "Больше", + "Greater Than or Equal to": "Больше или равна", + "Group Key": "Ключевые Группы", + "Group Name": "Название Группы", + "Grouping": "Группировка ", + "H.264 / H.265 / H.265+": "Формат H. 264 / H. 265 / H. 265 В ", + "HLS (.m3u8)": "ЗОЖ (.m3u8 форматов)", + "HLS (includes Audio)": "ЗОЖ (включает Аудио)", + "HLS Audio Encoder": "ЗОЖ Аудио Шифратор", + "HLS List Size": "Размер списка ЗОЖ", + "HLS Preset": "ЗОЖ предустановленных", + "HLS Segment Length": "ЗОЖ сегмент длиной в секунд", + "HLS Video Encoder": "ЗОЖ видео Энкодера", + "HTTP": "Протокол http", + "HTTPS": "Протоколу https", + "Height": "Высота", + "Help": "Помогите", + "Hide List": "Скрыть Список", + "Hide Notes": "Скрыть Примечания", + "Host": "Хозяин", + "Hotswap Modes (Watch-Only)": "Режима Горячей Замены (Часы Только)", + "How to Record": "Как записать", + "IP Address": "IP-адрес", + "Identity": "Личность", + "IdentityText1": "Это как система будет определять данные для этого потока. Вы не можете изменить идентификатор монитора после того, как вы нажали \"сохранить\". Если вы хотите, вы можете сделать монитор код более читабельным, прежде чем продолжить.", + "IdentityText2": "Вы можете дублировать монитор, изменяя идентификатор монитора нажмите клавишу сохранить. Вы не можете использовать идентификатор монитора, который уже существует или он сохранит за монитора базы данных.", + "Idle": "Праздный", + "Image Height": "Высота Изображения", + "Image Location": "Изображения Расположение абсолютный путь или оставьте поле пустым, чтобы использовать глобальные", + "Image Position": "Положение Изображения", + "Image Width": "Ширина Изображения", + "Import": "Импорт", + "Import Monitor Configuration": "Импорт Конфигурации Монитора", + "ImportMonitorConfigurationText": "Это overrwrite любые изменения в настоящее время не сохранены. Импортированные изменения будут применены только при нажатии сохранить.", + "In": "В", + "Incorrect Settings Chosen": "Выбраны Неправильные Параметры", + "Indifference": "Равнодушие", + "Input": "Вход", + "Input Flags": "Входных Флагов", + "Input Type": "Тип Входного Сигнала", + "InputText1": "Этот раздел рассказывает шиноби, как использовать поток. Для оптимальной производительности, попробуйте настройки внутренних параметров камеры. Найти следующие варианты и установить их, как показано. Чтобы найти вашу камеру, вы можете использовать встроенный onvif и сканер шиноби. Некоторые камеры onvif требуют использования инструмента управления, чтобы изменить свои внутренние настройки. Если Вы не можете найти вашей камеры вы можете попробовать onvif и диспетчер устройств для Windows.", + "InputText2": "
  • Кадров (fps) : высокая : 10 - 15 ФПС, минимум : 2-5 ФПС
  • I-кадр интервал : 80
  • Тип битрейта : CBR (Постоянный Битрейт)
  • Битрейт : между 256кбит / с - 500 Кбит / с
", + "InputText3": "Если вам нужна помощь в выяснение того, что входной тип Вашей камеры вы можете посмотреть в камеры URL-адреса в списке на шиноби сайт.", + "Invalid JSON": "Недопустимый Формат json", + "InvalidJSONText": "Пожалуйста, убедитесь, что это действительный json-строку для конфигурации шиноби монитор.", + "JPEG": "В формате JPEG", + "JPEG (Auto Enables JPEG API)": "В формате JPEG (авто позволит использовать API в формате JPEG)", + "JPEG API": "В формате JPEG интерфейс API снимка (цги-бин)", + "JPEG Error": "Ошибка формата JPEG", + "JPEG Mode": "JPEG режим", + "JPEGErrorText": "Возникла проблема получения данных с камеры.", + "Leave blank for random.": "Оставьте пустым для случайных.", + "Left": "Левый Адрес", + "Left Stop": "Левый стоп URL-Адрес", + "Less Than": "Меньше", + "Less Than or Equal to": "Меньше или равно", + "Like": "Как", + "Lisence Plate Detector": "Лицензии Детектор Пластины", + "List Toggle": "Список Тумблер", + "Live Stream Toggle": "Жить Переключения Потока", + "Live View": "Живой Просмотр", + "Local": "Местные", + "Log Level": "Уровень Журнала", + "Log Signal Event": "Журнал сигнал события на стороне клиента только", + "Logging": "Лесозаготовки", + "Login": "Логин", + "Logout": "Выход", + "Logs": "Журналы", + "MB": "МБ", + "MJPEG": "Формат MJPEG", + "MP4 (copy, libx264, libx265)": "МР4 (копия, поддержкой libx264, libx265)", + "MPEG-4 (.mp4 / .ts)": "Формат MPEG-4 (.МР4 / .ТС)", + "MailError": "Mail ошибка : не удалось отправить письмо, проверьте конф.в json. Пропуская какие-либо функции, опираясь на рассылки.", + "Matches": "Матчи", + "Max Storage Amount": "Памяти Макс. объем в мегабайтах", + "Mode": "Режим", + "Monitor": "Монитор", + "Monitor Added by user": "Монитор, добавленные пользователем.", + "Monitor Capture Rate": "Монитор скорости захвата (ФПС)", + "Monitor Groups": "Мониторинг Групп", + "Monitor ID": "Идентификатор монитора", + "Monitor Idling": "Монитор Простаивания", + "Monitor Name": "Имя Монитора", + "Monitor Settings": "Настройки Монитора", + "Monitor Stopped": "Монитор Перестал", + "Monitor Updated by user": "Монитор обновляться пользователем.", + "Monitor mode changed": "Режим монитора меняется", + "Monitor mode is already": "Режим монитора уже", + "Monitor or Key does not exist.": "Монитор или ключ не существует.", + "MonitorIdlingText": "Монитор сессии был заказан на холостом ходу.", + "MonitorStoppedText": "Монитор сеансов было приказано прекратить.", + "Monitors": "Мониторы", + "Monitors per row": "Мониторы на строку для монтажа", + "Montage": "Фотомонтаж", + "Motion GUI": "ГУЙ движения", + "Motion Meter": "Метр Движения", + "Name": "Название", + "No": "Нет", + "No Audio": "Нет Звука", + "No Data": "Нет Данных", + "No Events found for this video": "Не для этого видео", + "No Group with this key exists": "Ни одна группа с таким ключом существует", + "No Monitor Found, Ignoring Request": "Нет Монитор Нашли, Игнорируя Просьбу", + "No Rotation": "Нет Вращения", + "No such file": "Нет такого файла", + "NoMotionEmailText1": "Нет движения", + "NoMotionEmailText2": "Не было никакого движения на камеру", + "NoVideosFoundForDateRange": "Не нашла видео в этот диапазон дат. Попробуйте установить дату начала дальше.", + "Not Authorized": "Не Разрешено", + "Not Connected": "Не Подключен", + "Not Equal to": "Не равны", + "Not In": "Не В", + "Not Matches": "Не Соответствует", + "Not Permitted": "Не Допускается", + "Not an Administrator Account": "Не является учетной записью администратора", + "NotAuthorizedText1": "Не разрешенные, представить команду init с \"авт\",\"ке\" и \"юид\"", + "Notes": "Примечания", + "NotesPlacholder": "Комментарии Вы хотите оставить на этом настройки камеры.", + "Number of Days to keep": "Количество дней хранения", + "ONVIF": "Стандарт onvif", + "ONVIF Scanner": "Сканер стандарта onvif", + "ONVIFnote": "Откройте стандарт onvif устройств за пределами вашей сети или оставьте его пустым для сканирования сети.
Имя пользователя и пароль можно оставить пустым.", + "OpenCV Cascades": "В Формате Opencv Каскада", + "Order Streams": "Потоки Заказов", + "Output Method": "Способ Вывода", + "Password": "Пароль", + "Password Again": "Пароль Еще Раз", + "Passwords don't match": "Пароли не совпадают", + "Paste JSON here.": "Вставить json здесь.", + "Path": "Путь", + "Permissions": "Разрешения", + "Points": "Точки при добавлении точек, щелкните на краю полигона.", + "Port": "Порт", + "Position X": "Положение X", + "Position Y": "Позиция Y", + "Power Video Viewer": "Питания Видео Просмотра", + "Power Viewer": "Зритель Власти", + "Preferences": "Предпочтения", + "Preset": "Предустановленные", + "Probe Size": "Размер Зонда", + "Process Crashed for Monitor": "Процесс разбился на монитор", + "Process Unexpected Exit": "Процесс Неожиданный Выход", + "Profile": "Профиль", + "Quality": "Качество 1 высота, 23 низкий", + "Query": "Запрос", + "RAM": "Оперативной памяти", + "RTSP": "Протокол RTSP", + "RTSP Transport": "РЦП транспорта", + "Range or Single": "Диапазон или один", + "Rate": "Скорость (кадров в секунду)", + "Record": "Запись", + "Record File Type": "Тип Записи Файла", + "Record Height": "Рекордную Высоту", + "Record Video Filter": "Запись Видео Фильтр", + "Record Width": "Запись Ширина", + "Recording": "Запись", + "Recording Flags": "Запись Флаги", + "Recording Segment Interval": "Запись сегмента интервала в минутах", + "Recording Timeout": "Запись тайм-аута в минутах", + "Recording Timestamp": "Метки Записи", + "Recording Watermark": "Запись Водяной Знак", + "RecordingText": "Рекомендуется установить рекорд типа файла в формате WebMи MP4 и видео кодеков для libvpxкопия или поддержкой libx264 потому что твой ввод Тип имеет значение .", + "Refresh List of Cascades": "Обновить список каскадов", + "Region Editor": "Редактор Области", + "Region Name": "Название Области", + "RegionNote": "Точки сохраняются только при нажатии Сохранить на монитор настройки окна.", + "Regions": "Регионы", + "Remember Me": "Запомнить Меня", + "Reset Timer": "Сброс Таймера", + "Restarting Process": "Процесс Перезагрузки", + "Retry Connection": "Повторить попытку подключения несколько раз допустить провала", + "Retrying...": "Повторение...", + "Right": "Правильный URL-Адрес", + "Right Stop": "Право прекратить URL-Адрес", + "Rotate": "Повернуть", + "Save": "Сохранить", + "Save Directory": "Сохранить Каталог", + "Save Events to SQL": "Сохранять события в SQL", + "Save Log in SQL": "Сохранить журнал в SQL это может быстро заполняются.", + "Save as": "Сохранить как", + "Saved Filters": "Сохраненные Фильтры", + "Scan Settings": "Параметры Сканирования", + "Search": "Поиск", + "Send Frames": "Отправить кадры пуш-периодах для анализа", + "Separate with commas, no spaces": "Отделить запятыми, без пробелов", + "Set to Watch Only": "Установить, чтобы смотреть только", + "Settings": "Параметры", + "Settings Changed": "Настройки Изменились", + "SettingsChangedText": "Ваши настройки были сохранены и применены.", + "Shinobi": "Шиноби", + "Shinobi Streamer": "Шиноби Серпантин", + "Show Logs": "Показать Журналы", + "Silent": "Молчит", + "Simple": "Простой", + "Size (mb)": "Размер (Мб)", + "Snapshot": "Снимок", + "Snapshot Flags": "Снимок Флаги", + "Snapshots": "Снимки", + "Sort By": "Сортировать По", + "Start": "Начать", + "Start Recording": "Начать Запись", + "Start Time": "Время Начала", + "Started": "Начал", + "Status Indicator": "Индикатор Состояния", + "Stop URL": "Остановить URL", + "Stream": "Поток", + "Stream Flags": "Флаги Трансляция", + "Stream Timestamp": "Метка Поток", + "Stream Type": "Тип Потока", + "Stream Watermark": "Водяной Поток", + "Stream to YouTube": "Трансляцию на YouTube", + "Stream to YouTube Flags": "Поток флаги на YouTube", + "StreamText": "

В этом разделе будет указать основной поток метода и его параметров. Этот поток будет отображаться на приборной панели. Если вы решите использовать ЗОЖ, в формате JPEG или MJPEG, то вы можете потреблять поток через другие программы.

В формате JPEG потока, по сути, выключает основной поток и использует моментальный снимок ящика, чтобы получить кадры.

", + "Streamer": "Серпантин", + "Streams": "Потоки", + "Superuser": "Суперпользователя", + "Switch on for Still Image": "Переключиться на еще изображения", + "TCP": "Протокол TCP", + "Text Box Color": "Цвет Текстового Поля", + "Text Color": "Цвет Текста", + "Time-lapse": "Промежуток времени", + "Time-lapse Tool": "Инструмент покадровой", + "Timeout": "Ожидания", + "Timeout Reset on Next Motion": "Таймаут сброса на следующем движении", + "Toggle Sidebar": "Переключение Боковой Панели", + "Top Left": "Верхний Левый", + "Top Right": "Вверху Справа", + "Trigger Record": "Триггер Записи", + "Trigger Successful": "Триггер Успешным", + "UDP": "УДП", + "URL": "URL-адрес", + "URL Stop Timeout": "Адрес останавливать время ожидания запуска остановки URL после x миллисекунд", + "US": "Нам", + "Unable to Launch": "Не удалось запустить", + "UnabletoLaunchText": "Пожалуйста, сохраните сначала новый монитор. Затем попытаться запустить редактор регионе.", + "Up": "До URL-Адрес", + "Up Stop": "До остановки URL-Адрес", + "Username": "Имя пользователя", + "Value": "Значение", + "Video": "Видео", + "Video Codec": "Видеокодек", + "Video Filter": "Видеофильтра", + "Video Finished": "Видео Закончил", + "Video Length (minutes) and Motion Count per video": "Продолжительность видео (минут) и движения на видео", + "Video Record Rate": "Видео Скорость записи (кадров в секунду)", + "Video Status": "Статус Видео", + "Video and Time Span (Minutes)": "Прямая и отрезок времени (минут)", + "Videos": "Видео", + "Videos List": "Видео Список", + "Watch": "Смотреть", + "Watch Only": "Смотреть Только", + "WebDAV": "Протокол WebDAV", + "WebM (libvpx)": "Колсоном (libvpx)", + "Webdav Error": "Ошибка В WebDAV", + "WebdavErrorText": "Не удается сохранить. Вы сделали камеры папки внутри выбранной сохранить каталог?", + "Webhook": "Веб-перехватчик", + "Webhook URL": "URL-адрес веб-перехватчик", + "Width": "Ширина", + "Yes": "Да", + "Zoom In": "Зум в URL-Адрес", + "Zoom In Stop": "Зум в URL-Адрес", + "Zoom Out": "Уменьшать URL-Адрес", + "Zoom Out Stop": "Уменьшать остановка URL-Адрес", + "a day": "в день", + "a few seconds": "несколько секунд", + "a minute": "минуту", + "a month": "месяц", + "a year": "год", + "aac": "ААС", + "aac (Default)": "ААС (по умолчанию)", + "ac3": "АС3", + "ago": "назад", + "an hour": "час", + "blankPassword": "Оставьте поле пустым, чтобы сохранить тот же пароль", + "calendar": "календарь", + "clientStreamFailedattemptingReconnect": "На стороне клиента проверить ctream не удалось, попытка воссоединиться.", + "confirmDeleteFilter": "Вы действительно хотите удалить этот фильтр? Нельзя восстановить.", + "copy": "копия", + "days": "дней", + "dropBoxSuccess": "Успехов! Файлы, сохраненные в Dropbox.", + "for Global Access": "для глобального доступа", + "hours": "часов", + "in": "в", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis были (по умолчанию)", + "libvpx (Default)": "libvpx (по умолчанию)", + "libvpx-vp9": "libvpx-vp9 или", + "libx264": "поддержкой libx264", + "libx264 (Default)": "поддержкой libx264 (по умолчанию)", + "libx265": "libx265", + "minutes": "минут", + "modifyVideoText1": "Метод не существует. Убедитесь, что последнее значение URL является не пустым.", + "monitorEditFailedMaxReached": "Ваша учетная запись, достигнуто Максимальное число камер, которые могут быть созданы. Поговорить с администратором, если вы хотели бы это изменить.", + "monitorEditText1": "Неверные данные, проверьте, чтобы увидеть это допустимая строка импорт.", + "monitorEditText2": "Поврежденных Деталей Строку. Проверьте, это json-строку, а не обычный объект был принят.", + "monitorGetText1": "неполный запрос, удалить последний слеш в URL или положить приемлемой стоимости.", + "months": "месяцев", + "noSpecialCharacters": "Без пробелов или специальных символов.", + "on": "на", + "on Error": "в случае ошибки", + "startUpText0": "проверка размера для видео", + "startUpText1": "конец проверить Размер для видео", + "startUpText2": "все пользователи проверены, подождите закрывать открытые файлы и удалить файлы через лимит пользователей", + "startUpText3": "ждал недостроенный видео проверяем какое-то время. 3 секунды.", + "startUpText4": "начиная все мониторы установить для просмотра и записи", + "startUpText5": "Шиноби готов.", + "superAdminText": "\"супер.в json\" не существует. Пожалуйста, переименуйте \"супер.образец.в json\" на \"супер.в json\".", + "superAdminTitle": "Шиноби : Супер Админ", + "total": "общая", + "updateKeyText1": "\"updateKey\" отсутствует \"конф.с json\", нельзя делать обновление таким образом, пока вы не добавите его.", + "updateKeyText2": "\"updateKey\" - это неправильно.", + "years": "лет" +} diff --git a/languages/zh.json b/languages/zh.json new file mode 100644 index 0000000..7dbfcd0 --- /dev/null +++ b/languages/zh.json @@ -0,0 +1,496 @@ +{ + "\"No Motion\" Detector": "\"不运动\"探测器", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "180 Degrees": "180度", + "2-Factor Authentication": "2因素认证", + "90 Clockwise": "90顺时针", + "90 Clockwise and Vertical Flip": "90顺时针方向和垂直翻转", + "90 Counter Clockwise and Vertical Flip (default)": "90逆时针方向和垂直翻转的(默认)", + "API": "API", + "API Key Added": "API关键的加入", + "API Key Deleted": "API关键删除", + "API Keys": "API钥匙", + "APIKeyAddedText": "你可以用这个关键。", + "APIKeyDeletedText": "关键已被删除。 它将不再起作用。", + "ASC": "ASC", + "Account Info": "帐户信息", + "AccountEditText1": "不可能编辑。 刷新页面,如果问题继续进行。", + "Accounts": "帐户", + "Action for Selected": "行动选择", + "Add": "添加", + "Add Monitor": "增加监视", + "Add New": "添加新的", + "Admin": "管理员", + "Advanced": "先进的", + "Again": "再一次", + "All Monitors": "所有监视器", + "All Monitors and Privileges": "所有监视和特权", + "All Warnings": "所有的警告", + "Allow Next Command": "允许下一个命令 在分钟", + "Allow Next Email": "允许下电子邮件 在几分钟", + "Allow Next Trigger": "允许下一个触发 在毫秒", + "Allowed IPs": "允许IPs", + "Analyzation Duration": "分析的持续时间", + "Archive": "存档", + "Audio Codec": "音频编", + "Authenticate": "进行身份验证", + "Auto": "汽车", + "Autosave": "自动保存", + "Base64 over Websocket": "Base64过Websocket", + "Bottom Left": "左下", + "Bottom Right": "右", + "Browser Console Log": "浏览器控制台的记录", + "CPU": "CPU", + "CPU indicator will not work. Continuing...": "CPU指标将不会的工作。 继续...", + "CSS": "CSS 的风格你的仪表板。", + "Calendar": "日历", + "Camera Password": "摄像机的密码", + "Camera Username": "摄像机的用户名", + "Camera is not recording": "摄像机是不是记录", + "CameraNotRecordingText": "设置可能不相容的。 检查编码器。 重新启动...", + "Can Control Monitors": "可以控制的监视器", + "Can Delete Videos": "可以删除的视频", + "Can Delete Videos and Events": "可以删除的视频和活动", + "Can Edit Monitor": "可以编辑监控", + "Can Get Logs": "可以得到日志", + "Can Get Monitors": "可以得到监视", + "Can View Monitor": "可以查看监视器", + "Can View Snapshots": "可以查看的快照", + "Can View Streams": "可以看流", + "Can View Videos": "可以观看视频", + "Can View Videos and Events": "可以观看视频和活动", + "Can't Connect": "无法连接", + "Center": "中心 的URL地址", + "Chat on Discord": "聊天上的不和谐", + "Check": "检查", + "Check Signal Interval": "检查信号的时间间隔 在分钟", + "Check for Motion First": "检查运动的第一个", + "Close": "靠近", + "Closed": "关闭", + "Command": "命令", + "Command on Trigger": "命令触发", + "Complete Stream URL": "完整的流网址", + "Confirm": "确认", + "Connected": "连接", + "Connection Type": "连接类型", + "Control": "控制", + "Control Error": "控制误差", + "ControlErrorText1": "控制没有启用", + "Controllable": "可控的", + "Country of Plates": "国家的板", + "Counts of Motion": "项运动", + "Current": "电流", + "Currently viewing": "目前的观察", + "Custom": "定义", + "Custom Base URL": "定义基地址 留下的空白使用主机URL", + "DB Lost.. Retrying..": "数据库丢失。。重试..", + "DESC": "DESC", + "Dashboard": "仪表板", + "Dashboard Language": "仪表板语言", + "Dashcam": "行车记录仪", + "Dashcam (Streamer v2)": "行车记录仪(流v2)", + "Date Range": "日期范围", + "Debug": "调试", + "Default": "默认的", + "Delete": "删除", + "Delete Filter": "删除过滤器", + "Delete Matches": "删除匹配", + "Delete Monitor": "删除监控器", + "Delete Motionless Video": "删除一动不动的视频", + "Delete Motionless Videos (Record)": "删除一动不动的视频(记录)", + "Delete Selected Videos": "删除选择的视频", + "Delete Video": "删除的视频", + "Delete selected": "删除选择", + "DeleteMonitorText": "你想要删除这个监视器吗? 你不能恢复。 该文件为这个ID将保留在文件系统。 如果你选择重新建立一个监测与同一标识的影片和事件将变得可见,在仪表板。", + "DeleteSelectedVideosMsg": "你想要删除这些视频? 你不能恢复他们。", + "DeleteVideoMsg": "你想要删除这个视频? 你不能恢复。", + "Deleted": "已删除", + "Detect Objects": "检测对象, 见下", + "Detector": "探测器", + "Detector Flags": "探测器的标志", + "Detector Rate": "检测率 (》)", + "DetectorText": "

当宽度和高度框显示,你应该将它们设置为640x480或以下。 这将优化该阅读的速度框架。

", + "Disable Night Vision": "禁止夜视 的URL地址", + "Disable Nightvision": "禁止夜视", + "Disabled": "残疾人", + "Documentation": "文档", + "Don't show this anymore": "不再这样下去了", + "Double Quote Directory": "双引目录中的 一些目录具有空间。 使用这个可能会崩溃,一些摄像机。", + "Down": "下 URL地址", + "Down Stop": "下站 的URL地址", + "Download": "下载", + "EU": "欧盟", + "Edit": "编辑", + "Email": "电子邮件", + "Email Details": "电子邮件的细节", + "Email on No Motion": "电子邮件上的\"不动\"", + "Email on Trigger": "电子邮件,在触发 的电子邮件去的主要账户持有人的登录地址。", + "Enable Night Vision": "启用夜视 的URL地址", + "Enable Nightvision": "启用夜视", + "Enabled": "启用", + "End": "结束", + "End Time": "结束的时间", + "Ended": "结束", + "Enlarge": "放大", + "Enter this code to proceed": "输入这个代码来进入", + "Equal to": "等于", + "Error Connecting": "错误的连接", + "Event": "事件", + "Event Limit": "事件的限制", + "EventText1": "触发事件在运动", + "EventText2": "不能电子邮件的图像、文件是不可访问", + "Events": "事件", + "Example": "例", + "Execute Command": "执行命令", + "Executed": "执行", + "Export": "出口", + "FFmpegCantStart": "。不能开始", + "FFmpegCantStartText": "记录的引擎这摄像机不能开始。 有可能是错误的东西与你的摄像机的配置。 如果有任何记录其他比这个请帖子他们在该 问题 上的审查中。", + "FFmpegTip": "FFprobe是一个简单的多媒体流的分析仪。 你可以用它来输出的所有种类的信息输入其中包括持续时间,框率,框架大小,等等。", + "FFprobe": "探针", + "FactorAuthText1": "该守则将只是活跃的15分钟。 如果你再次登录的计时器将是重要15分钟用相同的代码。", + "Fatal": "致命的", + "Fatal Maximum Reached": "致命达到最大,停止摄像机。", + "FatalMaximumReachedText": "JPEG误差是致命的。", + "Feed-in Image Height": "在图像的高度", + "Feed-in Image Width": "在图像的宽度", + "Fields cannot be empty": "田不可能是空的", + "File Not Exist": "文件不存在", + "File Not Found": "找不到的文件", + "File Type": "文件的类型", + "FileNotExistText": "无法保存不存在的文件。 事了。", + "Filename": "文件名", + "Filesize": "Filesize", + "Filter ID": "过滤器ID", + "Filter Matches": "过滤器匹配", + "Filter Name": "过滤器名称", + "FilterMatchesText1": "这个过滤器已经满足的条件。", + "FilterMatchesText2": "视频发现。", + "Filters": "过滤器", + "Filters Updated": "过滤器更新", + "FiltersUpdatedText": "你有了变化保存和应用。", + "Find Where": "找到那里", + "Fix": "修复", + "Fix Video": "解决视频", + "FixVideoMsg": "你要修补这个视频? 你不能撤消这种行动。", + "Font Path": "字体路径", + "Font Size": "字体大小", + "Force Port": "部队口", + "Found Devices": "设备找到了", + "Frame Rate": "框率 (》)", + "Full Frame Detection": "完全检测框架", + "Fullscreen": "全屏", + "Greater Than": "大于", + "Greater Than or Equal to": "大于或等于", + "Group Key": "小组密", + "Group Name": "小组的名字", + "Grouping": "分组 ", + "H.264 / H.265 / H.265+": "H.264/H.265/H.265 ", + "HLS (.m3u8)": "高级别(中。m3u8)", + "HLS (includes Audio)": "高级别(包括音频)", + "HLS Audio Encoder": "高级别声音编码器", + "HLS List Size": "高级别列出的大小", + "HLS Preset": "高级别预先设定", + "HLS Segment Length": "高级别段的长度 在几秒钟内", + "HLS Video Encoder": "高级别编码视频", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "Height": "高度", + "Help": "帮助", + "Hide List": "隐藏列表中的", + "Hide Notes": "隐藏的笔记", + "Host": "主机", + "Hotswap Modes (Watch-Only)": "热交换模式(看-Only)", + "How to Record": "如何记录", + "IP Address": "IP地址", + "Identity": "身份", + "IdentityText1": "这是系统将如何识别数据为这个流。 你不能改变的 监测ID 一旦你必须按下保存。 如果你想你可以使 监测ID 更多的人阅读,然后再继续。", + "IdentityText2": "你可以重复一个监测通过修改 监测ID 然后按下保存。 你 不能 使用的标识一个监视已经存在或者它将存在于监测的数据库信息。", + "Idle": "空闲", + "Image Height": "像高", + "Image Location": "图像的位置 绝对路径或留下的空白使用全球", + "Image Position": "图像的位置", + "Image Width": "图像的宽度", + "Import": "进口", + "Import Monitor Configuration": "进口监测器的配置", + "ImportMonitorConfigurationText": "这样做将overrwrite任何改变目前没有保存。 进口的变化将只适用于当按 保存人。", + "In": "在", + "Incorrect Settings Chosen": "设置不正确的选择", + "Indifference": "冷漠", + "Input": "输入", + "Input Flags": "输入的标志", + "Input Type": "输入型", + "InputText1": "这部分告诉忍如何消耗流。 最佳性能试图调整你的摄像机的内置。 找到以下选项,并设定他们如图所示。 找到你的摄像机可以使用 建立在升扫描仪 的忍者. 一些升摄像机要求采用一个管理工具,以修改其内部设置。 如果你找不到你的摄像机你可以尝试 提升设备Manager for Windows.", + "InputText2": "
  • Framerate(》): 高:10-15》,低:2-5》
  • 我框架的时间间隔: 80
  • 比特率类型: 社区康复(恒定的比率)
  • 比特率: 间256kbps-500kbps
", + "InputText3": "如果你需要帮忙找出来是什么样的输入型你的摄像机是你可以看看 摄像机的Url清单 上的忍者的网站。", + "Invalid JSON": "无效JSON", + "InvalidJSONText": "请确保这是一个有效的JSON串忍监测配置。", + "JPEG": "JPEG", + "JPEG (Auto Enables JPEG API)": "JPEG(自动使JPEG API)", + "JPEG API": "JPEG API 快照(cgi-bin)", + "JPEG Error": "JPEG错误", + "JPEG Mode": "JPEG模式", + "JPEGErrorText": "有一个问题获得数据从你的相机。", + "Leave blank for random.": "留下的空白。", + "Left": "左 URL地址", + "Left Stop": "左站 的URL地址", + "Less Than": "不到", + "Less Than or Equal to": "小于或等于", + "Like": "喜欢", + "Lisence Plate Detector": "图编辑功能板检测器", + "List Toggle": "列表中切换", + "Live Stream Toggle": "现场流肘", + "Live View": "现场查看", + "Local": "本地", + "Log Level": "日志的水平", + "Log Signal Event": "登录信号的事件, 客户只有一侧", + "Logging": "日志记录", + "Login": "登录", + "Logout": "注销", + "Logs": "日志", + "MB": "MB", + "MJPEG": "安全监控", + "MP4 (copy, libx264, libx265)": "MP4(副本,libx264,libx265)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4(中。mp4/.ts)", + "MailError": "邮件错误:不能发送电子邮件、检查conf.手机中。 跳过的任何功能的依赖邮寄。", + "Matches": "比赛", + "Max Storage Amount": "最大储存量 在兆", + "Mode": "模式", + "Monitor": "监视器", + "Monitor Added by user": "监控中加入的用户。", + "Monitor Capture Rate": "监测捕获率 (》)", + "Monitor Groups": "监测组", + "Monitor ID": "监测ID", + "Monitor Idling": "监测空转", + "Monitor Name": "监视器名称", + "Monitor Settings": "监测设置", + "Monitor Stopped": "监测停止", + "Monitor Updated by user": "监测更新用户。", + "Monitor mode changed": "监视器模式的改变", + "Monitor mode is already": "监视器模式已经", + "Monitor or Key does not exist.": "监视器或关键并不存在。", + "MonitorIdlingText": "监测会议已订于空闲。", + "MonitorStoppedText": "监测会议已被下令停止。", + "Monitors": "监视器", + "Monitors per row": "监视器,每行 为的蒙太奇", + "Montage": "蒙太奇", + "Motion GUI": "运动GUI", + "Motion Meter": "运动米", + "Name": "名称", + "No": "没有", + "No Audio": "没有音频", + "No Data": "没有数据", + "No Events found for this video": "没事的找到这个视频", + "No Group with this key exists": "没有任何组织这个关键的存在", + "No Monitor Found, Ignoring Request": "没有监视器发现,忽略了请求", + "No Rotation": "没有旋转", + "No such file": "没有这样的文件", + "NoMotionEmailText1": "没有运动", + "NoMotionEmailText2": "没有任何运动检测摄像机", + "NoVideosFoundForDateRange": "没有视频发现在这的日期范围。 试图设置,开始日期进一步回。", + "Not Authorized": "没有授权", + "Not Connected": "不连接", + "Not Equal to": "不等于", + "Not In": "不在", + "Not Matches": "不匹配", + "Not Permitted": "不允许", + "Not an Administrator Account": "不是管理员的帐户", + "NotAuthorizedText1": "没有授权,提交init命令与\"授权\",\"科\",并\"uid\"", + "Notes": "注意到", + "NotesPlacholder": "评论你想离开这个相机设置。", + "Number of Days to keep": "保留的天数", + "ONVIF": "升", + "ONVIF Scanner": "升扫描仪", + "ONVIFnote": "发现提升设备网络之外自己或留下的空白以扫描你的前的网络。
用户名和密码可以留空。", + "OpenCV Cascades": "该版本的瀑布", + "Order Streams": "顺流", + "Output Method": "输出方法", + "Password": "密码", + "Password Again": "再次密码", + "Passwords don't match": "密码不匹配", + "Paste JSON here.": "贴JSON在这里。", + "Path": "路径", + "Permissions": "权限", + "Points": "点 在添加点击边缘上的多边形。", + "Port": "口", + "Position X": "X位置", + "Position Y": "Y位置", + "Power Video Viewer": "的电视观众", + "Power Viewer": "电观众", + "Preferences": "喜好", + "Preset": "预先设定", + "Probe Size": "探头大小", + "Process Crashed for Monitor": "进程崩溃的监视器", + "Process Unexpected Exit": "处理意想不到的退出", + "Profile": "配置文件", + "Quality": "质量 1高,23低", + "Query": "查询", + "RAM": "RAM", + "RTSP": "RTSP", + "RTSP Transport": "RTSP运输", + "Range or Single": "范围内或单", + "Rate": "率 (》)", + "Record": "记录", + "Record File Type": "记录文件的类型", + "Record Height": "记录的高度", + "Record Video Filter": "视频录制的过滤器", + "Record Width": "记录宽度", + "Recording": "记录", + "Recording Flags": "记录的标志", + "Recording Segment Interval": "记录段时间间隔 在分钟", + "Recording Timeout": "记录超时 在分钟", + "Recording Timestamp": "记录时间戳", + "Recording Watermark": "记录水印", + "RecordingText": "它建议设置 的记录文件的类型DivxMP4视频编libvpx复制或 libx264 因为你的 输入型 设置 的。", + "Refresh List of Cascades": "刷新名单的瀑布", + "Region Editor": "地区编辑器", + "Region Name": "地区名称", + "RegionNote": "点只保存,当你按下 保存监测器设置 窗口。", + "Regions": "区域", + "Remember Me": "还记得我", + "Reset Timer": "重置计时器", + "Restarting Process": "重新启动进程", + "Retry Connection": "试连接 的次数,允许失败", + "Retrying...": "重新尝试...", + "Right": "正确的 URL地址", + "Right Stop": "右站 的URL地址", + "Rotate": "旋转", + "Save": "保存", + "Save Directory": "保存目录", + "Save Events to SQL": "保存活动SQL", + "Save Log in SQL": "保存记录在SQL 这可以迅速填补的。", + "Save as": "保存", + "Saved Filters": "保存的过滤器", + "Scan Settings": "扫描设置", + "Search": "搜索", + "Send Frames": "送框架 推框架进行分析", + "Separate with commas, no spaces": "独立使用逗号,不空间", + "Set to Watch Only": "设置只观看", + "Settings": "设置", + "Settings Changed": "设置改变", + "SettingsChangedText": "你的设置已保存和应用。", + "Shinobi": "忍者", + "Shinobi Streamer": "忍流光", + "Show Logs": "日志显示", + "Silent": "沉默", + "Simple": "简单的", + "Size (mb)": "小(mb)", + "Snapshot": "快照", + "Snapshot Flags": "快照标志", + "Snapshots": "快照", + "Sort By": "排序", + "Start": "开始", + "Start Recording": "开始记录", + "Start Time": "开始的时间", + "Started": "开始", + "Status Indicator": "状态指示器", + "Stop URL": "停止URL", + "Stream": "流", + "Stream Flags": "流的标志", + "Stream Timestamp": "流的时间戳", + "Stream Type": "流的类型", + "Stream Watermark": "流水印", + "Stream to YouTube": "流到YouTube", + "Stream to YouTube Flags": "流到YouTube的标志", + "StreamText": "

这部分会指定主流的方法和它的设置。 这种流将显示在仪表板。 如果你选择使用高级别、JPEG或数然后你就可以占用的流通过其他程序。

使用JPEG流基本上关闭主流和使用的快照站获得的框架。

", + "Streamer": "经幡", + "Streams": "流", + "Superuser": "超级用户", + "Switch on for Still Image": "开关于仍然图像", + "TCP": "TCP", + "Text Box Color": "文本框颜色", + "Text Color": "文字颜色", + "Time-lapse": "时间流逝", + "Time-lapse Tool": "延时的工具", + "Timeout": "超时", + "Timeout Reset on Next Motion": "超时的重置上下运动", + "Toggle Sidebar": "切换边栏", + "Top Left": "左上", + "Top Right": "右上方", + "Trigger Record": "触发记录", + "Trigger Successful": "触发成功的", + "UDP": "UDP", + "URL": "URL", + "URL Stop Timeout": "URL停止超时 停止运行URL后X毫秒", + "US": "我们", + "Unable to Launch": "无法启动", + "UnabletoLaunchText": "请保存的新的监测第一次。 然后试图启动该地区编辑器。", + "Up": "立 URL地址", + "Up Stop": "起来站 的URL地址", + "Username": "用户名", + "Value": "值", + "Video": "视频", + "Video Codec": "视频编", + "Video Filter": "视频的过滤器", + "Video Finished": "视频完成", + "Video Length (minutes) and Motion Count per video": "视频度(分钟)和运动的计每视频", + "Video Record Rate": "视频记录速率 (》)", + "Video Status": "视频状态", + "Video and Time Span (Minutes)": "视频和时间跨度(分钟)", + "Videos": "视频", + "Videos List": "视频清单", + "Watch": "看", + "Watch Only": "只观看", + "WebDAV": "WebDAV", + "WebM (libvpx)": "Divx(libvpx)", + "Webdav Error": "Webdav错误", + "WebdavErrorText": "不能保存。 你使摄像文件夹在你选择的保存目录?", + "Webhook": "两者", + "Webhook URL": "两者URL", + "Width": "宽", + "Yes": "是的", + "Zoom In": "放大 的URL地址", + "Zoom In Stop": "放大停止 URL地址", + "Zoom Out": "缩小 的URL地址", + "Zoom Out Stop": "缩小站 的URL地址", + "a day": "一天", + "a few seconds": "几秒钟", + "a minute": "一分钟", + "a month": "一个月", + "a year": "一年", + "aac": "aac", + "aac (Default)": "aac(默认)", + "ac3": "ac3", + "ago": "前", + "an hour": "一个小时", + "blankPassword": "留下的空白,以保持同一个密码", + "calendar": "日历", + "clientStreamFailedattemptingReconnect": "客户的侧ctream检查失败,试图重新连接。", + "confirmDeleteFilter": "你想要删除这个过滤器? 你不能恢复。", + "copy": "复制", + "days": "天", + "dropBoxSuccess": "成功! 文件保存到您的序。", + "for Global Access": "全球访问", + "hours": "小时", + "in": "在", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis(默认)", + "libvpx (Default)": "libvpx(默认)", + "libvpx-vp9": "libvpx-vp9", + "libx264": "libx264", + "libx264 (Default)": "libx264(默认)", + "libx265": "libx265", + "minutes": "分钟", + "modifyVideoText1": "方法并不存在。 检查,以确保最后的价值的网址是没有空白。", + "monitorEditFailedMaxReached": "你的账户已经达到最大数量的摄像机,可以创建。 说话给管理员如果你想这改变。", + "monitorEditText1": "无效数据后,检查看看,这是一个有效的进口串。", + "monitorEditText2": "无效的细节串。 检查看看它是一个JSON串并不是一个普通的物体被通过。", + "monitorGetText1": "不完整的请求,删除最后一条斜线网址,或把接受的价值。", + "months": "几个月", + "noSpecialCharacters": "没有空间或特殊字符。", + "on": "上", + "on Error": "在错误", + "startUpText0": "尺寸检查的视频", + "startUpText1": "终端的尺寸检查的视频", + "startUpText2": "所有用户的检查,等待关闭打开文件,并删除文件的用户限制", + "startUpText3": "等着给未完成的视频检查一些时间。 3秒钟。", + "startUpText4": "开始的所有监视器组,以观察和记录", + "startUpText5": "忍者已准备就绪。", + "superAdminText": "\"超级。json\"不存在。 请重新命名\"超级。样品。json\"到\"超级。json\"。", + "superAdminTitle": "忍:超级管理员", + "total": "总", + "updateKeyText1": "\"updateKey\"缺失\"conf.json\",无法做更新这样直到你加入它。", + "updateKeyText2": "\"updateKey\"是不正确的。", + "years": "年" +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..badfe02 --- /dev/null +++ b/package.json @@ -0,0 +1,44 @@ +{ + "name": "shinobi", + "version": "1.0.37", + "description": "CCTV and NVR in Node.js, Version : daf882caf6053a7c2c8f4e69427620356f8a440c", + "main": "camera.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "chmod +x INSTALL/start.sh && INSTALL/start.sh" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/moeiscool/Shinobi.git" + }, + "author": "Moe Alam", + "bugs": { + "url": "https://github.com/ShinobiCCTV/Shinobi/issues" + }, + "homepage": "https://github.com/moeiscool/Shinobi#readme", + "dependencies": { + "body-parser": "^1.15.2", + "circular-json": "0.3.1", + "connection-tester": "^0.1.1", + "chokidar": "^2.0.3", + "mp4frag": "^0.0.15", + "ejs": "^2.5.5", + "express": "^4.14.0", + "jsonfile": "^3.0.1", + "moment": "^2.17.0", + "mysql": "^2.12.0", + "knex": "^0.14.2", + "pam-diff": "^0.10.2", + "pipe2pam": "^0.6.2", + "nodemailer": "^4.0.1", + "node-onvif": "^0.1.4", + "path": "^0.12.7", + "request": "^2.79.0", + "socket.io": "^1.7.1", + "socket.io-client": "^1.7.2", + "http-proxy": "^1.17.0", + "webdav": "^0.3.1", + "ldapauth-fork": "^4.0.2" + }, + "devDependencies": {} +} diff --git a/plugins/.gitignore b/plugins/.gitignore new file mode 100644 index 0000000..34613db --- /dev/null +++ b/plugins/.gitignore @@ -0,0 +1,4 @@ +opencv-python +ccv +stemkoski +variantai \ No newline at end of file diff --git a/plugins/child/.gitignore b/plugins/child/.gitignore new file mode 100644 index 0000000..bd55664 --- /dev/null +++ b/plugins/child/.gitignore @@ -0,0 +1,3 @@ +conf.json +events +frames \ No newline at end of file diff --git a/plugins/child/child.js b/plugins/child/child.js new file mode 100644 index 0000000..6b1a17c --- /dev/null +++ b/plugins/child/child.js @@ -0,0 +1,392 @@ +var os = require('os'); +var fs = require('fs'); +var path = require('path'); +var mysql = require('mysql'); +var moment = require('moment'); +var request = require("request"); +var spawn = require('child_process').spawn; +var exec = require('child_process').exec; +var execSync = require('child_process').execSync; +var connectionTester = require('connection-tester'); +var config = require('./conf.json'); + +exec("ps aux | grep -ie ffmpeg | awk '{print $2}' | xargs kill -9");//kill any ffmpeg running +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +s={connected:false,child_node:true,platform:os.platform(),group:{}}; + +//connect to master +io = require('socket.io-client')('ws://'+config.ws); +//spawn conatiner +s.spawns={}; +//emulate master sql query +sql={ + query:function(x,y,z){ + io.emit('c',{f:'sql',query:x,values:y});if(typeof z==='function'){z();} + } +} +//get this nodes cpu usage +s.cpuUsage=function(e){ + k={} + switch(s.platform){ + case'win32': + k.cmd="@for /f \"skip=1\" %p in ('wmic cpu get loadpercentage') do @echo %p%" + break; + case'darwin': + k.cmd="ps -A -o %cpu | awk '{s+=$1} END {print s}'"; + break; + case'linux': + k.cmd='LANG=C top -b -n 2 | grep "^'+config.cpuUsageMarker+'" | awk \'{print $2}\' | tail -n1'; + break; + } + if(config.customCpuCommand){ + exec(config.customCpuCommand,{encoding:'utf8',detached: true},function(err,d){ + if(s.isWin===true) { + d = d.replace(/(\r\n|\n|\r)/gm, "").replace(/%/g, "") + } + e(d) + }); + } else if(k.cmd){ + exec(k.cmd,{encoding:'utf8',detached: true},function(err,d){ + if(s.isWin===true){ + d=d.replace(/(\r\n|\n|\r)/gm,"").replace(/%/g,"") + } + e(d) + }); + } else{ + e(0) + } +} +setInterval(function(){ + s.cpuUsage(function(cpu){ + io.emit('c',{f:'cpu',cpu:parseFloat(cpu)}) + }) +},2000); +//interact with server functions +s.cx=function(x){io.emit('c',x)} +//emulate master socket emitter +s.tx=function(x,y){s.cx({f:'s.tx',data:x,to:y})} +//emulate master logger +s.log=function(x,y){console.log(y);s.cx({f:'s.log',data:s.init('clean',x),to:y})} +//emulate master camera function +s.camera=function(x,y){s.cx({f:'camera',mode:x,data:y})} + +//load camera controller vars +s.nameToTime=function(x){x=x.split('.')[0].split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;} +s.ratio=function(width,height,ratio){ratio = width / height;return ( Math.abs( ratio - 4 / 3 ) < Math.abs( ratio - 16 / 9 ) ) ? '4:3' : '16:9';} +s.gid=function(x){ + if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.moment=function(e,x){if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'};return moment(e).utcOffset('-0800').format(x)} +s.kill=function(x,e,p){ + if(e&&s.group[e.ke].mon[e.id].record){ + clearTimeout(s.group[e.ke].mon[e.id].record.capturing); + if(s.group[e.ke].mon[e.id].record.request&&s.group[e.ke].mon[e.id].record.request.abort){s.group[e.ke].mon[e.id].record.request.abort();delete(s.group[e.ke].mon[e.id].record.request);} + }; + if(!x||x===1){return};if(!x.stdin){return};p=x.pid;x.stdin.pause();setTimeout(function(){x.kill('SIGTERM');delete(x);setTimeout(function(){exec('kill -9 '+p)},1000)},1000) +} +s.cameraVals=function(e){ + e.t=Object.keys(s.group[e.ke].mon[e.id]);e.a={}; + e.t.forEach(function(n){ + if(s.group[e.ke].mon[e.id][n] instanceof Object){e.a[n]=s.group[e.ke].mon[e.id][n]}; + }); + return e.a; +} +//directories +s.group={}; +s.dir={videos:__dirname+'/videos/',frames:__dirname+'/frames/'}; +if (!fs.existsSync(s.dir.frames)){ + fs.mkdirSync(s.dir.frames); +} +if (!fs.existsSync(s.dir.videos)){ + fs.mkdirSync(s.dir.videos); +} +////Camera Controller +s.init=function(x,e){ + switch(x){ + case 0://camera + if(!s.group[e.ke]){s.group[e.ke]={}}; + if(!s.group[e.ke].mon){s.group[e.ke].mon={}} + if(!s.group[e.ke].mon[e.mid]){s.group[e.ke].mon[e.mid]={}} + if(!s.group[e.ke].mon[e.mid].watch){s.group[e.ke].mon[e.mid].watch={}}; + if(e.type==='record'){e.record=1}else{e.record=0} + if(!s.group[e.ke].mon[e.mid].record){s.group[e.ke].mon[e.mid].record={yes:e.record}}; + if(!s.group[e.ke].mon[e.mid].started){s.group[e.ke].mon[e.mid].started={}}; + if(!s.group[e.ke].mon[e.mid].running){s.group[e.ke].mon[e.mid].running={}}; + break; + case'clean': + if(e instanceof Object){ + x={keys:Object.keys(e),ar:{}}; + x.keys.forEach(function(v){ + if(v!=='record'&&v!=='spawn'&&v!=='running'&&(typeof e[v]!=='function')){x.ar[v]=e[v];} + }); + return x.ar; + } + break; + case'url': + //build a complete url from pieces + e.authd=''; + if(e.details.muser&&e.details.muser!==''&&e.host.indexOf('@')===-1) { + e.authd=e.details.muser+':'+e.details.mpass+'@'; + } + if(e.port==80&&e.details.port_force!=='1'){e.porty=''}else{e.porty=':'+e.port} + e.url=e.protocol+'://'+e.authd+e.host+e.porty+e.path;return e.url; + break; + case'url_no_path': + e.authd=''; + if(!e.details.muser){e.details.muser=''} + if(!e.details.mpass){e.details.mpass=''} + if(e.details.muser!==''&&e.host.indexOf('@')===-1) { + e.authd=e.details.muser+':'+e.details.mpass+'@'; + } + if(e.port==80&&e.details.port_force!=='1'){e.porty=''}else{e.porty=':'+e.port} + e.url=e.protocol+'://'+e.authd+e.host+e.porty;return e.url; + break; + } + if(typeof e.callback==='function'){setTimeout(function(){e.callback();delete(e.callback);},2000);} +} +s.video=function(x,e){ + if(!e){e={}}; + if(e.mid){e.id=e.mid}; + switch(x){ + case'delete': + e.dir=s.dir.videos+e.ke+'/'+e.id+'/'; + e.save=[e.id,e.ke,s.nameToTime(e.filename),0]; + sql.query('DELETE FROM Videos WHERE `mid`=? AND `ke`=? AND `time`=? AND `status`=?',e.save) + s.tx({f:'video_delete',reason:'Camera Error',filename:e.filename+'.'+e.ext,mid:e.id,ke:e.ke,time:s.nameToTime(e.filename),end:moment().format('YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke); + if(fs.existsSync(e.dir+e.filename+'.'+e.ext)){ + return fs.unlink(e.dir+e.filename+'.'+e.ext); + } + break; + case'close': + e.dir=s.dir.videos+e.ke+'/'+e.id+'/'; + console.log(e.dir+e.filename+'.'+e.ext) + if(fs.existsSync(e.dir+e.filename+'.'+e.ext)){ + e.filesize=fs.statSync(e.dir+e.filename+'.'+e.ext)["size"]; + if((e.filesize/100000).toFixed(2)>0.25){ + e.save=[e.filesize,e.frames,1,e.id,e.ke,s.nameToTime(e.filename)]; + sql.query('UPDATE Videos SET `size`=?,`frames`=?,`status`=? WHERE `mid`=? AND `ke`=? AND `time`=?',e.save) + fs.readFile(e.dir+e.filename+'.'+e.ext,function (err,data) { + s.cx({f:'created_file',mid:e.id,ke:e.ke,created_file:data,filename:e.filename+'.'+e.ext,d:s.init('clean',e)}); + s.tx({f:'video_build_success',filename:e.filename+'.'+e.ext,mid:e.id,ke:e.ke,time:s.nameToTime(e.filename),size:e.filesize,end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke); + }); + }else{ + s.video('delete',e); + s.log(e,{type:'File Corrupt',msg:{ffmpeg:s.group[e.ke].mon[e.mid].ffmpeg,filesize:(e.filesize/100000).toFixed(2)}}) + } + }else{ + s.video('delete',e); + s.log(e,{type:'File Not Exist',msg:'Cannot save non existant file. Something went wrong.',ffmpeg:s.group[e.ke].mon[e.id].ffmpeg}) + } + break; + } +} +s.ffmpeg=function(e,x){ + if(!x){x={tmp:''}} +// if(!e.details.cutoff||e.details.cutoff===''){x.cutoff=15}else{x.cutoff=parseFloat(e.details.cutoff)};if(isNaN(x.cutoff)===true){x.cutoff=15} +// x.segment=' -f segment -strftime 1 -segment_time '+(60*x.cutoff)+' -segment_format '+e.ext + if(!e.details.timestamp||e.details.timestamp==1){x.time=' -vf drawtext=fontfile=/usr/share/fonts/truetype/freefont/FreeSans.ttf:text=\'%{localtime}\':x=(w-tw)/2:y=0:fontcolor=white:box=1:boxcolor=0x00000000@1:fontsize=10';}else{x.time=''} + switch(e.ext){ + case'mp4': + x.vcodec='libx265';x.acodec='libfaac'; + if(e.details.vcodec&&e.details.vcodec!==''){x.vcodec=e.details.vcodec} + break; + case'webm': + x.acodec='libvorbis',x.vcodec='libvpx'; + break; + } + if(e.details.acodec&&e.details.acodec!==''){x.acodec=e.details.acodec} + if(x.acodec==='none'){x.acodec=''}else{x.acodec=' -acodec '+x.acodec} + if(x.vcodec!=='none'){x.vcodec=' -vcodec '+x.vcodec} + if(e.fps&&e.fps!==''){x.framerate=' -r '+e.fps}else{x.framerate=''} + if(e.details.vf&&e.details.vf!==''){ + if(x.time===''){x.vf=' -vf '}else{x.vf=','} + x.vf+=e.details.vf; + x.time+=x.vf; + } + if(e.details.svf&&e.details.svf!==''){x.svf=' -vf '+e.details.svf;}else{x.svf='';} +// if(e.details.svf){'-vf "rotate=45*(PI/180)'} + switch(e.type){ + case'socket':case'jpeg':case'pipe': + if(!x.vf||x.vf===','){x.vf=''} + x.tmp='-loglevel warning -pattern_type glob -f image2pipe'+x.framerate+' -vcodec mjpeg -i -'+x.vcodec+x.time+x.framerate+' -use_wallclock_as_timestamps 1 -q:v 1'+x.vf+' '+e.dir+e.filename+'.'+e.ext; + break; + case'mjpeg': + if(e.mode=='record'){ + x.watch=x.vcodec+x.time+' -r 10 -s '+e.width+'x'+e.height+' -use_wallclock_as_timestamps 1 -q:v 1 '+e.dir+e.filename+'.'+e.ext+'' + }else{ + x.watch=''; + }; + x.tmp='-loglevel warning -reconnect 1 -f mjpeg -i '+e.url+''+x.watch+' -f image2pipe'+x.svf+' -s '+e.ratio+' pipe:1'; + break; + case'h264': + if(!x.vf||x.vf===','){x.vf=''} + if(e.mode=='record'){ + x.watch=x.vcodec+x.framerate+x.acodec+' -movflags frag_keyframe+empty_moov -s '+e.width+'x'+e.height+' -use_wallclock_as_timestamps 1 -q:v 1'+x.vf+' '+e.dir+e.filename+'.'+e.ext + }else{ + x.watch=''; + }; + x.tmp='-loglevel warning -i '+e.url+' -stimeout 2000'+x.watch+' -f image2pipe'+x.svf+' -s '+e.ratio+' pipe:1'; + break; + case'local': + if(e.mode=='record'){ + x.watch=x.vcodec+x.time+x.framerate+x.acodec+' -movflags frag_keyframe+empty_moov -s '+e.width+'x'+e.height+' -use_wallclock_as_timestamps 1 '+e.dir+e.filename+'.'+e.ext + }else{ + x.watch=''; + }; + x.tmp='-loglevel warning -i '+e.path+''+x.watch+' -f image2pipe'+x.svf+' -s '+e.ratio+' pipe:1'; + break; + } + s.group[e.ke].mon[e.mid].ffmpeg=x.tmp; + return spawn('ffmpeg',x.tmp.split(' ')); +} + +//child functions +var cn={}; +io.on('connect', function(d){ + console.log('connected'); + io.emit('c',{f:'init',socketKey:config.key,u:{name:config.name}}) +}); +io.on('c',function(d){ + console.log(d.f); + switch(d.f){ + case'init_success': + s.connected=true; + s.other_helpers=d.child_helpers; + break; + case'kill': + s.init(0,d.d); + s.kill(s.group[d.d.ke].mon[d.d.id].spawn,d.d) + break; + case'sync': + s.init(0,d.sync); + Object.keys(d.sync).forEach(function(v){ + s.group[d.sync.ke].mon[d.sync.mid][v]=d.sync[v]; + }); + break; + case'delete_file'://delete video + d.dir=s.dir.videos+d.ke+'/'+d.mid+'/'+d.file; + if(fs.existsSync(d.dir)){ + fs.unlink(d.dir); + } + break; + case'close'://close video + s.video('close',d.d); + break; + case'spawn'://start video + s.init(0,d.d); + s.group[d.d.ke].mon[d.d.id]=d.mon; + if(!s.group[d.d.ke].mon_conf){s.group[d.d.ke].mon_conf={}} + if(!s.group[d.d.ke].mon_conf[d.d.id]){s.group[d.d.ke].mon_conf[d.d.id]=s.init('clean',d.d);} + if(s.group[d.d.ke].mon[d.d.id].spawn&&s.group[d.d.ke].mon[d.d.id].spawn.stdin){return} + if(d.d.mode==='record'){ + console.log(s.group[d.d.ke].mon[d.d.id]) + s.group[d.d.ke].mon[d.d.id].record.yes=1; + d.d.dir=s.dir.videos+d.d.ke+'/'; + if (!fs.existsSync(d.d.dir)){ + fs.mkdirSync(d.d.dir); + } + d.d.dir=s.dir.videos+d.d.ke+'/'+d.d.id+'/'; + if (!fs.existsSync(d.d.dir)){ + fs.mkdirSync(d.d.dir); + } + }else{ + s.group[d.d.ke].mon[d.d.mid].record.yes=0; + } + if(d.d.mode==='record'||d.d.type==='mjpeg'||d.d.type==='h264'||d.d.type==='local'){ + s.group[d.d.ke].mon[d.d.id].spawn = s.ffmpeg(d.d); + s.log(d.d,{type:'FFMPEG Process Starting',msg:{cmd:s.group[d.d.ke].mon[d.d.id].ffmpeg}}); + } + d.d.frames=0; + switch(d.d.type){ + case'jpeg': + if(!d.d.details.sfps||d.d.details.sfps===''){ + d.d.details.sfps=parseFloat(d.d.details.sfps); + if(isNaN(d.d.details.sfps)){d.d.details.sfps=1} + } + d.d.captureOne=function(f){ + s.group[d.d.ke].mon[d.d.id].record.request=request({url:d.d.url,method:'GET',encoding: null,timeout:3000},function(er,data){ + ++d.d.frames; if(s.group[d.d.ke].mon[d.d.id].spawn&&s.group[d.d.ke].mon[d.d.id].spawn.stdin){ + if(er){ + ++d.d.error_count; + s.log(d.d,{type:'Snapshot Error',msg:er}); + return; + } + if(d.d.mode==='record'&&s.group[d.d.ke].mon[d.d.id].spawn&&s.group[d.d.ke].mon[d.d.id].spawn.stdin){ + s.group[d.d.ke].mon[d.d.id].spawn.stdin.write(data.body); + } + if(s.group[d.d.ke].mon[d.d.id].watch&&Object.keys(s.group[d.d.ke].mon[d.d.id].watch).length>0){ + s.tx({f:'monitor_frame',ke:d.d.ke,id:d.d.id,time:s.moment(),frame:data.body.toString('base64'),frame_format:'b64'},'MON_'+d.d.id); + } + s.group[d.d.ke].mon[d.d.id].record.capturing=setTimeout(function(){d.d.captureOne()},1000/d.d.details.sfps); + clearTimeout(d.d.timeOut),d.d.timeOut=setTimeout(function(){d.d.error_count=0;},3000) + } + }).on('error', function(err){ +// if(s.group[d.d.ke]&&s.group[d.d.ke].mon[d.d.id]&&s.group[d.d.ke].mon[d.d.id].record&&s.group[d.d.ke].mon[d.d.id].record.request){s.group[d.d.ke].mon[d.d.id].record.request.abort();} + clearTimeout(s.group[d.d.ke].mon[d.d.id].record.capturing); + if(d.d.error_count>4){d.d.fn();return} + d.d.captureOne(); + }); + } + d.d.captureOne() + break; + case'mjpeg':case'h264'://case'socket':case'local': + if(!s.group[d.d.ke]||!s.group[d.d.ke].mon[d.d.id]){s.init(0,d.d)} + if(s.group[d.d.ke].mon[d.d.id].spawn){ + s.group[d.d.ke].mon[d.d.id].spawn.on('error',function(er){d.d.error({type:'Spawn Error',msg:er})}) + s.group[d.d.ke].mon[d.d.id].spawn.stdout.on('data',function(de){ + s.tx({f:'monitor_frame',ke:d.d.ke,id:d.d.id,time:s.moment(),frame:de.toString('base64'),frame_format:'b64'},'MON_'+d.d.id); + }); + s.group[d.d.ke].mon[d.d.id].spawn.stderr.on('data',function(de){ + de=de.toString(); + d.d.chk=function(x){return de.indexOf(x)>-1;} + switch(true){ +// case d.d.chk('av_interleaved_write_frame'): + case d.d.chk('Connection timed out'): + setTimeout(function(){s.log(d.d,{type:"Can't Connect",msg:'Retrying...'});d.d.error_fatal();},1000)//restart + break; + case d.d.chk('No pixel format specified'): + s.log(d.d,{type:"FFMPEG STDERR",msg:{ffmpeg:s.group[d.d.ke].mon[d.d.id].ffmpeg,msg:de}}) + break; + case d.d.chk('RTP: missed'): + case d.d.chk('deprecated pixel format used, make sure you did set range correctly'): + return + break; + case d.d.chk('No such file or directory'): + case d.d.chk('Unable to open RTSP for listening'): + case d.d.chk('timed out'): + case d.d.chk('Invalid data found when processing input'): + case d.d.chk('Immediate exit requested'): + case d.d.chk('reset by peer'): + if(d.d.frames===0&&x==='record'){s.video('delete',d.d)}; + break; + } + s.log(d.d,{type:"FFMPEG STDERR",msg:de}) + }); + } + break; + } + break; + case'video': + s.video(d.d[0],d.d[1]); + break; + } +}); +io.on('disconnect',function(d){ + s.connected=false; +}); + +//web server +if(config.port===undefined)config.port = 8080; +if(config.ip===undefined||config.ip===''||config.ip.indexOf('0.0.0.0')>-1){config.ip='localhost'}else{config.bindip=config.ip}; +var childNodeHTTP = express(); +var childNodeServer = http.createServer(app); +var childNodeWebsocket = new (require('socket.io'))() +childNodeServer.listen(config.port,config.bindip,function(){ + console.log('SHINOBI CHILD NODE RUNNING ON PORT : '+config.port); +}); +childNodeWebsocket.attach(childNodeServer); \ No newline at end of file diff --git a/plugins/child/conf.sample.json b/plugins/child/conf.sample.json new file mode 100644 index 0000000..d1b2008 --- /dev/null +++ b/plugins/child/conf.sample.json @@ -0,0 +1,6 @@ +{ + "name":"childMachine1", + "ws":"192.168.1.48", + "port":8080, + "key":"3123asdasdf1dtj1hjk23sdfaasd12asdasddfdbtnkkfgvesra3asdsd3123afdsfqw345", +} \ No newline at end of file diff --git a/plugins/darknet/INSTALL.sh b/plugins/darknet/INSTALL.sh new file mode 100644 index 0000000..f2cdc4d --- /dev/null +++ b/plugins/darknet/INSTALL.sh @@ -0,0 +1,13 @@ +#!/bin/bash +ln -s /usr/local/cuda/targets/x86_64-linux/lib/libcurand.so /usr/local/lib/libcurand.so +ln -s /usr/local/cuda/targets/x86_64-linux/lib/libcublas.so /usr/local/lib/libcublas.so +ln -s /usr/local/cuda/targets/x86_64-linux/lib/libcudart.so /usr/local/lib/libcudart.so + +git clone https://github.com/OrKoN/darknet +rm darknet/Makefile +cp modifiedMakefile darknet/Makefile +cd darknet +make OPENCV=1 GPU=1 +make install + +npm install @moovel/yolo --unsafe-perm \ No newline at end of file diff --git a/plugins/darknet/conf.sample.json b/plugins/darknet/conf.sample.json new file mode 100644 index 0000000..1a4b8dc --- /dev/null +++ b/plugins/darknet/conf.sample.json @@ -0,0 +1,9 @@ +{ + "plug":"OpenCV", + "host":"localhost", + "port":8080, + "hostPort":8082, + "key":"change_this_to_something_very_random____make_sure_to_match__/plugins/opencv/conf.json", + "mode":"client", + "type":"detector" +} \ No newline at end of file diff --git a/plugins/darknet/modifiedMakefile b/plugins/darknet/modifiedMakefile new file mode 100644 index 0000000..d5f61aa --- /dev/null +++ b/plugins/darknet/modifiedMakefile @@ -0,0 +1,119 @@ +GPU=0 +CUDNN=0 +OPENCV=1 +OPENMP=0 +DEBUG=0 + +PREFIX = /usr/local + +ARCH= #-gencode arch=compute_20,code=[sm_20,sm_21] \ + -gencode arch=compute_30,code=sm_30 \ + -gencode arch=compute_35,code=sm_35 \ + -gencode arch=compute_50,code=[sm_50,compute_50] \ + -gencode arch=compute_52,code=[sm_52,compute_52] + +# This is what I use, uncomment if you know your arch and want to specify +# ARCH= -gencode arch=compute_52,code=compute_52 + +VPATH=./src/:./examples +SLIB=libdarknet.so +ALIB=libdarknet.a +EXEC=darknet +OBJDIR=./obj/ + +CC=gcc +NVCC=nvcc +AR=ar +ARFLAGS=rcs +OPTS=-Ofast +LDFLAGS= -lm -pthread +COMMON= -Iinclude/ -Isrc/ +CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC + +ifeq ($(OPENMP), 1) +CFLAGS+= -fopenmp +endif + +ifeq ($(DEBUG), 1) +OPTS=-O0 -g +endif + +CFLAGS+=$(OPTS) + +ifeq ($(OPENCV), 1) +COMMON+= -DOPENCV +CFLAGS+= -DOPENCV +LDFLAGS+= `pkg-config --libs opencv` +COMMON+= `pkg-config --cflags opencv` +endif + +ifeq ($(GPU), 1) +COMMON+= -DGPU -I/usr/local/cuda/include/ +CFLAGS+= -DGPU +LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand +endif + +ifeq ($(CUDNN), 1) +COMMON+= -DCUDNN +CFLAGS+= -DCUDNN +LDFLAGS+= -lcudnn +endif + +OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o detection_layer.o route_layer.o box.o normalization_layer.o avgpool_layer.o layer.o local_layer.o shortcut_layer.o activation_layer.o rnn_layer.o gru_layer.o crnn_layer.o demo.o batchnorm_layer.o region_layer.o reorg_layer.o tree.o lstm_layer.o +EXECOBJA=captcha.o lsd.o super.o voxel.o art.o tag.o cifar.o go.o rnn.o rnn_vid.o compare.o segmenter.o regressor.o classifier.o coco.o dice.o yolo.o detector.o writing.o nightmare.o swag.o darknet.o +ifeq ($(GPU), 1) +LDFLAGS+= -lstdc++ +OBJ+=convolutional_kernels.o deconvolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o network_kernels.o avgpool_layer_kernels.o +endif + +EXECOBJ = $(addprefix $(OBJDIR), $(EXECOBJA)) +OBJS = $(addprefix $(OBJDIR), $(OBJ)) +DEPS = $(wildcard src/*.h) Makefile include/darknet.h +HEADERS = $(wildcard src/*.h) + +#all: obj backup results $(SLIB) $(ALIB) $(EXEC) +all: obj results $(SLIB) $(ALIB) $(EXEC) + + +$(EXEC): $(EXECOBJ) $(ALIB) + $(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(ALIB) + +$(ALIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $^ + +$(SLIB): $(OBJS) + $(CC) $(CFLAGS) -shared $^ -o $@ $(LDFLAGS) + +$(OBJDIR)%.o: %.c $(DEPS) + $(CC) $(COMMON) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)%.o: %.cu $(DEPS) + $(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $@ + +darknet.a: $(OBJS) + ar rcs $@ $^ + +obj: + mkdir -p obj +backup: + mkdir -p backup +results: + mkdir -p results + +.PHONY: clean + +clean: + rm -rf $(OBJS) $(SLIB) $(ALIB) $(EXEC) $(EXECOBJ) darknet.a + +.PHONY: install + +install: + mkdir -p $(PREFIX)/include/darknet + cp libdarknet.a $(PREFIX)/lib/libdarknet.a + cp ${HEADERS} include/darknet.h $(PREFIX)/include/darknet + +.PHONY: uninstall + +uninstall: + rm -f $(PREFIX)/lib/libdarknet.a + rm -rf $(PREFIX)/include/darknet diff --git a/plugins/darknet/shinobi-darknet.js b/plugins/darknet/shinobi-darknet.js new file mode 100644 index 0000000..85f2470 --- /dev/null +++ b/plugins/darknet/shinobi-darknet.js @@ -0,0 +1,456 @@ +// +// Shinobi - OpenCV Plugin +// Copyright (C) 2016-2025 Moe Alam, moeiscool +// +// # Donate +// +// If you like what I am doing here and want me to continue please consider donating :) +// PayPal : paypal@m03.ca +// +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +var fs=require('fs'); +var cv=require('opencv4nodejs'); +var exec = require('child_process').exec; +var moment = require('moment'); +var Canvas = require('canvas'); +var express = require('express'); +var http = require('http'), + app = express(), + server = http.createServer(app); +var config=require('./conf.json'); +if(!config.port){config.port=8080} +if(!config.hostPort){config.hostPort=8082} +if(config.systemLog===undefined){config.systemLog=true} +if(config.cascadesDir===undefined){config.cascadesDir=__dirname+'/cascades/'} +if(config.alprConfig===undefined){config.alprConfig=__dirname+'/openalpr.conf'} +s={ + group:{}, + dir:{ + cascades : config.cascadesDir + }, + isWin:(process.platform==='win32') +} +//default stream folder check +if(!config.streamDir){ + if(s.isWin===false){ + config.streamDir='/dev/shm' + }else{ + config.streamDir=config.windowsTempDir + } + if(!fs.existsSync(config.streamDir)){ + config.streamDir=__dirname+'/streams/' + }else{ + config.streamDir+='/streams/' + } +} +s.dir.streams=config.streamDir; +//streams dir +if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); +} +s.gid=function(x){ + if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.findCascades=function(callback){ + var tmp={}; + tmp.foundCascades=[]; + fs.readdir(s.dir.cascades,function(err,files){ + files.forEach(function(cascade,n){ + if(cascade.indexOf('.xml')>-1){ + tmp.foundCascades.push(cascade.replace('.xml','')) + } + }) + s.cascadesInDir=tmp.foundCascades; + callback(tmp.foundCascades) + }) +} +s.findCascades(function(){ + //get cascades +}) +s.detectLicensePlate=function(buffer,d,tx){ + if(!d.mon.detector_lisence_plate_country||d.mon.detector_lisence_plate_country===''){ + d.mon.detector_lisence_plate_country='us' + } + d.tmpFile=s.gid(5)+'.jpg' + if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); + } + d.dir=s.dir.streams+d.ke+'/' + if(!fs.existsSync(d.dir)){ + fs.mkdirSync(d.dir); + } + d.dir=s.dir.streams+d.ke+'/'+d.id+'/' + if(!fs.existsSync(d.dir)){ + fs.mkdirSync(d.dir); + } + fs.writeFile(d.dir+d.tmpFile,buffer,function(err){ + if(err) return s.systemLog(err); + exec('alpr -j --config '+config.alprConfig+' -c '+d.mon.detector_lisence_plate_country+' '+d.dir+d.tmpFile,{encoding:'utf8'},(err, scan, stderr) => { + if(err){ + s.systemLog(err); + }else{ + try{ + try{ + scan=JSON.parse(scan.replace('--(!)Loaded CUDA classifier','').trim()) + }catch(err){ + if(!scan||!scan.results){ + return s.systemLog(scan,err); + } + } +// console.log('scan',scan) + if(scan.results.length>0){ + scan.plates=[] + scan.mats=[] + scan.results.forEach(function(v){ + v.candidates.forEach(function(g,n){ + if(v.candidates[n].matches_template) + delete(v.candidates[n].matches_template) + }) + scan.plates.push({coordinates:v.coordinates,candidates:v.candidates,confidence:v.confidence,plate:v.plate}) + var width = Math.sqrt( Math.pow(v.coordinates[1].x - v.coordinates[0].x, 2) + Math.pow(v.coordinates[1].y - v.coordinates[0].y, 2)); + var height = Math.sqrt( Math.pow(v.coordinates[2].x - v.coordinates[1].x, 2) + Math.pow(v.coordinates[2].y - v.coordinates[1].y, 2)) + scan.mats.push({ + x:v.coordinates[0].x, + y:v.coordinates[0].y, + width:width, + height:height, + tag:v.plate + }) + }) + tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:'licensePlate',reason:'object',matrices:scan.mats,imgHeight:d.mon.detector_scale_y,imgWidth:d.mon.detector_scale_x,frame:d.base64}}) + } + }catch(err){ + s.systemLog(scan,err); + } + } + exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'}) + }) + }) +} +s.detectObject=function(buffer,d,tx){ + //detect license plate? + if(d.mon.detector_lisence_plate==="1"){ + s.detectLicensePlate(buffer,d,tx) + } + //check selected opencv cascades + var selectedCascades = Object.keys(d.mon.detector_cascades); + if(selectedCascades.length > 0){ + cv.imdecodeAsync(buffer,(err,im) => { + if(err){ + console.log(err) + return + } + selectedCascades.forEach(function(cascade){ + var classifier = new cv.CascadeClassifier(s.dir.cascades+cascade+'.xml') + var matrices = classifier.detectMultiScaleGpu(im).objects + if(matrices.length > 0){ + matrices.forEach(function(v,n){ + v.centerX=v.width/2 + v.centerY=v.height/2 + v.centerXnoParent=v.x+(v.width/2) + v.centerYnoParent=v.y+(v.height/2) + }) + s.cx({ + f:'trigger', + id:d.id, + ke:d.ke, + name:cascade, + details:{ + plug:'built-in-opencv', + name:cascade, + reason:'object', + matrices : matrices, + confidence:d.average + }, + imgHeight:d.mon.detector_scale_y, + imgWidth:d.mon.detector_scale_x + }) + } + }) + }); + } +} +s.systemLog=function(q,w,e){ + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + return console.log(moment().format(),q,w,e) + } +} + +s.blenderRegion=function(d,cord,tx){ + d.width = d.image.width; + d.height = d.image.height; + if(!s.group[d.ke][d.id].canvas[cord.name]){ + if(!cord.sensitivity||isNaN(cord.sensitivity)){ + cord.sensitivity=d.mon.detector_sensitivity; + } + s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height); + s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d'); + s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#000'; + s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height); + if(cord.points&&cord.points.length>0){ + s.group[d.ke][d.id].canvasContext[cord.name].beginPath(); + for (var b = 0; b < cord.points.length; b++){ + cord.points[b][0]=parseFloat(cord.points[b][0]); + cord.points[b][1]=parseFloat(cord.points[b][1]); + if(b===0){ + s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]); + }else{ + s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]); + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clip(); + } + } + if(!s.group[d.ke][d.id].canvasContext[cord.name]){ + return + } + s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height); + if(!s.group[d.ke][d.id].blendRegion[cord.name]){ + s.group[d.ke][d.id].blendRegion[cord.name] = new Canvas(d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name] = s.group[d.ke][d.id].blendRegion[cord.name].getContext('2d'); + } + var sourceData = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create an image if the previous image doesn�t exist + if (!s.group[d.ke][d.id].lastRegionImageData[cord.name]) s.group[d.ke][d.id].lastRegionImageData[cord.name] = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create a ImageData instance to receive the blended result + var blendedData = s.group[d.ke][d.id].canvasContext[cord.name].createImageData(d.width, d.height); + // blend the 2 images + s.differenceAccuracy(blendedData.data,sourceData.data,s.group[d.ke][d.id].lastRegionImageData[cord.name].data); + // draw the result in a canvas + s.group[d.ke][d.id].blendRegionContext[cord.name].putImageData(blendedData, 0, 0); + // store the current webcam image + s.group[d.ke][d.id].lastRegionImageData[cord.name] = sourceData; + blendedData = s.group[d.ke][d.id].blendRegionContext[cord.name].getImageData(0, 0, d.width, d.height); + var i = 0; + d.average = 0; + while (i < (blendedData.data.length * 0.25)) { + d.average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]); + ++i; + } + d.average = (d.average / (blendedData.data.length * 0.25))*10; + if (d.average > parseFloat(cord.sensitivity)){ + if(d.mon.detector_use_detect_object==="1"&&d.mon.detector_second!=='1'){ + var buffer=s.group[d.ke][d.id].canvas[cord.name].toBuffer(); + s.detectObject(buffer,d,tx) + }else{ + tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:cord.name,reason:'motion',confidence:d.average,frame:d.base64}}) + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name].clearRect(0, 0, d.width, d.height); +} +function blobToBuffer (blob, cb) { + if (typeof Blob === 'undefined' || !(blob instanceof Blob)) { + throw new Error('first argument must be a Blob') + } + if (typeof cb !== 'function') { + throw new Error('second argument must be a function') + } + + var reader = new FileReader() + + function onLoadEnd (e) { + reader.removeEventListener('loadend', onLoadEnd, false) + if (e.error) cb(e.error) + else cb(null, Buffer.from(reader.result)) + } + + reader.addEventListener('loadend', onLoadEnd, false) + reader.readAsArrayBuffer(blob) +} +function fastAbs(value) { + return (value ^ (value >> 31)) - (value >> 31); +} + +function threshold(value) { + return (value > 0x15) ? 0xFF : 0; +} +s.differenceAccuracy=function(target, data1, data2) { + if (data1.length != data2.length) return null; + var i = 0; + while (i < (data1.length * 0.25)) { + var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3; + var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3; + var diff = threshold(fastAbs(average1 - average2)); + target[4 * i] = diff; + target[4 * i + 1] = diff; + target[4 * i + 2] = diff; + target[4 * i + 3] = 0xFF; + ++i; + } +} +s.checkAreas=function(d,tx){ + if(!s.group[d.ke][d.id].cords){ + if(!d.mon.cords){d.mon.cords={}} + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + } + if(d.mon.detector_frame==='1'){ + d.mon.cords.frame={name:'FULL_FRAME',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; + s.group[d.ke][d.id].cords.push(d.mon.cords.frame); + } + for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){ + if(!s.group[d.ke][d.id].cords[b]){return} + s.blenderRegion(d,s.group[d.ke][d.id].cords[b],tx) + } + delete(d.image) +} + +s.MainEventController=function(d,cn,tx){ + switch(d.f){ + case'refreshPlugins': + s.findCascades(function(cascades){ + s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:cascades},to:'GRP_'+d.ke}) + }) + break; + case'readPlugins': + s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:s.cascadesInDir},to:'GRP_'+d.ke}) + break; + case'init_plugin_as_host': + if(!cn){ + console.log('No CN',d) + return + } + if(d.key!==config.key){ + console.log(new Date(),'Plugin Key Mismatch',cn.request.connection.remoteAddress,d) + cn.emit('init',{ok:false}) + cn.disconnect() + }else{ + console.log(new Date(),'Plugin Connected to Client',cn.request.connection.remoteAddress) + cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type}) + } + break; + case'init_monitor': + if(s.group[d.ke]&&s.group[d.ke][d.id]){ + s.group[d.ke][d.id].canvas={} + s.group[d.ke][d.id].canvasContext={} + s.group[d.ke][d.id].blendRegion={} + s.group[d.ke][d.id].blendRegionContext={} + s.group[d.ke][d.id].lastRegionImageData={} + s.group[d.ke][d.id].numberOfTriggers=0 + delete(s.group[d.ke][d.id].cords) + delete(s.group[d.ke][d.id].buffer) + } + break; + case'init_aws_push': +// console.log('init_aws') + s.group[d.ke][d.id].aws={links:[],complete:0,total:d.total,videos:[],tx:tx} + break; + case'frame': + try{ + if(!s.group[d.ke]){ + s.group[d.ke]={} + } + if(!s.group[d.ke][d.id]){ + s.group[d.ke][d.id]={ + canvas:{}, + canvasContext:{}, + lastRegionImageData:{}, + blendRegion:{}, + blendRegionContext:{}, + } + } + if(!s.group[d.ke][d.id].buffer){ + s.group[d.ke][d.id].buffer=[d.frame]; + }else{ + s.group[d.ke][d.id].buffer.push(d.frame) + } + if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ + s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer); + try{ + d.mon.detector_cascades=JSON.parse(d.mon.detector_cascades) + }catch(err){ + + } + if(d.mon.detector_frame_save==="1"){ + d.base64=s.group[d.ke][d.id].buffer.toString('base64') + } + if(d.mon.detector_second==='1'&&d.objectOnly===true){ + s.detectObject(s.group[d.ke][d.id].buffer,d,tx) + }else{ + if((d.mon.detector_pam !== '1' && d.mon.detector_use_motion === "1") || d.mon.detector_use_detect_object !== "1"){ + if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){ + d.mon.cords=[] + }else{ + try{ + d.mon.cords=JSON.parse(d.mon.cords) + }catch(err){ + // console.log('d.mon.cords',err,d) + } + } + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + d.mon.cords=d.mon.cords; + d.image = new Canvas.Image; + if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){ + s.systemLog('Must set detector image size') + return + }else{ + d.image.width=d.mon.detector_scale_x; + d.image.height=d.mon.detector_scale_y; + } + d.width=d.image.width; + d.height=d.image.height; + d.image.onload = function() { + s.checkAreas(d,tx); + } + d.image.src = s.group[d.ke][d.id].buffer; + }else{ + s.detectObject(s.group[d.ke][d.id].buffer,d,tx) + } + } + s.group[d.ke][d.id].buffer=null; + } + }catch(err){ + if(err){ + s.systemLog(err) + delete(s.group[d.ke][d.id].buffer) + } + } + break; + } +} +server.listen(config.hostPort); +//web pages and plugin api +app.get('/', function (req, res) { + res.end(''+config.plug+' for Shinobi is running') +}); +//Conector to Shinobi +if(config.mode==='host'){ + //start plugin as host + var io = require('socket.io')(server); + io.attach(server); + s.connectedClients={}; + io.on('connection', function (cn) { + s.connectedClients[cn.id]={id:cn.id} + s.connectedClients[cn.id].tx = function(data){ + data.pluginKey=config.key;data.plug=config.plug; + return io.to(cn.id).emit('ocv',data); + } + cn.on('f',function(d){ + s.MainEventController(d,cn,s.connectedClients[cn.id].tx) + }); + cn.on('disconnect',function(d){ + delete(s.connectedClients[cn.id]) + }) + }); +}else{ + //start plugin as client + if(!config.host){config.host='localhost'} + var io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master + s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} + io.on('connect',function(d){ + s.cx({f:'init',plug:config.plug,notice:config.notice,type:config.type}); + }) + io.on('disconnect',function(d){ + io.connect(); + }) + io.on('f',function(d){ + s.MainEventController(d,null,s.cx) + }) +} \ No newline at end of file diff --git a/plugins/microsoft/conf.sample.json b/plugins/microsoft/conf.sample.json new file mode 100644 index 0000000..5f9b9dc --- /dev/null +++ b/plugins/microsoft/conf.sample.json @@ -0,0 +1,29 @@ +{ + "plug":"ComputerVision", + "host":"localhost", + "port":8080, + "key":"UNIQUE KEY HERE", + "computerVision":{ + "apiKey":"YOUR_KEY", + "endpoint":"http://YOUR_ENDPOINT/analyze", + "params":{ + "visualFeatures": "Categories,Description,Color", + "details": "", + "language": "en" + } + }, + "EmotionAPI":{ + "apiKey":"YOUR_KEY", + "endpoint":"http://YOUR_ENDPOINT/recognize", + "params":{} + }, + "FaceAPI":{ + "apiKey":"YOUR_KEY", + "endpoint":"http://YOUR_ENDPOINT/detect", + "params":{ + "returnFaceId": "true", + "returnFaceLandmarks": "false", + "returnFaceAttributes": "age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise" + } + } +} \ No newline at end of file diff --git a/plugins/microsoft/shinobi-ms-vision.js b/plugins/microsoft/shinobi-ms-vision.js new file mode 100644 index 0000000..938e787 --- /dev/null +++ b/plugins/microsoft/shinobi-ms-vision.js @@ -0,0 +1,170 @@ +// +// Shinobi - Microsoft Computer Vision Plugin +// Copyright (C) 2016-2025 Moe Alam, moeiscool +// +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +var fs=require('fs'); +var exec = require('child_process').exec; +//var http = require('http'); +var request = require('request'); +var moment = require('moment'); +var cognitive = require('cognitive-services'); +var config=require('./conf.json'); +if(config.systemLog===undefined){config.systemLog=true} +s={ + group:{}, + dir:{ + cascades:__dirname+'/cascades/' + }, + isWin:(process.platform==='win32') +} +//default stream folder check +if(!config.streamDir){ + if(s.isWin===false){ + config.streamDir='/dev/shm' + }else{ + config.streamDir=config.windowsTempDir + } + if(!fs.existsSync(config.streamDir)){ + config.streamDir=__dirname+'/streams/' + }else{ + config.streamDir+='/streams/' + } +} +s.dir.streams=config.streamDir; +//streams dir +if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); +} +s.gid=function(x){ + if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.systemLog=function(q,w,e){ + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + return console.log(moment().format(),q,w,e) + } +} +s.objectToParameter = function(obj){ + return Object.keys(obj).map(function(key) { + return key + '=' + encodeURIComponent(obj[key]); + }).join('&'); +} +s.sendImageToMS=function(sourceImageUrl,API,callback){ + var URL = API.endpoint+'?'+s.objectToParameter(API.params) + request(URL,{ + method: 'POST', + headers:{ + "Ocp-Apim-Subscription-Key":API.apiKey + }, + json: { + url:sourceImageUrl + } + }, callback) +} +s.detectObject=function(buffer,d){ + var sourceImageUrl = 'http://184.105.6.43/'+s.api_key+'/jpeg/'+d.ke+'/'+d.id+'/s.jpg' +// const client = new cognitive.computerVision({ +// apiKey: config.computerVision.apiKey, +// endpoint: config.computerVision.endpoint +// }); +// const parameters = { +// "visualFeatures": "Categories,Tags,Description", +// "details": "Celebrities,Landmarks" +// }; +// const headers = { +// 'Content-type': 'application/json' +// }; +// const body = { +// "url": sourceImageUrl +// }; +// +// client.analyzeImage({ +// parameters, +// headers, +// body +// }).then((response) => { +//// should(response).not.be.undefined(); +//// should(response).have.properties(["categories", "metadata", "requestId"]); +// console.log(response) +// }).catch((err) => { +// console.log('Error',err) +// }); + var responses = {} + s.sendImageToMS(sourceImageUrl,config.computerVision,function(err,resp,body1){ + responses.computerVisionURL = body1 + s.sendImageToMS(sourceImageUrl,config.FaceAPI,function(err,resp,body2){ + responses.faceApiURL = body2 + s.sendImageToMS(sourceImageUrl,config.EmotionAPI,function(err,resp,body3){ + responses.EmotionAPI = body3 + console.log('responses',JSON.stringify(responses,null,3)) + }) + }) + }) +} +s.makeMonitorObject=function(d){ + if(!s.group[d.ke]){ + s.group[d.ke]={} + } + if(!s.group[d.ke][d.id]){ + s.group[d.ke][d.id]={ + port:null, + countStarted:new Date() + } + } +} +io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master +s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} +io.on('connect',function(d){ + s.cx({f:'init',plug:config.plug}); +}) +io.on('disconnect',function(d){ + io.connect() +}) +io.on('f',function(d){ + switch(d.f){ + case'api_key': + s.api_key=d.key + break; + case'init_monitor': + if(s.group[d.ke]&&s.group[d.ke][d.id]){ + s.group[d.ke][d.id].buffer=null + s.group[d.ke][d.id].countStarted=new Date() + } + s.makeMonitorObject(d) + break; + case'frame': + d.details={} + try{ + s.makeMonitorObject(d) + if(!s.group[d.ke][d.id].buffer){ + s.group[d.ke][d.id].buffer=[d.frame]; + }else{ + s.group[d.ke][d.id].buffer.push(d.frame) + } + if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ + if(d.mon.detector_frame_save==="1"){ + d.base64=s.group[d.ke][d.id].buffer.toString('base64') + } + if(d.mon.detector_scale_x&&d.mon.detector_scale_x!==''&&d.mon.detector_scale_y&&d.mon.detector_scale_y!==''){ + d.width=d.mon.detector_scale_x; + d.height=d.mon.detector_scale_y; + }else{ + d.width=640 + d.height=480 + } + s.detectObject(Buffer.concat(s.group[d.ke][d.id].buffer),d) + s.group[d.ke][d.id].buffer=null; + } + } catch(err){ + console.error(err) + } + break; + } +}) \ No newline at end of file diff --git a/plugins/motion/.gitignore b/plugins/motion/.gitignore new file mode 100644 index 0000000..85825a5 --- /dev/null +++ b/plugins/motion/.gitignore @@ -0,0 +1 @@ +conf.json diff --git a/plugins/motion/INSTALL.sh b/plugins/motion/INSTALL.sh new file mode 100644 index 0000000..902d6ab --- /dev/null +++ b/plugins/motion/INSTALL.sh @@ -0,0 +1,5 @@ +apt-get install libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev build-essential g++ +npm install canvas +cd plugins/motion +cp conf.sample.json conf.json +pm2 start shinobi-motion.js \ No newline at end of file diff --git a/plugins/motion/README.md b/plugins/motion/README.md new file mode 100644 index 0000000..ca3c6f4 --- /dev/null +++ b/plugins/motion/README.md @@ -0,0 +1,56 @@ +# Shinobi Motion Detector + +Install required libraries. + +**Ubuntu and Debian only** + +``` +sudo apt-get install libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev build-essential g++ +``` + +**CentOS only** + +``` +su -c 'yum install cairo cairo-devel cairomm-devel libjpeg-turbo-devel pango pango-devel pangomm pangomm-devel giflib-devel' +yum search arial +yum install liberation-sans-fonts.noarch +``` + +**Install the Node.js Canvas engine** + +``` +sudo npm install canvas +``` + +Go to the Shinobi directory. **Below is an example.** + +``` +cd /home/Shinobi +``` + +Copy the config file. + +``` +cp plugins/motion/conf.sample.json plugins/motion/conf.json +``` + +Edit it the new file. Host should be `localhost` and port should match the `listening port for camera.js`. + +``` +nano plugins/motion/conf.json +``` + +Start the plugin. + +``` +node plugins/motion/shinobi-motion.js +``` + +Or to daemonize with PM2. + +``` +pm2 start plugins/motion/shinobi-motion.js +``` + +Doing this will reveal options in the monitor configuration. Shinobi does not need to be restarted when a plugin is initiated or stopped. + diff --git a/plugins/motion/conf.sample.json b/plugins/motion/conf.sample.json new file mode 100644 index 0000000..171a562 --- /dev/null +++ b/plugins/motion/conf.sample.json @@ -0,0 +1,7 @@ +{ + "plug":"Motion", + "host":"localhost", + "port":8080, + "key":"change_this_to_something_very_random____make_sure_to_match__/plugins/motion/conf.json", + "notice":"Looks like you have the Motion plugin running. Don't forget to enable Send Frames to start pushing frames to be read." +} \ No newline at end of file diff --git a/plugins/motion/libs/clusterPoints.js b/plugins/motion/libs/clusterPoints.js new file mode 100644 index 0000000..9d05fe8 --- /dev/null +++ b/plugins/motion/libs/clusterPoints.js @@ -0,0 +1,115 @@ +'use strict' + +module.exports = { + + data: getterSetter([], function(arrayOfArrays) { + var n = arrayOfArrays[0].length; + return (arrayOfArrays.map(function(array) { + return array.length == n; + }).reduce(function(boolA, boolB) { return (boolA & boolB) }, true)); + }), + + clusters: function() { + var pointsAndCentroids = kmeans(this.data(), {k: this.k(), iterations: this.iterations() }); + var points = pointsAndCentroids.points; + var centroids = pointsAndCentroids.centroids; + + return centroids.map(function(centroid) { + return { + centroid: centroid.location(), + points: points.filter(function(point) { return point.label() == centroid.label() }).map(function(point) { return point.location() }), + }; + }); + }, + + k: getterSetter(undefined, function(value) { return ((value % 1 == 0) & (value > 0)) }), + + iterations: getterSetter(Math.pow(10, 3), function(value) { return ((value % 1 == 0) & (value > 0)) }), + +}; + +function kmeans(data, config) { + // default k + var k = config.k || Math.round(Math.sqrt(data.length / 2)); + var iterations = config.iterations; + + // initialize point objects with data + var points = data.map(function(vector) { return new Point(vector) }); + + // intialize centroids randomly + var centroids = []; + for (var i = 0; i < k; i++) { + centroids.push(new Centroid(points[i % points.length].location(), i)); + }; + + // update labels and centroid locations until convergence + for (var iter = 0; iter < iterations; iter++) { + points.forEach(function(point) { point.updateLabel(centroids) }); + centroids.forEach(function(centroid) { centroid.updateLocation(points) }); + }; + + // return points and centroids + return { + points: points, + centroids: centroids + }; + +}; + +// objects +function Point(location) { + var self = this; + this.location = getterSetter(location); + this.label = getterSetter(); + this.updateLabel = function(centroids) { + var distancesSquared = centroids.map(function(centroid) { + return sumOfSquareDiffs(self.location(), centroid.location()); + }); + self.label(mindex(distancesSquared)); + }; +}; + +function Centroid(initialLocation, label) { + var self = this; + this.location = getterSetter(initialLocation); + this.label = getterSetter(label); + this.updateLocation = function(points) { + var pointsWithThisCentroid = points.filter(function(point) { return point.label() == self.label() }); + if (pointsWithThisCentroid.length > 0) self.location(averageLocation(pointsWithThisCentroid)); + }; +}; + +// convenience functions +function getterSetter(initialValue, validator) { + var thingToGetSet = initialValue; + var isValid = validator || function(val) { return true }; + return function(newValue) { + if (typeof newValue === 'undefined') return thingToGetSet; + if (isValid(newValue)) thingToGetSet = newValue; + }; +}; + +function sumOfSquareDiffs(oneVector, anotherVector) { + var squareDiffs = oneVector.map(function(component, i) { + return Math.pow(component - anotherVector[i], 2); + }); + return squareDiffs.reduce(function(a, b) { return a + b }, 0); +}; + +function mindex(array) { + var min = array.reduce(function(a, b) { + return Math.min(a, b); + }); + return array.indexOf(min); +}; + +function sumVectors(a, b) { + return a.map(function(val, i) { return val + b[i] }); +}; + +function averageLocation(points) { + var zeroVector = points[0].location().map(function() { return 0 }); + var locations = points.map(function(point) { return point.location() }); + var vectorSum = locations.reduce(function(a, b) { return sumVectors(a, b) }, zeroVector); + return vectorSum.map(function(val) { return val / points.length }); +}; diff --git a/plugins/motion/shinobi-motion-pixel.js b/plugins/motion/shinobi-motion-pixel.js new file mode 100644 index 0000000..6dfba78 --- /dev/null +++ b/plugins/motion/shinobi-motion-pixel.js @@ -0,0 +1,245 @@ +// +// Shinobi - Motion Plugin +// Copyright (C) 2016-2025 Moe Alam, moeiscool +// +// # Donate +// +// If you like what I am doing here and want me to continue please consider donating :) +// PayPal : paypal@m03.ca +// +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +var fs = require('fs'); +var moment = require('moment'); +var Canvas = require('canvas'); +var Cluster = require('./libs/clusterPoints.js'); +var config=require('./conf.json'); +if(process.argv[2]&&process.argv[3]){ + config.host=process.argv[2] + config.port=process.argv[3] + config.key=process.argv[4] +} +if(config.systemLog===undefined){config.systemLog=true} +s={ + group:{}, +} +s.systemLog=function(q,w,e){ + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + return console.log(moment().format(),q,w,e) + } +} +s.checkRegion=function(d,cord){ + d.width = d.image.width; + d.height = d.image.height; + if(!s.group[d.ke][d.id].canvas[cord.name]){ + if(!cord.sensitivity||isNaN(cord.sensitivity)){ + cord.sensitivity=d.mon.detector_sensitivity; + } + s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height); + s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d'); + s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#005337'; + s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height); + if(cord.points&&cord.points.length>0){ + s.group[d.ke][d.id].canvasContext[cord.name].beginPath(); + for (var b = 0; b < cord.points.length; b++){ + cord.points[b][0]=parseFloat(cord.points[b][0]); + cord.points[b][1]=parseFloat(cord.points[b][1]); + if(b===0){ + s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]); + }else{ + s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]); + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clip(); + } + } + s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height); + var blenderCanvas = s.group[d.ke][d.id].canvas[cord.name]; + var blenderCanvasContext = s.group[d.ke][d.id].canvasContext[cord.name]; + s.group[d.ke][d.id].frameSelected[s.group[d.ke][d.id].frameNumber] = blenderCanvasContext.getImageData(0, 0, blenderCanvas.width, blenderCanvas.height); + s.group[d.ke][d.id].frameNumber = 0 == s.group[d.ke][d.id].frameNumber ? 1 : 0; + s.group[d.ke][d.id].lastRegionImageData = blenderCanvasContext.getImageData(0, 0, blenderCanvas.width, blenderCanvas.height); + if(!s.group[d.ke][d.id].lastRegionImageData){return} + var foundPixels = []; + var average = 0; + var currentImageLength = s.group[d.ke][d.id].lastRegionImageData.data.length * 0.25; + for (b = 0; b < currentImageLength;){ + var pos = b * 4 + s.group[d.ke][d.id].lastRegionImageData.data[pos] = .5 * (255 - s.group[d.ke][d.id].lastRegionImageData.data[pos]) + .5 * s.group[d.ke][d.id].frameSelected[s.group[d.ke][d.id].frameNumber].data[pos]; + s.group[d.ke][d.id].lastRegionImageData.data[pos + 1] = .5 * (255 - s.group[d.ke][d.id].lastRegionImageData.data[pos + 1]) + .5 * s.group[d.ke][d.id].frameSelected[s.group[d.ke][d.id].frameNumber].data[pos + 1]; + s.group[d.ke][d.id].lastRegionImageData.data[pos + 2] = .5 * (255 - s.group[d.ke][d.id].lastRegionImageData.data[pos + 2]) + .5 * s.group[d.ke][d.id].frameSelected[s.group[d.ke][d.id].frameNumber].data[pos + 2]; + s.group[d.ke][d.id].lastRegionImageData.data[pos + 3] = 255; + var score = (s.group[d.ke][d.id].lastRegionImageData.data[pos] + s.group[d.ke][d.id].lastRegionImageData.data[pos + 1] + s.group[d.ke][d.id].lastRegionImageData.data[pos + 2]) / 3; + if(score>170){ + var x = (pos / 4) % d.width; + var y = Math.floor((pos / 4) / d.width); + foundPixels.push([x,y]) + } + + average += (s.group[d.ke][d.id].lastRegionImageData.data[b * 4] + s.group[d.ke][d.id].lastRegionImageData.data[b * 4 + 1] + s.group[d.ke][d.id].lastRegionImageData.data[b * 4 + 2]); + + b += 4; + } +// console.log(foundPixels) + var matrices + if(d.mon.detector_region_of_interest==='1'&&foundPixels.length>0){ + var groupedPoints = Object.assign({},Cluster); + groupedPoints.iterations(25); + groupedPoints.data(foundPixels); + var groupedPoints = groupedPoints.clusters() + var matrices=[] + var mostHeight = 0; + var mostWidth = 0; + var mostWithMotion = null; + groupedPoints.forEach(function(v,n){ + var matrix = { + topLeft:[d.width,d.height], + topRight:[0,d.height], + bottomRight:[0,0], + bottomLeft:[d.width,0], + } + v.points.forEach(function(b){ + var x = b[0] + var y = b[1] + if(xmatrix.topRight[0])matrix.topRight[0]=x; + if(ymatrix.bottomRight[0])matrix.bottomRight[0]=x; + if(y>matrix.bottomRight[1])matrix.bottomRight[1]=y; + //Bottom Left point + if(xmatrix.bottomLeft[1])matrix.bottomLeft[1]=y; + }) + matrix.x = matrix.topLeft[0]; + matrix.y = matrix.topLeft[1]; + matrix.width = matrix.topRight[0] - matrix.topLeft[0] + matrix.height = matrix.bottomLeft[1] - matrix.topLeft[1] + + if(matrix.width>mostWidth&&matrix.height>mostHeight){ + mostWidth = matrix.width; + mostHeight = matrix.height; + mostWithMotion = matrix; + } + + matrices.push(matrix) + }) + } + average = (average / (currentImageLength)); + if (average > parseFloat(cord.sensitivity)){ + s.cx({f:'trigger',id:d.id,ke:d.ke,details:{plug:config.plug,name:cord.name,reason:'motion',confidence:average,matrices:matrices}}) + } + s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height); +} +s.checkAreas=function(d){ + if(!s.group[d.ke][d.id].cords){ + if(!d.mon.cords){d.mon.cords={}} + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + } + if(d.mon.detector_frame==='1'){ + d.mon.cords.frame={name:'frame',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; + s.group[d.ke][d.id].cords.push(d.mon.cords.frame); + } + for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){ + if(!s.group[d.ke][d.id].cords[b]){return} + s.checkRegion(d,s.group[d.ke][d.id].cords[b]) + } + delete(d.image) +} + +io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master +s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} +io.on('connect',function(d){ + s.cx({f:'init',plug:config.plug,notice:config.notice}); +}) +io.on('disconnect',function(d){ + io.connect(); +}) +io.on('f',function(d){ + switch(d.f){ + case'init_monitor': + if(s.group[d.ke]&&s.group[d.ke][d.id]){ + s.group[d.ke][d.id].canvas={} + s.group[d.ke][d.id].canvasContext={} + s.group[d.ke][d.id].lastRegionImageData=undefined + s.group[d.ke][d.id].frameNumber=0 + s.group[d.ke][d.id].frameSelected=[] + delete(s.group[d.ke][d.id].cords) + delete(s.group[d.ke][d.id].buffer) + } + break; + case'frame': + try{ + if(!s.group[d.ke]){ + s.group[d.ke]={} + } + if(!s.group[d.ke][d.id]){ + s.group[d.ke][d.id]={ + canvas:{}, + canvasContext:{}, + lastRegionImageData:undefined, + frameNumber:0, + frameSelected:[], + } + } + if(!s.group[d.ke][d.id].buffer){ + s.group[d.ke][d.id].buffer=[d.frame]; + }else{ + s.group[d.ke][d.id].buffer.push(d.frame) + } + if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ + if(s.group[d.ke][d.id].motion_lock){ + return + }else{ + if(!d.mon.detector_lock_timeout||d.mon.detector_lock_timeout===''||d.mon.detector_lock_timeout==0){ + d.mon.detector_lock_timeout=2000 + }else{ + d.mon.detector_lock_timeout=parseFloat(d.mon.detector_lock_timeout) + } + s.group[d.ke][d.id].motion_lock=setTimeout(function(){ + clearTimeout(s.group[d.ke][d.id].motion_lock); + delete(s.group[d.ke][d.id].motion_lock); + },d.mon.detector_lock_timeout) + } + s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer); + if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){ + d.mon.cords=[] + }else{ + try{ + d.mon.cords=JSON.parse(d.mon.cords) + }catch(err){ + } + } + if(d.mon.detector_frame_save==="1"){ + d.base64=s.group[d.ke][d.id].buffer.toString('base64') + } + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + d.mon.cords=d.mon.cords; + d.image = new Canvas.Image; + if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){ + s.systemLog('Must set detector image size') + return + }else{ + d.image.width=d.mon.detector_scale_x; + d.image.height=d.mon.detector_scale_y; + } + d.image.onload = function() { + s.checkAreas(d); + } + d.image.src = s.group[d.ke][d.id].buffer; + s.group[d.ke][d.id].buffer=null; + } + }catch(err){ + if(err){ + s.systemLog(err) + delete(s.group[d.ke][d.id].buffer) + } + } + break; + } +}) \ No newline at end of file diff --git a/plugins/motion/shinobi-motion.js b/plugins/motion/shinobi-motion.js new file mode 100644 index 0000000..3b003cf --- /dev/null +++ b/plugins/motion/shinobi-motion.js @@ -0,0 +1,233 @@ +// +// Shinobi - Motion Plugin +// Copyright (C) 2016-2025 Moe Alam, moeiscool +// +// # Donate +// +// If you like what I am doing here and want me to continue please consider donating :) +// PayPal : paypal@m03.ca +// +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +var fs = require('fs'); +var moment = require('moment'); +var Canvas = require('canvas'); +var config=require('./conf.json'); +if(process.argv[2]&&process.argv[3]){ + config.host=process.argv[2] + config.port=process.argv[3] + config.key=process.argv[4] +} +if(config.systemLog===undefined){config.systemLog=true} +s={ + group:{}, +} +s.systemLog=function(q,w,e){ + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + return console.log(moment().format(),q,w,e) + } +} +s.blenderRegion=function(d,cord){ + d.width = d.image.width; + d.height = d.image.height; + if(!s.group[d.ke][d.id].canvas[cord.name]){ + if(!cord.sensitivity||isNaN(cord.sensitivity)){ + cord.sensitivity=d.mon.detector_sensitivity; + } + s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height); + s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d'); + s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#005337'; + s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height); + if(cord.points&&cord.points.length>0){ + s.group[d.ke][d.id].canvasContext[cord.name].beginPath(); + for (var b = 0; b < cord.points.length; b++){ + cord.points[b][0]=parseFloat(cord.points[b][0]); + cord.points[b][1]=parseFloat(cord.points[b][1]); + if(b===0){ + s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]); + }else{ + s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]); + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clip(); + } + } + if(!s.group[d.ke][d.id].canvasContext[cord.name]){ + return + } + s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height); + if(!s.group[d.ke][d.id].blendRegion[cord.name]){ + s.group[d.ke][d.id].blendRegion[cord.name] = new Canvas(d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name] = s.group[d.ke][d.id].blendRegion[cord.name].getContext('2d'); + } + var sourceData = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create an image if the previous image doesn�t exist + if (!s.group[d.ke][d.id].lastRegionImageData[cord.name]) s.group[d.ke][d.id].lastRegionImageData[cord.name] = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create a ImageData instance to receive the blended result + var blendedData = s.group[d.ke][d.id].canvasContext[cord.name].createImageData(d.width, d.height); + // blend the 2 images + s.differenceAccuracy(blendedData.data,sourceData.data,s.group[d.ke][d.id].lastRegionImageData[cord.name].data); + // draw the result in a canvas + s.group[d.ke][d.id].blendRegionContext[cord.name].putImageData(blendedData, 0, 0); + // store the current webcam image + s.group[d.ke][d.id].lastRegionImageData[cord.name] = sourceData; + blendedData = s.group[d.ke][d.id].blendRegionContext[cord.name].getImageData(0, 0, d.width, d.height); + var i = 0; + var average = 0; + while (i < (blendedData.data.length * 0.25)) { + average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]); + ++i; + } + average = (average / (blendedData.data.length * 0.25))*10; + if (average > parseFloat(cord.sensitivity)){ + s.cx({f:'trigger',id:d.id,ke:d.ke,details:{plug:config.plug,name:cord.name,reason:'motion',confidence:average}}) + + } + s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name].clearRect(0, 0, d.width, d.height); +} +function fastAbs(value) { + return (value ^ (value >> 31)) - (value >> 31); +} + +function threshold(value) { + return (value > 0x15) ? 0xFF : 0; +} + +function difference(target, data1, data2) { + // blend mode difference + if (data1.length != data2.length) return null; + var i = 0; + while (i < (data1.length * 0.25)) { + target[4 * i] = data1[4 * i] == 0 ? 0 : fastAbs(data1[4 * i] - data2[4 * i]); + target[4 * i + 1] = data1[4 * i + 1] == 0 ? 0 : fastAbs(data1[4 * i + 1] - data2[4 * i + 1]); + target[4 * i + 2] = data1[4 * i + 2] == 0 ? 0 : fastAbs(data1[4 * i + 2] - data2[4 * i + 2]); + target[4 * i + 3] = 0xFF; + ++i; + } +} +s.differenceAccuracy=function(target, data1, data2) { + if (data1.length != data2.length) return null; + var i = 0; + while (i < (data1.length * 0.25)) { + var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3; + var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3; + var diff = threshold(fastAbs(average1 - average2)); + target[4 * i] = diff; + target[4 * i + 1] = diff; + target[4 * i + 2] = diff; + target[4 * i + 3] = 0xFF; + ++i; + } +} + +s.checkAreas=function(d){ + if(!s.group[d.ke][d.id].cords){ + if(!d.mon.cords){d.mon.cords={}} + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + } + if(d.mon.detector_frame==='1'){ + d.mon.cords.frame={name:'frame',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; + s.group[d.ke][d.id].cords.push(d.mon.cords.frame); + } + for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){ + if(!s.group[d.ke][d.id].cords[b]){return} + s.blenderRegion(d,s.group[d.ke][d.id].cords[b]) + } + delete(d.image) +} + +io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master +s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} +io.on('connect',function(d){ + s.cx({f:'init',plug:config.plug,notice:config.notice}); +}) +io.on('disconnect',function(d){ + io.connect(); +}) +io.on('f',function(d){ + switch(d.f){ + case'init_monitor': + if(s.group[d.ke]&&s.group[d.ke][d.id]){ + s.group[d.ke][d.id].canvas={} + s.group[d.ke][d.id].canvasContext={} + s.group[d.ke][d.id].blendRegion={} + s.group[d.ke][d.id].blendRegionContext={} + s.group[d.ke][d.id].lastRegionImageData={} + delete(s.group[d.ke][d.id].cords) + delete(s.group[d.ke][d.id].buffer) + } + break; + case'frame': + try{ + if(!s.group[d.ke]){ + s.group[d.ke]={} + } + if(!s.group[d.ke][d.id]){ + s.group[d.ke][d.id]={ + canvas:{}, + canvasContext:{}, + lastRegionImageData:{}, + blendRegion:{}, + blendRegionContext:{}, + } + } + if(!s.group[d.ke][d.id].buffer){ + s.group[d.ke][d.id].buffer=[d.frame]; + }else{ + s.group[d.ke][d.id].buffer.push(d.frame) + } + if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ + if(s.group[d.ke][d.id].motion_lock){ + return + }else{ + if(!d.mon.detector_lock_timeout||d.mon.detector_lock_timeout===''||d.mon.detector_lock_timeout==0){ + d.mon.detector_lock_timeout=2000 + }else{ + d.mon.detector_lock_timeout=parseFloat(d.mon.detector_lock_timeout) + } + s.group[d.ke][d.id].motion_lock=setTimeout(function(){ + clearTimeout(s.group[d.ke][d.id].motion_lock); + delete(s.group[d.ke][d.id].motion_lock); + },d.mon.detector_lock_timeout) + } + s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer); + if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){ + d.mon.cords=[] + }else{ + try{ + d.mon.cords=JSON.parse(d.mon.cords) + }catch(err){ + } + } + if(d.mon.detector_frame_save==="1"){ + d.base64=s.group[d.ke][d.id].buffer.toString('base64') + } + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + d.mon.cords=d.mon.cords; + d.image = new Canvas.Image; + if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){ + s.systemLog('Must set detector image size') + return + }else{ + d.image.width=d.mon.detector_scale_x; + d.image.height=d.mon.detector_scale_y; + } + d.image.onload = function() { + s.checkAreas(d); + } + d.image.src = s.group[d.ke][d.id].buffer; + s.group[d.ke][d.id].buffer=null; + } + }catch(err){ + if(err){ + s.systemLog(err) + delete(s.group[d.ke][d.id].buffer) + } + } + break; + } +}) \ No newline at end of file diff --git a/plugins/openalpr/.gitignore b/plugins/openalpr/.gitignore new file mode 100644 index 0000000..5881654 --- /dev/null +++ b/plugins/openalpr/.gitignore @@ -0,0 +1,2 @@ +conf.json +cascades \ No newline at end of file diff --git a/plugins/openalpr/README.md b/plugins/openalpr/README.md new file mode 100644 index 0000000..36a023f --- /dev/null +++ b/plugins/openalpr/README.md @@ -0,0 +1,93 @@ +# OpenALPR and Motion Detector + +Install required libraries. + +**Ubuntu and Debian only** + +``` +sudo apt update && sudo apt install libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev build-essential g++ openalpr openalpr-daemon openalpr-utils libopenalpr-dev -y +``` + +**Install the Node.js Canvas engine** + +``` +sudo npm install canvas@1.6 +``` +Go to the Shinobi directory. **Below is an example.** + +``` +cd /home/Shinobi +``` + +Copy the config file. + +``` +cp plugins/openalpr/conf.sample.json plugins/openalpr/conf.json +``` + +Edit it the new file. Host should be `localhost` and port should match the `listening port for camera.js`. + +``` +nano plugins/openalpr/conf.json +``` + +Start the plugin. + +``` +node plugins/openalpr/shinobi-motion.js +``` + +Or to daemonize with PM2. + +``` +pm2 start plugins/openalpr/shinobi-motion.js +``` + +Doing this will reveal options in the monitor configuration. Shinobi does not need to be restarted when a plugin is initiated or stopped. + +## Run the plugin as a Host +> The main app (Shinobi) will be the client and the plugin will be the host. The purpose of allowing this method is so that you can use one plugin for multiple Shinobi instances. Allowing you to easily manage connections without starting multiple processes. + +Edit your plugins configuration file. Set the `hostPort` **to be different** than the `listening port for camera.js`. + +``` +nano plugins/openalpr/conf.json +``` + +Here is a sample of a Host configuration for the plugin. + - `plug` is the name of the plugin corresponding in the main configuration file. + - `https` choose if you want to use SSL or not. Default is `false`. + - `hostPort` can be any available port number. **Don't make this the same port number as Shinobi.** Default is `8082`. + - `type` tells the main application (Shinobi) what kind of plugin it is. In this case it is a detector. + +``` +{ + "plug":"OpenALPR", + "hostPort":8082, + "key":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi", + "mode":"host", + "type":"detector" +} +``` + +Now modify the **main configuration file** located in the main directory of Shinobi. *Where you currently should be.* + +``` +nano conf.json +``` + +Add the `plugins` array if you don't already have it. Add the following *object inside the array*. + +``` + "plugins":[ + { + "id" : "OpenALPR", + "https" : false, + "host" : "localhost", + "port" : 8082, + "key" : "SomeOpenALPRkeySoPeopleDontMessWithYourShinobi", + "mode" : "host", + "type" : "detector" + } + ], +``` \ No newline at end of file diff --git a/plugins/openalpr/conf.sample.json b/plugins/openalpr/conf.sample.json new file mode 100644 index 0000000..08ce79d --- /dev/null +++ b/plugins/openalpr/conf.sample.json @@ -0,0 +1,9 @@ +{ + "plug":"OpenALPR", + "host":"localhost", + "port":8080, + "hostPort":8082, + "key":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi", + "mode":"client", + "type":"detector" +} \ No newline at end of file diff --git a/plugins/openalpr/openalpr.conf b/plugins/openalpr/openalpr.conf new file mode 100644 index 0000000..070752b --- /dev/null +++ b/plugins/openalpr/openalpr.conf @@ -0,0 +1,94 @@ + +; Specify the path to the runtime data directory +runtime_dir = ${CMAKE_INSTALL_PREFIX}/share/openalpr/runtime_data + + +ocr_img_size_percent = 1.33333333 +state_id_img_size_percent = 2.0 + +; Calibrating your camera improves detection accuracy in cases where vehicle plates are captured at a steep angle +; Use the openalpr-utils-calibrate utility to calibrate your fixed camera to adjust for an angle +; Once done, update the prewarp config with the values obtained from the tool +prewarp = + +; detection will ignore plates that are too large. This is a good efficiency technique to use if the +; plates are going to be a fixed distance away from the camera (e.g., you will never see plates that fill +; up the entire image +max_plate_width_percent = 100 +max_plate_height_percent = 100 + +; detection_iteration_increase is the percentage that the LBP frame increases each iteration. +; It must be greater than 1.0. A value of 1.01 means increase by 1%, 1.10 increases it by 10% each time. +; So a 1% increase would be ~10x slower than 10% to process, but it has a higher chance of landing +; directly on the plate and getting a strong detection +detection_iteration_increase = 1.1 + +; The minimum detection strength determines how sure the detection algorithm must be before signaling that +; a plate region exists. Technically this corresponds to LBP nearest neighbors (e.g., how many detections +; are clustered around the same area). For example, 2 = very lenient, 9 = very strict. +detection_strictness = 3 + +; The detection doesn't necessarily need an extremely high resolution image in order to detect plates +; Using a smaller input image should still find the plates and will do it faster +; Tweaking the max_detection_input values will resize the input image if it is larger than these sizes +; max_detection_input_width/height are specified in pixels +max_detection_input_width = 1280 +max_detection_input_height = 720 + +; detector is the technique used to find license plate regions in an image. Value can be set to +; lbpcpu - default LBP-based detector uses the system CPU +; lbpgpu - LBP-based detector that uses Nvidia GPU to increase recognition speed. +; lbpopencl - LBP-based detector that uses OpenCL GPU to increase recognition speed. Requires OpenCV 3.0 +; morphcpu - Experimental detector that detects white rectangles in an image. Does not require training. +detector = lbpgpu + +; If set to true, all results must match a postprocess text pattern if a pattern is available. +; If not, the result is disqualified. +must_match_pattern = 0 + +; Bypasses plate detection. If this is set to 1, the library assumes that each region provided is a likely plate area. +skip_detection = 0 + +; Specifies the full path to an image file that constrains the detection area. Only the plate regions allowed through the mask +; will be analyzed. The mask image must match the resolution of your image to be analyzed. The mask is black and white. +; Black areas will be ignored, white areas will be searched. An empty value means no mask (scan the entire image) +detection_mask_image = + +; OpenALPR can scan the same image multiple times with different randomization. Setting this to a value larger than +; 1 may increase accuracy, but will increase processing time linearly (e.g., analysis_count = 3 is 3x slower) +analysis_count = 1 + +; OpenALPR detects high-contrast plate crops and uses an alternative edge detection technique. Setting this to 0.0 +; would classify ALL images as high-contrast, setting it to 1.0 would classify no images as high-contrast. +contrast_detection_threshold = 0.3 + +max_plate_angle_degrees = 15 + +ocr_min_font_point = 6 + +; Minimum OCR confidence percent to consider. +postprocess_min_confidence = 65 + +; Any OCR character lower than this will also add an equally likely +; chance that the character is incorrect and will be skipped. Value is a confidence percent +postprocess_confidence_skip_level = 80 + + +debug_general = 0 +debug_timing = 0 +debug_detector = 0 +debug_prewarp = 0 +debug_state_id = 0 +debug_plate_lines = 0 +debug_plate_corners = 0 +debug_char_segment = 0 +debug_char_analysis = 0 +debug_color_filter = 0 +debug_ocr = 0 +debug_postprocess = 0 +debug_show_images = 0 +debug_pause_on_frame = 0 + + + + diff --git a/plugins/openalpr/package.json b/plugins/openalpr/package.json new file mode 100644 index 0000000..7f6d5aa --- /dev/null +++ b/plugins/openalpr/package.json @@ -0,0 +1,18 @@ +{ + "name": "shinobi-openalpr", + "version": "1.0.0", + "description": "OpenALPR plugin for Shinobi", + "main": "shinobi-openalpr.js", + "dependencies": { + "canvas": "^1.6.7", + "express": "^4.16.2", + "moment": "^2.19.2", + "socket.io": "^2.0.4" + }, + "devDependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Moe Alam", + "license": "ISC" +} diff --git a/plugins/openalpr/shinobi-openalpr.js b/plugins/openalpr/shinobi-openalpr.js new file mode 100644 index 0000000..8295208 --- /dev/null +++ b/plugins/openalpr/shinobi-openalpr.js @@ -0,0 +1,413 @@ +// +// Shinobi - OpenALPR Plugin +// Copyright (C) 2016-2025 Moe Alam, moeiscool +// +// # Donate +// +// If you like what I am doing here and want me to continue please consider donating :) +// PayPal : paypal@m03.ca +// +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +//main vars +var fs=require('fs'); +var exec = require('child_process').exec; +var moment = require('moment'); +var Canvas = require('canvas'); +var express = require('express'); +var config=require('./conf.json'); +var http = require('http'), + app = express(), + server = http.createServer(app); +s={ + group:{}, + dir:{ + cascades:__dirname+'/cascades/' + }, + isWin:(process.platform==='win32'), + s:function(json){return JSON.stringify(json,null,3)} +} +s.checkCorrectPathEnding=function(x){ + var length=x.length + if(x.charAt(length-1)!=='/'){ + x=x+'/' + } + return x.replace('__DIR__',__dirname) +} +if(!config.port){config.port=8080} +if(!config.hostPort){config.hostPort=8082} +if(config.systemLog===undefined){config.systemLog=true} +if(config.alprConfig===undefined){config.alprConfig=__dirname+'/openalpr.conf'} +//default stream folder check +if(!config.streamDir){ + if(s.isWin===false){ + config.streamDir='/dev/shm' + }else{ + config.streamDir=config.windowsTempDir + } + if(!fs.existsSync(config.streamDir)){ + config.streamDir=__dirname+'/streams/' + }else{ + config.streamDir+='/streams/' + } +} +s.dir.streams=config.streamDir; +//streams dir +if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); +} +s.gid=function(x){ + if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.detectObject=function(buffer,d,tx){ + var keys = Object.keys(d.mon.detector_cascades); + if(d.mon.detector_lisence_plate==="1"){ + if(!d.mon.detector_lisence_plate_country||d.mon.detector_lisence_plate_country===''){ + d.mon.detector_lisence_plate_country='us' + } + d.tmpFile=s.gid(5)+'.jpg' + if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); + } + d.dir=s.dir.streams+d.ke+'/' + if(!fs.existsSync(d.dir)){ + fs.mkdirSync(d.dir); + } + d.dir=s.dir.streams+d.ke+'/'+d.id+'/' + if(!fs.existsSync(d.dir)){ + fs.mkdirSync(d.dir); + } + fs.writeFile(d.dir+d.tmpFile,buffer,function(err){ + if(err) return s.systemLog(err); + exec('alpr -j --config '+config.alprConfig+' -c '+d.mon.detector_lisence_plate_country+' '+d.dir+d.tmpFile,{encoding:'utf8'},(err, scan, stderr) => { + if(err){ + s.systemLog(err); + }else{ + try{ + try{ + scan=JSON.parse(scan.replace('--(!)Loaded CUDA classifier','').trim()) + }catch(err){ + if(!scan||!scan.results){ + return s.systemLog(scan,err); + } + } +// console.log('scan',scan) + if(scan.results.length>0){ + if(s.isNumberOfTriggersMet(d,2)){ + scan.plates=[] + scan.mats=[] + scan.results.forEach(function(v){ + v.candidates.forEach(function(g,n){ + if(v.candidates[n].matches_template) + delete(v.candidates[n].matches_template) + }) + scan.plates.push({coordinates:v.coordinates,candidates:v.candidates,confidence:v.confidence,plate:v.plate}) + var width = Math.sqrt( Math.pow(v.coordinates[1].x - v.coordinates[0].x, 2) + Math.pow(v.coordinates[1].y - v.coordinates[0].y, 2)); + var height = Math.sqrt( Math.pow(v.coordinates[2].x - v.coordinates[1].x, 2) + Math.pow(v.coordinates[2].y - v.coordinates[1].y, 2)) + scan.mats.push({ + x:v.coordinates[0].x, + y:v.coordinates[0].y, + width:width, + height:height, + tag:v.plate + }) + }) + tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:'licensePlate',reason:'object',matrices:scan.mats,imgHeight:d.mon.detector_scale_y,imgWidth:d.mon.detector_scale_x,frame:d.base64}}) + } + } + }catch(err){ + s.systemLog(scan,err); + } + } + exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'}) + }) + }) + } +} +s.systemLog=function(q,w,e){ + if(w===undefined){return} + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + return console.log(moment().format(),q,w,e) + } +} +s.blenderRegion=function(d,cord,tx){ + d.width = d.image.width; + d.height = d.image.height; + if(!s.group[d.ke][d.id].canvas[cord.name]){ + if(!cord.sensitivity||isNaN(cord.sensitivity)){ + cord.sensitivity=d.mon.detector_sensitivity; + } + s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height); + s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d'); + s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#000'; + s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height); + if(cord.points&&cord.points.length>0){ + s.group[d.ke][d.id].canvasContext[cord.name].beginPath(); + for (var b = 0; b < cord.points.length; b++){ + cord.points[b][0]=parseFloat(cord.points[b][0]); + cord.points[b][1]=parseFloat(cord.points[b][1]); + if(b===0){ + s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]); + }else{ + s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]); + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clip(); + } + } + if(!s.group[d.ke][d.id].canvasContext[cord.name]){ + return + } + s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height); + if(!s.group[d.ke][d.id].blendRegion[cord.name]){ + s.group[d.ke][d.id].blendRegion[cord.name] = new Canvas(d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name] = s.group[d.ke][d.id].blendRegion[cord.name].getContext('2d'); + } + var sourceData = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create an image if the previous image doesn�t exist + if (!s.group[d.ke][d.id].lastRegionImageData[cord.name]) s.group[d.ke][d.id].lastRegionImageData[cord.name] = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create a ImageData instance to receive the blended result + var blendedData = s.group[d.ke][d.id].canvasContext[cord.name].createImageData(d.width, d.height); + // blend the 2 images + s.differenceAccuracy(blendedData.data,sourceData.data,s.group[d.ke][d.id].lastRegionImageData[cord.name].data); + // draw the result in a canvas + s.group[d.ke][d.id].blendRegionContext[cord.name].putImageData(blendedData, 0, 0); + // store the current webcam image + s.group[d.ke][d.id].lastRegionImageData[cord.name] = sourceData; + blendedData = s.group[d.ke][d.id].blendRegionContext[cord.name].getImageData(0, 0, d.width, d.height); + var i = 0; + d.average = 0; + while (i < (blendedData.data.length * 0.25)) { + d.average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]); + ++i; + } + d.average = (d.average / (blendedData.data.length * 0.25))*10; + if (d.average > parseFloat(cord.sensitivity)){ + if(s.isNumberOfTriggersMet(d,2)){ + if(d.mon.detector_use_detect_object==="1"&&d.mon.detector_second!=='1'){ + var buffer=s.group[d.ke][d.id].canvas[cord.name].toBuffer(); + s.detectObject(buffer,d,tx) + }else{ + tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:cord.name,reason:'motion',confidence:d.average,frame:d.base64}}) + } + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name].clearRect(0, 0, d.width, d.height); +} +function blobToBuffer (blob, cb) { + if (typeof Blob === 'undefined' || !(blob instanceof Blob)) { + throw new Error('first argument must be a Blob') + } + if (typeof cb !== 'function') { + throw new Error('second argument must be a function') + } + + var reader = new FileReader() + + function onLoadEnd (e) { + reader.removeEventListener('loadend', onLoadEnd, false) + if (e.error) cb(e.error) + else cb(null, Buffer.from(reader.result)) + } + + reader.addEventListener('loadend', onLoadEnd, false) + reader.readAsArrayBuffer(blob) +} +function fastAbs(value) { + return (value ^ (value >> 31)) - (value >> 31); +} + +function threshold(value) { + return (value > 0x15) ? 0xFF : 0; +} +s.differenceAccuracy=function(target, data1, data2) { + if (data1.length != data2.length) return null; + var i = 0; + while (i < (data1.length * 0.25)) { + var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3; + var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3; + var diff = threshold(fastAbs(average1 - average2)); + target[4 * i] = diff; + target[4 * i + 1] = diff; + target[4 * i + 2] = diff; + target[4 * i + 3] = 0xFF; + ++i; + } +} +s.checkAreas=function(d,tx){ + if(!s.group[d.ke][d.id].cords){ + if(!d.mon.cords){d.mon.cords={}} + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + } + if(d.mon.detector_frame==='1'){ + d.mon.cords.frame={name:'FULL_FRAME',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; + s.group[d.ke][d.id].cords.push(d.mon.cords.frame); + } + for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){ + if(!s.group[d.ke][d.id].cords[b]){return} + s.blenderRegion(d,s.group[d.ke][d.id].cords[b],tx) + } + delete(d.image) +} +s.isNumberOfTriggersMet = function(d,max){ +// ++s.group[d.ke][d.id].numberOfTriggers +// clearTimeout(s.group[d.ke][d.id].numberOfTriggersTimeout) +// s.group[d.ke][d.id].numberOfTriggersTimeout = setTimeout(function(){ +// s.group[d.ke][d.id].numberOfTriggers=0 +// },10000) +// if(s.group[d.ke][d.id].numberOfTriggers>max){ + return true; +// } +// return false; +} +s.MainEventController=function(d,cn,tx){ + switch(d.f){ + case'init_plugin_as_host': + if(!cn){ + console.log('No CN',d) + return + } + if(d.key!==config.key){ + console.log(new Date(),'Plugin Key Mismatch',cn.request.connection.remoteAddress,d) + cn.emit('init',{ok:false}) + cn.disconnect() + }else{ + console.log(new Date(),'Plugin Connected to Client',cn.request.connection.remoteAddress) + cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type}) + } + break; + case'init_monitor': + if(s.group[d.ke]&&s.group[d.ke][d.id]){ + s.group[d.ke][d.id].canvas={} + s.group[d.ke][d.id].canvasContext={} + s.group[d.ke][d.id].blendRegion={} + s.group[d.ke][d.id].blendRegionContext={} + s.group[d.ke][d.id].lastRegionImageData={} + s.group[d.ke][d.id].numberOfTriggers=0 + delete(s.group[d.ke][d.id].cords) + delete(s.group[d.ke][d.id].buffer) + } + break; + case'init_aws_push': +// console.log('init_aws') + s.group[d.ke][d.id].aws={links:[],complete:0,total:d.total,videos:[],tx:tx} + break; + case'frame': + try{ + if(!s.group[d.ke]){ + s.group[d.ke]={} + } + if(!s.group[d.ke][d.id]){ + s.group[d.ke][d.id]={ + canvas:{}, + canvasContext:{}, + lastRegionImageData:{}, + blendRegion:{}, + blendRegionContext:{}, + } + } + if(!s.group[d.ke][d.id].buffer){ + s.group[d.ke][d.id].buffer=[d.frame]; + }else{ + s.group[d.ke][d.id].buffer.push(d.frame) + } + if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ + s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer); + try{ + d.mon.detector_cascades=JSON.parse(d.mon.detector_cascades) + }catch(err){ + + } + if(d.mon.detector_frame_save==="1"){ + d.base64=s.group[d.ke][d.id].buffer.toString('base64') + } + if(d.mon.detector_second==='1'&&d.objectOnly===true){ + s.detectObject(s.group[d.ke][d.id].buffer,d,tx) + }else{ + if(d.mon.detector_use_motion==="1"||d.mon.detector_use_detect_object!=="1"){ + if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){ + d.mon.cords=[] + }else{ + try{ + d.mon.cords=JSON.parse(d.mon.cords) + }catch(err){ + // console.log('d.mon.cords',err,d) + } + } + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + d.mon.cords=d.mon.cords; + d.image = new Canvas.Image; + if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){ + s.systemLog('Must set detector image size') + return + }else{ + d.image.width=d.mon.detector_scale_x; + d.image.height=d.mon.detector_scale_y; + } + d.width=d.image.width; + d.height=d.image.height; + d.image.onload = function() { + s.checkAreas(d,tx); + } + d.image.src = s.group[d.ke][d.id].buffer; + }else{ + s.detectObject(s.group[d.ke][d.id].buffer,d,tx) + } + } + s.group[d.ke][d.id].buffer=null; + } + }catch(err){ + if(err){ + s.systemLog(err) + delete(s.group[d.ke][d.id].buffer) + } + } + break; + } +} +server.listen(config.hostPort); +//web pages and plugin api +app.get('/', function (req, res) { + res.end(''+config.plug+' for Shinobi is running') +}); +//Conector to Shinobi +if(config.mode==='host'){ + //start plugin as host + var io = require('socket.io')(server); + io.attach(server); + s.connectedClients={}; + io.on('connection', function (cn) { + s.connectedClients[cn.id]={id:cn.id} + s.connectedClients[cn.id].tx = function(data){ + data.pluginKey=config.key;data.plug=config.plug; + return io.to(cn.id).emit('ocv',data); + } + cn.on('f',function(d){ + s.MainEventController(d,cn,s.connectedClients[cn.id].tx) + }); + cn.on('disconnect',function(d){ + delete(s.connectedClients[cn.id]) + }) + }); +}else{ + //start plugin as client + if(!config.host){config.host='localhost'} + var io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master + s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} + io.on('connect',function(d){ + s.cx({f:'init',plug:config.plug,notice:config.notice,type:config.type}); + }) + io.on('disconnect',function(d){ + io.connect(); + }) + io.on('f',function(d){ + s.MainEventController(d,null,s.cx) + }) +} \ No newline at end of file diff --git a/plugins/opencv/INSTALL.sh b/plugins/opencv/INSTALL.sh new file mode 100644 index 0000000..cab6113 --- /dev/null +++ b/plugins/opencv/INSTALL.sh @@ -0,0 +1,15 @@ +#!/bin/bash +if [ $(dpkg-query -W -f='${Status}' opencv_version 2>/dev/null | grep -c "ok installed") -eq 0 ]; then + echo "Shinobi - Do ypu want to let the `opencv4nodejs` npm package install OpenCV? " + echo "Only do this if you do not have OpenCV already or will not use a GPU (Hardware Acceleration)." + echo "(y)es or (N)o" + read nodejsinstall + if [ "$nodejsinstall" = "y" ] || [ "$nodejsinstall" = "Y" ]; then + export OPENCV4NODEJS_DISABLE_AUTOBUILD=0 + else + export OPENCV4NODEJS_DISABLE_AUTOBUILD=1 + fi +else + export OPENCV4NODEJS_DISABLE_AUTOBUILD=1 +fi +npm install opencv4nodejs moment express canvas@1.6 --unsafe-perm \ No newline at end of file diff --git a/plugins/opencv/conf.sample.json b/plugins/opencv/conf.sample.json new file mode 100644 index 0000000..1a4b8dc --- /dev/null +++ b/plugins/opencv/conf.sample.json @@ -0,0 +1,9 @@ +{ + "plug":"OpenCV", + "host":"localhost", + "port":8080, + "hostPort":8082, + "key":"change_this_to_something_very_random____make_sure_to_match__/plugins/opencv/conf.json", + "mode":"client", + "type":"detector" +} \ No newline at end of file diff --git a/plugins/opencv/openalpr.conf b/plugins/opencv/openalpr.conf new file mode 100644 index 0000000..070752b --- /dev/null +++ b/plugins/opencv/openalpr.conf @@ -0,0 +1,94 @@ + +; Specify the path to the runtime data directory +runtime_dir = ${CMAKE_INSTALL_PREFIX}/share/openalpr/runtime_data + + +ocr_img_size_percent = 1.33333333 +state_id_img_size_percent = 2.0 + +; Calibrating your camera improves detection accuracy in cases where vehicle plates are captured at a steep angle +; Use the openalpr-utils-calibrate utility to calibrate your fixed camera to adjust for an angle +; Once done, update the prewarp config with the values obtained from the tool +prewarp = + +; detection will ignore plates that are too large. This is a good efficiency technique to use if the +; plates are going to be a fixed distance away from the camera (e.g., you will never see plates that fill +; up the entire image +max_plate_width_percent = 100 +max_plate_height_percent = 100 + +; detection_iteration_increase is the percentage that the LBP frame increases each iteration. +; It must be greater than 1.0. A value of 1.01 means increase by 1%, 1.10 increases it by 10% each time. +; So a 1% increase would be ~10x slower than 10% to process, but it has a higher chance of landing +; directly on the plate and getting a strong detection +detection_iteration_increase = 1.1 + +; The minimum detection strength determines how sure the detection algorithm must be before signaling that +; a plate region exists. Technically this corresponds to LBP nearest neighbors (e.g., how many detections +; are clustered around the same area). For example, 2 = very lenient, 9 = very strict. +detection_strictness = 3 + +; The detection doesn't necessarily need an extremely high resolution image in order to detect plates +; Using a smaller input image should still find the plates and will do it faster +; Tweaking the max_detection_input values will resize the input image if it is larger than these sizes +; max_detection_input_width/height are specified in pixels +max_detection_input_width = 1280 +max_detection_input_height = 720 + +; detector is the technique used to find license plate regions in an image. Value can be set to +; lbpcpu - default LBP-based detector uses the system CPU +; lbpgpu - LBP-based detector that uses Nvidia GPU to increase recognition speed. +; lbpopencl - LBP-based detector that uses OpenCL GPU to increase recognition speed. Requires OpenCV 3.0 +; morphcpu - Experimental detector that detects white rectangles in an image. Does not require training. +detector = lbpgpu + +; If set to true, all results must match a postprocess text pattern if a pattern is available. +; If not, the result is disqualified. +must_match_pattern = 0 + +; Bypasses plate detection. If this is set to 1, the library assumes that each region provided is a likely plate area. +skip_detection = 0 + +; Specifies the full path to an image file that constrains the detection area. Only the plate regions allowed through the mask +; will be analyzed. The mask image must match the resolution of your image to be analyzed. The mask is black and white. +; Black areas will be ignored, white areas will be searched. An empty value means no mask (scan the entire image) +detection_mask_image = + +; OpenALPR can scan the same image multiple times with different randomization. Setting this to a value larger than +; 1 may increase accuracy, but will increase processing time linearly (e.g., analysis_count = 3 is 3x slower) +analysis_count = 1 + +; OpenALPR detects high-contrast plate crops and uses an alternative edge detection technique. Setting this to 0.0 +; would classify ALL images as high-contrast, setting it to 1.0 would classify no images as high-contrast. +contrast_detection_threshold = 0.3 + +max_plate_angle_degrees = 15 + +ocr_min_font_point = 6 + +; Minimum OCR confidence percent to consider. +postprocess_min_confidence = 65 + +; Any OCR character lower than this will also add an equally likely +; chance that the character is incorrect and will be skipped. Value is a confidence percent +postprocess_confidence_skip_level = 80 + + +debug_general = 0 +debug_timing = 0 +debug_detector = 0 +debug_prewarp = 0 +debug_state_id = 0 +debug_plate_lines = 0 +debug_plate_corners = 0 +debug_char_segment = 0 +debug_char_analysis = 0 +debug_color_filter = 0 +debug_ocr = 0 +debug_postprocess = 0 +debug_show_images = 0 +debug_pause_on_frame = 0 + + + + diff --git a/plugins/opencv/shinobi-opencv.js b/plugins/opencv/shinobi-opencv.js new file mode 100644 index 0000000..f51c46e --- /dev/null +++ b/plugins/opencv/shinobi-opencv.js @@ -0,0 +1,465 @@ +// +// Shinobi - OpenCV Plugin +// Copyright (C) 2016-2025 Moe Alam, moeiscool +// +// # Donate +// +// If you like what I am doing here and want me to continue please consider donating :) +// PayPal : paypal@m03.ca +// +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +var fs=require('fs'); +var cv=require('opencv4nodejs'); +var exec = require('child_process').exec; +var moment = require('moment'); +var Canvas = require('canvas'); +var express = require('express'); +var http = require('http'), + app = express(), + server = http.createServer(app); +var config=require('./conf.json'); +if(!config.port){config.port=8080} +if(!config.hostPort){config.hostPort=8082} +if(config.systemLog===undefined){config.systemLog=true} +if(config.cascadesDir===undefined){config.cascadesDir=__dirname+'/cascades/'} +if(config.alprConfig===undefined){config.alprConfig=__dirname+'/openalpr.conf'} +s={ + group:{}, + dir:{ + cascades : config.cascadesDir + }, + isWin:(process.platform==='win32'), + foundCascades : { + + } +} +//default stream folder check +if(!config.streamDir){ + if(s.isWin===false){ + config.streamDir='/dev/shm' + }else{ + config.streamDir=config.windowsTempDir + } + if(!fs.existsSync(config.streamDir)){ + config.streamDir=__dirname+'/streams/' + }else{ + config.streamDir+='/streams/' + } +} +s.dir.streams=config.streamDir; +//streams dir +if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); +} +//streams dir +if(!fs.existsSync(s.dir.cascades)){ + fs.mkdirSync(s.dir.cascades); +} +s.gid=function(x){ + if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.findCascades=function(callback){ + var tmp={}; + tmp.foundCascades=[]; + fs.readdir(s.dir.cascades,function(err,files){ + files.forEach(function(cascade,n){ + if(cascade.indexOf('.xml')>-1){ + tmp.foundCascades.push(cascade.replace('.xml','')) + } + }) + s.cascadesInDir=tmp.foundCascades; + callback(tmp.foundCascades) + }) +} +s.findCascades(function(){ + //get cascades +}) +s.detectLicensePlate=function(buffer,d,tx){ + if(!d.mon.detector_lisence_plate_country||d.mon.detector_lisence_plate_country===''){ + d.mon.detector_lisence_plate_country='us' + } + d.tmpFile=s.gid(5)+'.jpg' + if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); + } + d.dir=s.dir.streams+d.ke+'/' + if(!fs.existsSync(d.dir)){ + fs.mkdirSync(d.dir); + } + d.dir=s.dir.streams+d.ke+'/'+d.id+'/' + if(!fs.existsSync(d.dir)){ + fs.mkdirSync(d.dir); + } + fs.writeFile(d.dir+d.tmpFile,buffer,function(err){ + if(err) return s.systemLog(err); + exec('alpr -j --config '+config.alprConfig+' -c '+d.mon.detector_lisence_plate_country+' '+d.dir+d.tmpFile,{encoding:'utf8'},(err, scan, stderr) => { + if(err){ + s.systemLog(err); + }else{ + try{ + scan=JSON.parse(scan.replace('--(!)Loaded CUDA classifier','').trim()) + }catch(err){ + if(!scan||!scan.results){ + return s.systemLog(scan,err); + } + } + if(scan.results.length>0){ + scan.plates=[] + scan.mats=[] + scan.results.forEach(function(v){ + v.candidates.forEach(function(g,n){ + if(v.candidates[n].matches_template) + delete(v.candidates[n].matches_template) + }) + scan.plates.push({coordinates:v.coordinates,candidates:v.candidates,confidence:v.confidence,plate:v.plate}) + var width = Math.sqrt( Math.pow(v.coordinates[1].x - v.coordinates[0].x, 2) + Math.pow(v.coordinates[1].y - v.coordinates[0].y, 2)); + var height = Math.sqrt( Math.pow(v.coordinates[2].x - v.coordinates[1].x, 2) + Math.pow(v.coordinates[2].y - v.coordinates[1].y, 2)) + scan.mats.push({ + x:v.coordinates[0].x, + y:v.coordinates[0].y, + width:width, + height:height, + tag:v.plate + }) + }) + tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:'licensePlate',reason:'object',matrices:scan.mats,imgHeight:d.mon.detector_scale_y,imgWidth:d.mon.detector_scale_x,frame:d.base64}}) + } + } + exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'}) + }) + }) +} +s.detectObject=function(buffer,d,tx){ + //detect license plate? + if(d.mon.detector_lisence_plate==="1"){ + s.detectLicensePlate(buffer,d,tx) + } + //check selected opencv cascades + if(!d.mon.detector_cascades || d.mon.detector_cascades === '')return; + var selectedCascades = Object.keys(d.mon.detector_cascades); + if(selectedCascades.length > 0){ + cv.imdecodeAsync(buffer,(err,im) => { + if(err){ + console.log(err) + return + } + selectedCascades.forEach(function(cascade){ + var cascadePath = s.dir.cascades+cascade+'.xml' + if(s.foundCascades[cascadePath] === undefined){ + s.foundCascades[cascadePath] = fs.existsSync(cascadePath) + }else if(s.foundCascades[cascadePath] === false){ + return s.systemLog('Attempted to use non existant cascade. : '+cascadePath) + } + var classifier = new cv.CascadeClassifier(cascadePath) + var matrices = classifier.detectMultiScaleGpu(im).objects + if(matrices.length > 0){ + matrices.forEach(function(v,n){ + v.centerX=v.width/2 + v.centerY=v.height/2 + v.centerXnoParent=v.x+(v.width/2) + v.centerYnoParent=v.y+(v.height/2) + }) + s.cx({ + f:'trigger', + id:d.id, + ke:d.ke, + name:cascade, + details:{ + plug:'built-in-opencv', + name:cascade, + reason:'object', + matrices : matrices, + confidence:d.average + }, + imgHeight:d.mon.detector_scale_y, + imgWidth:d.mon.detector_scale_x + }) + } + }) + }); + } +} +s.systemLog=function(q,w,e){ + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + return console.log(moment().format(),q,w,e) + } +} + +s.blenderRegion=function(d,cord,tx){ + d.width = d.image.width; + d.height = d.image.height; + if(!s.group[d.ke][d.id].canvas[cord.name]){ + if(!cord.sensitivity||isNaN(cord.sensitivity)){ + cord.sensitivity=d.mon.detector_sensitivity; + } + s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height); + s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d'); + s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#000'; + s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height); + if(cord.points&&cord.points.length>0){ + s.group[d.ke][d.id].canvasContext[cord.name].beginPath(); + for (var b = 0; b < cord.points.length; b++){ + cord.points[b][0]=parseFloat(cord.points[b][0]); + cord.points[b][1]=parseFloat(cord.points[b][1]); + if(b===0){ + s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]); + }else{ + s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]); + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clip(); + } + } + if(!s.group[d.ke][d.id].canvasContext[cord.name]){ + return + } + s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height); + if(!s.group[d.ke][d.id].blendRegion[cord.name]){ + s.group[d.ke][d.id].blendRegion[cord.name] = new Canvas(d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name] = s.group[d.ke][d.id].blendRegion[cord.name].getContext('2d'); + } + var sourceData = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create an image if the previous image doesn�t exist + if (!s.group[d.ke][d.id].lastRegionImageData[cord.name]) s.group[d.ke][d.id].lastRegionImageData[cord.name] = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create a ImageData instance to receive the blended result + var blendedData = s.group[d.ke][d.id].canvasContext[cord.name].createImageData(d.width, d.height); + // blend the 2 images + s.differenceAccuracy(blendedData.data,sourceData.data,s.group[d.ke][d.id].lastRegionImageData[cord.name].data); + // draw the result in a canvas + s.group[d.ke][d.id].blendRegionContext[cord.name].putImageData(blendedData, 0, 0); + // store the current webcam image + s.group[d.ke][d.id].lastRegionImageData[cord.name] = sourceData; + blendedData = s.group[d.ke][d.id].blendRegionContext[cord.name].getImageData(0, 0, d.width, d.height); + var i = 0; + d.average = 0; + while (i < (blendedData.data.length * 0.25)) { + d.average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]); + ++i; + } + d.average = (d.average / (blendedData.data.length * 0.25))*10; + if (d.average > parseFloat(cord.sensitivity)){ + if(d.mon.detector_use_detect_object==="1"&&d.mon.detector_second!=='1'){ + var buffer=s.group[d.ke][d.id].canvas[cord.name].toBuffer(); + s.detectObject(buffer,d,tx) + }else{ + tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:cord.name,reason:'motion',confidence:d.average,frame:d.base64}}) + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name].clearRect(0, 0, d.width, d.height); +} +function blobToBuffer (blob, cb) { + if (typeof Blob === 'undefined' || !(blob instanceof Blob)) { + throw new Error('first argument must be a Blob') + } + if (typeof cb !== 'function') { + throw new Error('second argument must be a function') + } + + var reader = new FileReader() + + function onLoadEnd (e) { + reader.removeEventListener('loadend', onLoadEnd, false) + if (e.error) cb(e.error) + else cb(null, Buffer.from(reader.result)) + } + + reader.addEventListener('loadend', onLoadEnd, false) + reader.readAsArrayBuffer(blob) +} +function fastAbs(value) { + return (value ^ (value >> 31)) - (value >> 31); +} + +function threshold(value) { + return (value > 0x15) ? 0xFF : 0; +} +s.differenceAccuracy=function(target, data1, data2) { + if (data1.length != data2.length) return null; + var i = 0; + while (i < (data1.length * 0.25)) { + var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3; + var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3; + var diff = threshold(fastAbs(average1 - average2)); + target[4 * i] = diff; + target[4 * i + 1] = diff; + target[4 * i + 2] = diff; + target[4 * i + 3] = 0xFF; + ++i; + } +} +s.checkAreas=function(d,tx){ + if(!s.group[d.ke][d.id].cords){ + if(!d.mon.cords){d.mon.cords={}} + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + } + if(d.mon.detector_frame==='1'){ + d.mon.cords.frame={name:'FULL_FRAME',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; + s.group[d.ke][d.id].cords.push(d.mon.cords.frame); + } + for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){ + if(!s.group[d.ke][d.id].cords[b]){return} + s.blenderRegion(d,s.group[d.ke][d.id].cords[b],tx) + } + delete(d.image) +} + +s.MainEventController=function(d,cn,tx){ + switch(d.f){ + case'refreshPlugins': + s.findCascades(function(cascades){ + s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:cascades},to:'GRP_'+d.ke}) + }) + break; + case'readPlugins': + s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:s.cascadesInDir},to:'GRP_'+d.ke}) + break; + case'init_plugin_as_host': + if(!cn){ + console.log('No CN',d) + return + } + if(d.key!==config.key){ + console.log(new Date(),'Plugin Key Mismatch',cn.request.connection.remoteAddress,d) + cn.emit('init',{ok:false}) + cn.disconnect() + }else{ + console.log(new Date(),'Plugin Connected to Client',cn.request.connection.remoteAddress) + cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type}) + } + break; + case'init_monitor': + if(s.group[d.ke]&&s.group[d.ke][d.id]){ + s.group[d.ke][d.id].canvas={} + s.group[d.ke][d.id].canvasContext={} + s.group[d.ke][d.id].blendRegion={} + s.group[d.ke][d.id].blendRegionContext={} + s.group[d.ke][d.id].lastRegionImageData={} + s.group[d.ke][d.id].numberOfTriggers=0 + delete(s.group[d.ke][d.id].cords) + delete(s.group[d.ke][d.id].buffer) + } + break; + case'init_aws_push': +// console.log('init_aws') + s.group[d.ke][d.id].aws={links:[],complete:0,total:d.total,videos:[],tx:tx} + break; + case'frame': + try{ + if(!s.group[d.ke]){ + s.group[d.ke]={} + } + if(!s.group[d.ke][d.id]){ + s.group[d.ke][d.id]={ + canvas:{}, + canvasContext:{}, + lastRegionImageData:{}, + blendRegion:{}, + blendRegionContext:{}, + } + } + if(!s.group[d.ke][d.id].buffer){ + s.group[d.ke][d.id].buffer=[d.frame]; + }else{ + s.group[d.ke][d.id].buffer.push(d.frame) + } + if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ + s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer); + try{ + d.mon.detector_cascades=JSON.parse(d.mon.detector_cascades) + }catch(err){ + + } + if(d.mon.detector_frame_save==="1"){ + d.base64=s.group[d.ke][d.id].buffer.toString('base64') + } + if(d.mon.detector_second==='1'&&d.objectOnly===true){ + s.detectObject(s.group[d.ke][d.id].buffer,d,tx) + }else{ + if((d.mon.detector_pam !== '1' && d.mon.detector_use_motion === "1") || d.mon.detector_use_detect_object !== "1"){ + if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){ + d.mon.cords=[] + }else{ + try{ + d.mon.cords=JSON.parse(d.mon.cords) + }catch(err){ + // console.log('d.mon.cords',err,d) + } + } + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + d.mon.cords=d.mon.cords; + d.image = new Canvas.Image; + if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){ + s.systemLog('Must set detector image size') + return + }else{ + d.image.width=d.mon.detector_scale_x; + d.image.height=d.mon.detector_scale_y; + } + d.width=d.image.width; + d.height=d.image.height; + d.image.onload = function() { + s.checkAreas(d,tx); + } + d.image.src = s.group[d.ke][d.id].buffer; + }else{ + s.detectObject(s.group[d.ke][d.id].buffer,d,tx) + } + } + s.group[d.ke][d.id].buffer=null; + } + }catch(err){ + if(err){ + s.systemLog(err) + delete(s.group[d.ke][d.id].buffer) + } + } + break; + } +} +server.listen(config.hostPort); +//web pages and plugin api +app.get('/', function (req, res) { + res.end(''+config.plug+' for Shinobi is running') +}); +//Conector to Shinobi +if(config.mode==='host'){ + //start plugin as host + var io = require('socket.io')(server); + io.attach(server); + s.connectedClients={}; + io.on('connection', function (cn) { + s.connectedClients[cn.id]={id:cn.id} + s.connectedClients[cn.id].tx = function(data){ + data.pluginKey=config.key;data.plug=config.plug; + return io.to(cn.id).emit('ocv',data); + } + cn.on('f',function(d){ + s.MainEventController(d,cn,s.connectedClients[cn.id].tx) + }); + cn.on('disconnect',function(d){ + delete(s.connectedClients[cn.id]) + }) + }); +}else{ + //start plugin as client + if(!config.host){config.host='localhost'} + var io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master + s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} + io.on('connect',function(d){ + s.cx({f:'init',plug:config.plug,notice:config.notice,type:config.type}); + }) + io.on('disconnect',function(d){ + io.connect(); + }) + io.on('f',function(d){ + s.MainEventController(d,null,s.cx) + }) +} \ No newline at end of file diff --git a/sql/.gitignore b/sql/.gitignore new file mode 100644 index 0000000..87b2844 --- /dev/null +++ b/sql/.gitignore @@ -0,0 +1,2 @@ +monitors.sql +users.sql \ No newline at end of file diff --git a/sql/default_data.sql b/sql/default_data.sql new file mode 100644 index 0000000..5a66924 --- /dev/null +++ b/sql/default_data.sql @@ -0,0 +1,20 @@ +-- -------------------------------------------------------- +-- Host: 66.51.132.100 +-- Server version: 5.7.16-0ubuntu0.16.04.1 - (Ubuntu) +-- Server OS: Linux +-- HeidiSQL Version: 9.3.0.4984 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +-- Dumping data for table ccio.Users: ~0 rows (approximately) +/*!40000 ALTER TABLE `Users` DISABLE KEYS */; +INSERT INTO `Users` (`ke`, `uid`, `auth`, `mail`, `pass`, `details`) VALUES + ('2Df5hBE', 'XDf5hB3', 'ec49f05c1ddc7d818c61b3343c98cbc6', 'ccio@m03.ca', '5f4dcc3b5aa765d61d8327deb882cf99', '{"days":"10"}'); +INSERT INTO `Monitors` (`mid`, `ke`, `name`, `shto`, `shfr`, `details`, `type`, `ext`, `protocol`, `host`, `path`, `port`, `fps`, `mode`, `width`, `height`) VALUES ('bunny', '2Df5hBE', 'Bunny', '[]', '[]', '{"fatal_max":"","notes":"","dir":"","rtsp_transport":"tcp","muser":"","mpass":"","port_force":"0","sfps":"","aduration":"1000000","probesize":"1000000","accelerator":"0","hwaccel":null,"hwaccel_vcodec":"","hwaccel_device":"","stream_type":"hls","stream_mjpeg_clients":"","stream_vcodec":"copy","stream_acodec":"no","hls_time":"","preset_stream":"","hls_list_size":"","signal_check":"","signal_check_log":null,"stream_quality":"","stream_fps":"1","stream_scale_x":"","stream_scale_y":"","rotate_stream":null,"svf":"","stream_timestamp":"0","stream_timestamp_font":"","stream_timestamp_font_size":"","stream_timestamp_color":"","stream_timestamp_box_color":"","stream_timestamp_x":"","stream_timestamp_y":"","stream_watermark":"0","stream_watermark_location":"","stream_watermark_position":null,"snap":"1","snap_fps":"","snap_scale_x":"","snap_scale_y":"","snap_vf":"","vcodec":"copy","crf":"","preset_record":"","acodec":"libvorbis","dqf":null,"cutoff":"10","rotate_record":null,"vf":"","timestamp":"1","timestamp_font":"","timestamp_font_size":"","timestamp_color":"","timestamp_box_color":"","timestamp_x":"","timestamp_y":"","watermark":null,"watermark_location":"","watermark_position":null,"cust_input":"","cust_snap":"","cust_detect":"","cust_stream":"","cust_stream_server":"","cust_record":"","custom_output":"","detector":"0","detector_webhook":null,"detector_webhook_url":"","detector_command_enable":null,"detector_command":"","detector_command_timeout":"","detector_lock_timeout":"","detector_save":null,"detector_frame_save":null,"detector_mail":null,"detector_mail_timeout":"","detector_record_method":null,"detector_trigger":null,"detector_trigger_record_fps":"","detector_timeout":"","watchdog_reset":null,"detector_delete_motionless_videos":null,"detector_send_frames":null,"detector_fps":"","detector_scale_x":"","detector_scale_y":"","detector_use_motion":null,"detector_use_detect_object":null,"detector_frame":null,"detector_sensitivity":"","cords":"","detector_lisence_plate":null,"detector_lisence_plate_country":null,"detector_notrigger":null,"detector_notrigger_mail":null,"detector_notrigger_timeout":"","control":"0","control_base_url":"","control_stop":null,"control_url_stop_timeout":"","control_url_center":"","control_url_left":"","control_url_left_stop":"","control_url_right":"","control_url_right_stop":"","control_url_up":"","control_url_up_stop":"","control_url_down":"","control_url_down_stop":"","control_url_enable_nv":"","control_url_disable_nv":"","control_url_zoom_out":"","control_url_zoom_out_stop":"","control_url_zoom_in":"","control_url_zoom_in_stop":"","groups":"","loglevel":"warning","sqllog":"0","detector_cascades":""}', 'mjpeg', 'mp4', 'http', 'came3.nkansai.ne.jp', '/nphMotionJpeg?Resolution=640x480&Quality=Motion', 81, 15, 'start', 640, 480); +/*!40000 ALTER TABLE `Users` ENABLE KEYS */; +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/docker/01-framework.sql b/sql/docker/01-framework.sql new file mode 100644 index 0000000..cec2dda --- /dev/null +++ b/sql/docker/01-framework.sql @@ -0,0 +1,113 @@ +-- -------------------------------------------------------- +-- Host: 192.168.88.58 +-- Server version: 5.7.17-0ubuntu0.16.04.1 - (Ubuntu) +-- Server OS: Linux +-- HeidiSQL Version: 9.3.0.4984 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; + +-- Dumping structure for table ccio.API +CREATE TABLE IF NOT EXISTS `API` ( + `ke` varchar(50) DEFAULT NULL, + `uid` varchar(50) DEFAULT NULL, + `ip` tinytext, + `code` varchar(100) DEFAULT NULL, + `details` text, + `time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. + + +-- Dumping structure for table ccio.Events +CREATE TABLE IF NOT EXISTS `Events` ( + `ke` varchar(50) DEFAULT NULL, + `mid` varchar(50) DEFAULT NULL, + `details` text, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +-- Data exporting was unselected. + + +-- Dumping structure for table ccio.Logs +CREATE TABLE IF NOT EXISTS `Logs` ( + `ke` varchar(50) DEFAULT NULL, + `mid` varchar(50) DEFAULT NULL, + `info` text, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. + + +-- Dumping structure for table ccio.Monitors +CREATE TABLE IF NOT EXISTS `Monitors` ( + `mid` varchar(50) DEFAULT NULL, + `ke` varchar(50) DEFAULT NULL, + `name` varchar(50) DEFAULT NULL, + `shto` text, + `shfr` text, + `details` longtext, + `type` varchar(50) DEFAULT 'jpeg', + `ext` varchar(50) DEFAULT 'webm', + `protocol` varchar(50) DEFAULT 'http', + `host` varchar(100) DEFAULT '0.0.0.0', + `path` varchar(100) DEFAULT '/', + `port` int(8) DEFAULT '80', + `fps` int(8) DEFAULT '1', + `mode` varchar(15) DEFAULT NULL, + `width` int(11) DEFAULT '640', + `height` int(11) DEFAULT '360' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. + + +-- Dumping structure for table ccio.Presets +CREATE TABLE IF NOT EXISTS `Presets` ( + `ke` varchar(50) DEFAULT NULL, + `name` text, + `details` text, + `type` enum('monitor','event','user') DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. + + +-- Dumping structure for table ccio.Users +CREATE TABLE IF NOT EXISTS `Users` ( + `ke` varchar(50) DEFAULT NULL, + `uid` varchar(50) DEFAULT NULL, + `auth` varchar(50) DEFAULT NULL, + `mail` varchar(100) DEFAULT NULL, + `pass` varchar(100) DEFAULT NULL, + `details` longtext, + UNIQUE KEY `mail` (`mail`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. + + +-- Dumping structure for table ccio.Videos +CREATE TABLE IF NOT EXISTS `Videos` ( + `mid` varchar(50) DEFAULT NULL, + `ke` varchar(50) DEFAULT NULL, + `ext` enum('webm','mp4') DEFAULT NULL, + `time` timestamp NULL DEFAULT NULL, + `duration` float DEFAULT NULL, + `size` float DEFAULT NULL, + `frames` int(11) DEFAULT NULL, + `end` timestamp NULL DEFAULT NULL, + `status` int(1) DEFAULT '0' COMMENT '0:Building,1:Complete,2:Read,3:Archive', + `details` text +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/framework.sql b/sql/framework.sql new file mode 100644 index 0000000..4961e54 --- /dev/null +++ b/sql/framework.sql @@ -0,0 +1,107 @@ +-- -------------------------------------------------------- +-- Host: 192.168.88.37 +-- Server version: 10.1.25-MariaDB- - Ubuntu 17.04 +-- Server OS: debian-linux-gnu +-- HeidiSQL Version: 9.4.0.5125 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8 */; +/*!50503 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; + + +-- Dumping database structure for ccio +CREATE DATABASE IF NOT EXISTS `ccio` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; +USE `ccio`; + +-- Dumping structure for table ccio.API +CREATE TABLE IF NOT EXISTS `API` ( + `ke` varchar(50) DEFAULT NULL, + `uid` varchar(50) DEFAULT NULL, + `ip` tinytext, + `code` varchar(100) DEFAULT NULL, + `details` text, + `time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Events +CREATE TABLE IF NOT EXISTS `Events` ( + `ke` varchar(50) DEFAULT NULL, + `mid` varchar(50) DEFAULT NULL, + `details` text, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Logs +CREATE TABLE IF NOT EXISTS `Logs` ( + `ke` varchar(50) DEFAULT NULL, + `mid` varchar(50) DEFAULT NULL, + `info` text, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Monitors +CREATE TABLE IF NOT EXISTS `Monitors` ( + `mid` varchar(50) DEFAULT NULL, + `ke` varchar(50) DEFAULT NULL, + `name` varchar(50) DEFAULT NULL, + `shto` text, + `shfr` text, + `details` longtext, + `type` varchar(50) DEFAULT 'jpeg', + `ext` varchar(50) DEFAULT 'webm', + `protocol` varchar(50) DEFAULT 'http', + `host` varchar(100) DEFAULT '0.0.0.0', + `path` varchar(100) DEFAULT '/', + `port` int(8) DEFAULT '80', + `fps` int(8) DEFAULT '1', + `mode` varchar(15) DEFAULT NULL, + `width` int(11) DEFAULT '640', + `height` int(11) DEFAULT '360' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Presets +CREATE TABLE IF NOT EXISTS `Presets` ( + `ke` varchar(50) DEFAULT NULL, + `name` text, + `details` text, + `type` enum('monitor','event','user') DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Users +CREATE TABLE IF NOT EXISTS `Users` ( + `ke` varchar(50) DEFAULT NULL, + `uid` varchar(50) DEFAULT NULL, + `auth` varchar(50) DEFAULT NULL, + `mail` varchar(100) DEFAULT NULL, + `pass` varchar(100) DEFAULT NULL, + `details` longtext, + UNIQUE KEY `mail` (`mail`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Videos +CREATE TABLE IF NOT EXISTS `Videos` ( + `mid` varchar(50) DEFAULT NULL, + `ke` varchar(50) DEFAULT NULL, + `ext` enum('webm','mp4') DEFAULT NULL, + `time` timestamp NULL DEFAULT NULL, + `duration` float DEFAULT NULL, + `size` float DEFAULT NULL, + `frames` int(11) DEFAULT NULL, + `end` timestamp NULL DEFAULT NULL, + `status` int(1) DEFAULT '0' COMMENT '0:Building,1:Complete,2:Read,3:Archive', + `details` text +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/mssql/default_data.sql b/sql/mssql/default_data.sql new file mode 100644 index 0000000..e3dae9e --- /dev/null +++ b/sql/mssql/default_data.sql @@ -0,0 +1,20 @@ +-- -------------------------------------------------------- +-- Host: 66.51.132.100 +-- Server version: 5.7.16-0ubuntu0.16.04.1 - (Ubuntu) +-- Server OS: Linux +-- HeidiSQL Version: 9.3.0.4984 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +-- Dumping data for table ccio.Users: ~0 rows (approximately) +/*!40000 ALTER TABLE `Users` DISABLE KEYS */; +INSERT INTO Users ([ke], [uid], [auth], [mail], [pass], [details]) VALUES + ('2Df5hBE', 'XDf5hB3', 'ec49f05c1ddc7d818c61b3343c98cbc6', 'ccio@m03.ca', '5f4dcc3b5aa765d61d8327deb882cf99', '{"days":"10"}'); +INSERT INTO Monitors ([mid], [ke], [name], [shto], [shfr], [details], [type], [ext], [protocol], [host], [path], [port], [fps], [mode], [width], [height]) VALUES ('bunny', '2Df5hBE', 'Bunny', '[]', '[]', '{"fatal_max":"","notes":"","dir":"","rtsp_transport":"tcp","muser":"","mpass":"","port_force":"0","sfps":"","aduration":"1000000","probesize":"1000000","accelerator":"0","hwaccel":null,"hwaccel_vcodec":"","hwaccel_device":"","stream_type":"hls","stream_mjpeg_clients":"","stream_vcodec":"copy","stream_acodec":"no","hls_time":"","preset_stream":"","hls_list_size":"","signal_check":"","signal_check_log":null,"stream_quality":"","stream_fps":"1","stream_scale_x":"","stream_scale_y":"","rotate_stream":null,"svf":"","stream_timestamp":"0","stream_timestamp_font":"","stream_timestamp_font_size":"","stream_timestamp_color":"","stream_timestamp_box_color":"","stream_timestamp_x":"","stream_timestamp_y":"","stream_watermark":"0","stream_watermark_location":"","stream_watermark_position":null,"snap":"1","snap_fps":"","snap_scale_x":"","snap_scale_y":"","snap_vf":"","vcodec":"copy","crf":"","preset_record":"","acodec":"libvorbis","dqf":null,"cutoff":"10","rotate_record":null,"vf":"","timestamp":"1","timestamp_font":"","timestamp_font_size":"","timestamp_color":"","timestamp_box_color":"","timestamp_x":"","timestamp_y":"","watermark":null,"watermark_location":"","watermark_position":null,"cust_input":"","cust_snap":"","cust_detect":"","cust_stream":"","cust_stream_server":"","cust_record":"","custom_output":"","detector":"0","detector_webhook":null,"detector_webhook_url":"","detector_command_enable":null,"detector_command":"","detector_command_timeout":"","detector_lock_timeout":"","detector_save":null,"detector_frame_save":null,"detector_mail":null,"detector_mail_timeout":"","detector_record_method":null,"detector_trigger":null,"detector_trigger_record_fps":"","detector_timeout":"","watchdog_reset":null,"detector_delete_motionless_videos":null,"detector_send_frames":null,"detector_fps":"","detector_scale_x":"","detector_scale_y":"","detector_use_motion":null,"detector_use_detect_object":null,"detector_frame":null,"detector_sensitivity":"","cords":"","detector_lisence_plate":null,"detector_lisence_plate_country":null,"detector_notrigger":null,"detector_notrigger_mail":null,"detector_notrigger_timeout":"","control":"0","control_base_url":"","control_stop":null,"control_url_stop_timeout":"","control_url_center":"","control_url_left":"","control_url_left_stop":"","control_url_right":"","control_url_right_stop":"","control_url_up":"","control_url_up_stop":"","control_url_down":"","control_url_down_stop":"","control_url_enable_nv":"","control_url_disable_nv":"","control_url_zoom_out":"","control_url_zoom_out_stop":"","control_url_zoom_in":"","control_url_zoom_in_stop":"","groups":"","loglevel":"warning","sqllog":"0","detector_cascades":""}', 'mjpeg', 'mp4', 'http', 'came3.nkansai.ne.jp', '/nphMotionJpeg?Resolution=640x480&Quality=Motion', 81, 15, 'start', 640, 480); +/*!40000 ALTER TABLE `Users` ENABLE KEYS */; +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/mssql/framework.sql b/sql/mssql/framework.sql new file mode 100644 index 0000000..d066cce --- /dev/null +++ b/sql/mssql/framework.sql @@ -0,0 +1,107 @@ +-- -------------------------------------------------------- +-- Host: 192.168.88.37 +-- Server version: 10.1.25-MariaDB- - Ubuntu 17.04 +-- Server OS: debian-linux-gnu +-- HeidiSQL Version: 9.4.0.5125 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8 */; +/*!50503 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; + + +-- Dumping database structure for ccio +CREATE DATABASE `ccio` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; +USE ccio; + +-- Dumping structure for table ccio.API +CREATE TABLE API ( + ke varchar(50) DEFAULT NULL, + uid varchar(50) DEFAULT NULL, + ip varchar(255), + code varchar(100) DEFAULT NULL, + details varchar(max), + time datetime2(0) NULL DEFAULT GETDATE() +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Events +CREATE TABLE Events ( + ke varchar(50) DEFAULT NULL, + mid varchar(50) DEFAULT NULL, + details varchar(max), + time datetime2(0) NOT NULL DEFAULT GETDATE() +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Logs +CREATE TABLE Logs ( + ke varchar(50) DEFAULT NULL, + mid varchar(50) DEFAULT NULL, + info varchar(max), + time datetime2(0) NOT NULL DEFAULT GETDATE() +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Monitors +CREATE TABLE Monitors ( + mid varchar(50) DEFAULT NULL, + ke varchar(50) DEFAULT NULL, + name varchar(50) DEFAULT NULL, + shto varchar(max), + shfr varchar(max), + details varchar(max), + type varchar(50) DEFAULT 'jpeg', + ext varchar(50) DEFAULT 'webm', + protocol varchar(50) DEFAULT 'http', + host varchar(100) DEFAULT '0.0.0.0', + path varchar(100) DEFAULT '/', + port int DEFAULT '80', + fps int DEFAULT '1', + mode varchar(15) DEFAULT NULL, + width int DEFAULT '640', + height int DEFAULT '360' +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Presets +CREATE TABLE Presets ( + ke varchar(50) DEFAULT NULL, + name varchar(max), + details varchar(max), + type enum('monitor','event','user') DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Users +CREATE TABLE Users ( + ke varchar(50) DEFAULT NULL, + uid varchar(50) DEFAULT NULL, + auth varchar(50) DEFAULT NULL, + mail varchar(100) DEFAULT NULL, + pass varchar(100) DEFAULT NULL, + details varchar(max), + CONSTRAINT mail UNIQUE (mail) +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Videos +CREATE TABLE Videos ( + mid varchar(50) DEFAULT NULL, + ke varchar(50) DEFAULT NULL, + ext enum('webm','mp4') DEFAULT NULL, + time datetime2(0) NULL DEFAULT NULL, + duration float DEFAULT NULL, + size float DEFAULT NULL, + frames int DEFAULT NULL, + end datetime2(0) NULL DEFAULT NULL, + status int DEFAULT '0' , + details varchar(max) +) ; + +-- Data exporting was unselected. +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/mssql/user.sql b/sql/mssql/user.sql new file mode 100644 index 0000000..399511d --- /dev/null +++ b/sql/mssql/user.sql @@ -0,0 +1,3 @@ +CREATE USER 'majesticflame'@'127.0.0.1' IDENTIFIED BY ''; +GRANT ALL PRIVILEGES ON ccio.* TO 'majesticflame'@'127.0.0.1'; +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/sql/postgresql/default_data.sql b/sql/postgresql/default_data.sql new file mode 100644 index 0000000..3cf0d48 --- /dev/null +++ b/sql/postgresql/default_data.sql @@ -0,0 +1,20 @@ +-- -------------------------------------------------------- +-- Host: 66.51.132.100 +-- Server version: 5.7.16-0ubuntu0.16.04.1 - (Ubuntu) +-- Server OS: Linux +-- HeidiSQL Version: 9.3.0.4984 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +-- Dumping data for table ccio.Users: ~0 rows (approximately) +/*!40000 ALTER TABLE `Users` DISABLE KEYS */; +INSERT INTO Users (ke, uid, auth, mail, pass, details) VALUES + ('2Df5hBE', 'XDf5hB3', 'ec49f05c1ddc7d818c61b3343c98cbc6', 'ccio@m03.ca', '5f4dcc3b5aa765d61d8327deb882cf99', '{"days":"10"}'); +INSERT INTO Monitors (mid, ke, name, shto, shfr, details, type, ext, protocol, host, path, port, fps, mode, width, height) VALUES ('bunny', '2Df5hBE', 'Bunny', '[]', '[]', '{"fatal_max":"","notes":"","dir":"","rtsp_transport":"tcp","muser":"","mpass":"","port_force":"0","sfps":"","aduration":"1000000","probesize":"1000000","accelerator":"0","hwaccel":null,"hwaccel_vcodec":"","hwaccel_device":"","stream_type":"hls","stream_mjpeg_clients":"","stream_vcodec":"copy","stream_acodec":"no","hls_time":"","preset_stream":"","hls_list_size":"","signal_check":"","signal_check_log":null,"stream_quality":"","stream_fps":"1","stream_scale_x":"","stream_scale_y":"","rotate_stream":null,"svf":"","stream_timestamp":"0","stream_timestamp_font":"","stream_timestamp_font_size":"","stream_timestamp_color":"","stream_timestamp_box_color":"","stream_timestamp_x":"","stream_timestamp_y":"","stream_watermark":"0","stream_watermark_location":"","stream_watermark_position":null,"snap":"1","snap_fps":"","snap_scale_x":"","snap_scale_y":"","snap_vf":"","vcodec":"copy","crf":"","preset_record":"","acodec":"libvorbis","dqf":null,"cutoff":"10","rotate_record":null,"vf":"","timestamp":"1","timestamp_font":"","timestamp_font_size":"","timestamp_color":"","timestamp_box_color":"","timestamp_x":"","timestamp_y":"","watermark":null,"watermark_location":"","watermark_position":null,"cust_input":"","cust_snap":"","cust_detect":"","cust_stream":"","cust_stream_server":"","cust_record":"","custom_output":"","detector":"0","detector_webhook":null,"detector_webhook_url":"","detector_command_enable":null,"detector_command":"","detector_command_timeout":"","detector_lock_timeout":"","detector_save":null,"detector_frame_save":null,"detector_mail":null,"detector_mail_timeout":"","detector_record_method":null,"detector_trigger":null,"detector_trigger_record_fps":"","detector_timeout":"","watchdog_reset":null,"detector_delete_motionless_videos":null,"detector_send_frames":null,"detector_fps":"","detector_scale_x":"","detector_scale_y":"","detector_use_motion":null,"detector_use_detect_object":null,"detector_frame":null,"detector_sensitivity":"","cords":"","detector_lisence_plate":null,"detector_lisence_plate_country":null,"detector_notrigger":null,"detector_notrigger_mail":null,"detector_notrigger_timeout":"","control":"0","control_base_url":"","control_stop":null,"control_url_stop_timeout":"","control_url_center":"","control_url_left":"","control_url_left_stop":"","control_url_right":"","control_url_right_stop":"","control_url_up":"","control_url_up_stop":"","control_url_down":"","control_url_down_stop":"","control_url_enable_nv":"","control_url_disable_nv":"","control_url_zoom_out":"","control_url_zoom_out_stop":"","control_url_zoom_in":"","control_url_zoom_in_stop":"","groups":"","loglevel":"warning","sqllog":"0","detector_cascades":""}', 'mjpeg', 'mp4', 'http', 'came3.nkansai.ne.jp', '/nphMotionJpeg?Resolution=640x480&Quality=Motion', 81, 15, 'start', 640, 480); +/*!40000 ALTER TABLE `Users` ENABLE KEYS */; +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/postgresql/framework.sql b/sql/postgresql/framework.sql new file mode 100644 index 0000000..21773d8 --- /dev/null +++ b/sql/postgresql/framework.sql @@ -0,0 +1,107 @@ +-- -------------------------------------------------------- +-- Host: 192.168.88.37 +-- Server version: 10.1.25-MariaDB- - Ubuntu 17.04 +-- Server OS: debian-linux-gnu +-- HeidiSQL Version: 9.4.0.5125 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8 */; +/*!50503 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; + + +-- Dumping database structure for ccio +CREATE DATABASE `ccio` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; +USE ccio; + +-- Dumping structure for table ccio.API +CREATE TABLE IF NOT EXISTS API ( + ke varchar(50) DEFAULT NULL, + uid varchar(50) DEFAULT NULL, + ip tinytext, + code varchar(100) DEFAULT NULL, + details text, + time timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Events +CREATE TABLE IF NOT EXISTS Events ( + ke varchar(50) DEFAULT NULL, + mid varchar(50) DEFAULT NULL, + details text, + time timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Logs +CREATE TABLE IF NOT EXISTS Logs ( + ke varchar(50) DEFAULT NULL, + mid varchar(50) DEFAULT NULL, + info text, + time timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Monitors +CREATE TABLE IF NOT EXISTS Monitors ( + mid varchar(50) DEFAULT NULL, + ke varchar(50) DEFAULT NULL, + name varchar(50) DEFAULT NULL, + shto text, + shfr text, + details text, + type varchar(50) DEFAULT 'jpeg', + ext varchar(50) DEFAULT 'webm', + protocol varchar(50) DEFAULT 'http', + host varchar(100) DEFAULT '0.0.0.0', + path varchar(100) DEFAULT '/', + port int DEFAULT '80', + fps int DEFAULT '1', + mode varchar(15) DEFAULT NULL, + width int DEFAULT '640', + height int DEFAULT '360' +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Presets +CREATE TABLE IF NOT EXISTS Presets ( + ke varchar(50) DEFAULT NULL, + name text, + details text, + type enum('monitor','event','user') DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Users +CREATE TABLE IF NOT EXISTS Users ( + ke varchar(50) DEFAULT NULL, + uid varchar(50) DEFAULT NULL, + auth varchar(50) DEFAULT NULL, + mail varchar(100) DEFAULT NULL, + pass varchar(100) DEFAULT NULL, + details text, + CONSTRAINT mail UNIQUE (mail) +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Videos +CREATE TABLE IF NOT EXISTS Videos ( + mid varchar(50) DEFAULT NULL, + ke varchar(50) DEFAULT NULL, + ext enum('webm','mp4') DEFAULT NULL, + time timestamp(0) NULL DEFAULT NULL, + duration double precision DEFAULT NULL, + size double precision DEFAULT NULL, + frames int DEFAULT NULL, + end timestamp(0) NULL DEFAULT NULL, + status int DEFAULT '0' , + details text +) ; + +-- Data exporting was unselected. +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/postgresql/user.sql b/sql/postgresql/user.sql new file mode 100644 index 0000000..399511d --- /dev/null +++ b/sql/postgresql/user.sql @@ -0,0 +1,3 @@ +CREATE USER 'majesticflame'@'127.0.0.1' IDENTIFIED BY ''; +GRANT ALL PRIVILEGES ON ccio.* TO 'majesticflame'@'127.0.0.1'; +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/sql/shinobi.sample.sqlite b/sql/shinobi.sample.sqlite new file mode 100644 index 0000000..2796be7 Binary files /dev/null and b/sql/shinobi.sample.sqlite differ diff --git a/sql/sqllog.txt b/sql/sqllog.txt new file mode 100644 index 0000000..d2ee894 --- /dev/null +++ b/sql/sqllog.txt @@ -0,0 +1 @@ +update-5-6-2017.sql - allows Idle mode options and future proofs the mode field for other modes. \ No newline at end of file diff --git a/sql/tables.sql b/sql/tables.sql new file mode 100644 index 0000000..6013c3f --- /dev/null +++ b/sql/tables.sql @@ -0,0 +1,84 @@ +-- Dumping structure for table ccio.API +CREATE TABLE IF NOT EXISTS `API` ( + `ke` varchar(50) DEFAULT NULL, + `uid` varchar(50) DEFAULT NULL, + `ip` tinytext, + `code` varchar(100) DEFAULT NULL, + `details` text, + `time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Events +CREATE TABLE IF NOT EXISTS `Events` ( + `ke` varchar(50) DEFAULT NULL, + `mid` varchar(50) DEFAULT NULL, + `details` text, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Logs +CREATE TABLE IF NOT EXISTS `Logs` ( + `ke` varchar(50) DEFAULT NULL, + `mid` varchar(50) DEFAULT NULL, + `info` text, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Monitors +CREATE TABLE IF NOT EXISTS `Monitors` ( + `mid` varchar(50) DEFAULT NULL, + `ke` varchar(50) DEFAULT NULL, + `name` varchar(50) DEFAULT NULL, + `shto` text, + `shfr` text, + `details` longtext, + `type` varchar(50) DEFAULT 'jpeg', + `ext` varchar(50) DEFAULT 'webm', + `protocol` varchar(50) DEFAULT 'http', + `host` varchar(100) DEFAULT '0.0.0.0', + `path` varchar(100) DEFAULT '/', + `port` int(8) DEFAULT '80', + `fps` int(8) DEFAULT '1', + `mode` varchar(15) DEFAULT NULL, + `width` int(11) DEFAULT '640', + `height` int(11) DEFAULT '360' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Presets +CREATE TABLE IF NOT EXISTS `Presets` ( + `ke` varchar(50) DEFAULT NULL, + `name` text, + `details` text, + `type` enum('monitor','event','user') DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Users +CREATE TABLE IF NOT EXISTS `Users` ( + `ke` varchar(50) DEFAULT NULL, + `uid` varchar(50) DEFAULT NULL, + `auth` varchar(50) DEFAULT NULL, + `mail` varchar(100) DEFAULT NULL, + `pass` varchar(100) DEFAULT NULL, + `details` longtext, + UNIQUE KEY `mail` (`mail`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Videos +CREATE TABLE IF NOT EXISTS `Videos` ( + `mid` varchar(50) DEFAULT NULL, + `ke` varchar(50) DEFAULT NULL, + `ext` enum('webm','mp4') DEFAULT NULL, + `time` timestamp NULL DEFAULT NULL, + `duration` float DEFAULT NULL, + `size` float DEFAULT NULL, + `frames` int(11) DEFAULT NULL, + `end` timestamp NULL DEFAULT NULL, + `status` int(1) DEFAULT '0' COMMENT '0:Building,1:Complete,2:Read,3:Archive', + `details` text +) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/sql/update-1-1-2017.sql b/sql/update-1-1-2017.sql new file mode 100644 index 0000000..d5384ac --- /dev/null +++ b/sql/update-1-1-2017.sql @@ -0,0 +1,11 @@ +USE ccio; +ALTER TABLE Monitors MODIFY ext VARCHAR(50); + +CREATE TABLE IF NOT EXISTS `API` ( + `ke` varchar(50) DEFAULT NULL, + `uid` varchar(50) DEFAULT NULL, + `ip` tinytext, + `code` varchar(100) DEFAULT NULL, + `details` text, + `time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/sql/update-13-7-2017.sql b/sql/update-13-7-2017.sql new file mode 100644 index 0000000..f72995b --- /dev/null +++ b/sql/update-13-7-2017.sql @@ -0,0 +1,2 @@ +USE `ccio`; +ALTER TABLE Videos CHANGE end end TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP; \ No newline at end of file diff --git a/sql/update-17-5-2017.sql b/sql/update-17-5-2017.sql new file mode 100644 index 0000000..e523e54 --- /dev/null +++ b/sql/update-17-5-2017.sql @@ -0,0 +1,17 @@ +CREATE DATABASE IF NOT EXISTS `ccio`; +USE `ccio`; + +CREATE TABLE IF NOT EXISTS `BackupVideos` ( + `mid` varchar(50) DEFAULT NULL, + `ke` varchar(50) DEFAULT NULL, + `ext` varchar(15) DEFAULT NULL, + `time` timestamp NULL DEFAULT NULL, + `end` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `size` float DEFAULT NULL, + `details` longtext +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE Videos MODIFY COLUMN `ext` varchar(15); +ALTER TABLE Videos ADD `details` longtext; +ALTER TABLE Videos DROP COLUMN `frames`; +ALTER TABLE Videos DROP COLUMN `duration`; \ No newline at end of file diff --git a/sql/update-2-2-2017.sql b/sql/update-2-2-2017.sql new file mode 100644 index 0000000..abef1d2 --- /dev/null +++ b/sql/update-2-2-2017.sql @@ -0,0 +1,28 @@ +-- -------------------------------------------------------- +-- Host: 192.168.88.58 +-- Server version: 5.7.17-0ubuntu0.16.04.1 - (Ubuntu) +-- Server OS: Linux +-- HeidiSQL Version: 9.3.0.4984 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; + +-- Dumping database structure for ccio +USE ccio; +ALTER TABLE `Monitors` CHANGE COLUMN `protocol` `protocol` VARCHAR(50) NULL DEFAULT 'http' AFTER `ext`; + +-- Dumping structure for table ccio.Events +CREATE TABLE IF NOT EXISTS `Events` ( + `ke` varchar(50) DEFAULT NULL, + `mid` varchar(50) DEFAULT NULL, + `details` text, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +-- Data exporting was unselected. +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/update-26-08-2017.sql b/sql/update-26-08-2017.sql new file mode 100644 index 0000000..0c985dd --- /dev/null +++ b/sql/update-26-08-2017.sql @@ -0,0 +1,2 @@ +use ccio +ALTER TABLE `Videos` ADD COLUMN `details` TEXT NULL DEFAULT NULL AFTER `status`; \ No newline at end of file diff --git a/sql/update-5-6-2017.sql b/sql/update-5-6-2017.sql new file mode 100644 index 0000000..987f751 --- /dev/null +++ b/sql/update-5-6-2017.sql @@ -0,0 +1,3 @@ +USE `ccio`; + +ALTER TABLE Monitors MODIFY COLUMN `mode` varchar(15); \ No newline at end of file diff --git a/sql/user.sql b/sql/user.sql new file mode 100644 index 0000000..399511d --- /dev/null +++ b/sql/user.sql @@ -0,0 +1,3 @@ +CREATE USER 'majesticflame'@'127.0.0.1' IDENTIFIED BY ''; +GRANT ALL PRIVILEGES ON ccio.* TO 'majesticflame'@'127.0.0.1'; +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/super.sample.json b/super.sample.json new file mode 100644 index 0000000..43d42d3 --- /dev/null +++ b/super.sample.json @@ -0,0 +1,6 @@ +[ + { + "mail":"admin@shinobi.video", + "pass":"21232f297a57a5a743894a0e4a801fc3" + } +] \ No newline at end of file diff --git a/tools/FLV Stream/ffmpegToWeb.js b/tools/FLV Stream/ffmpegToWeb.js new file mode 100644 index 0000000..0889326 --- /dev/null +++ b/tools/FLV Stream/ffmpegToWeb.js @@ -0,0 +1,102 @@ +// Shinobi (http://shinobi.video) - FFMPEG FLV over HTTP Test +// How to Use +// 1. Navigate to directory where this file is. +// 2. Run `npm install express moment` +// 3. Start with `node ffmpegToWeb.js` +// 4. Get the IP address of the computer where you did step 1. Example : 127.0.0.1 +// 5. Open `http://127.0.0.1:8001/` in your browser. + +var child = require('child_process'); +var events = require('events'); +var moment = require('moment'); +var express = require('express') +var app = express(); +var server = require('http').Server(app); +var io = require('socket.io')(server); +var spawn = child.spawn; +var exec = child.exec; +var Emitters = {} +var firstChunks = {} +var config = { + port:8001, + //ffmpegDir:'ffmpeg',//mac, linux +// ffmpegInput:'-rtsp_transport tcp -i rtsp://112.162.205.151:554/axis-media/media.3gp', + ffmpegInput:'-hwaccel cuvid -f dshow -i video=screen-capture-recorder',//windows screen + ffmpegDir:'D:/Program Files/ffmpeg/ffmpeg.exe',//windows (shortcutted ffmpeg to the same directory as this file) +} +var initEmitter = function(feed){ + if(!Emitters[feed]){ + Emitters[feed] = new events.EventEmitter().setMaxListeners(0) + } + return Emitters[feed] +} +//hold first chunk of FLV video +var initFirstChunk = function(feed,firstBuffer){ + if(!firstChunks[feed]){ + firstChunks[feed] = firstBuffer + } + return firstChunks[feed] +} +console.log('Starting Express Web Server on Port '+config.port) +//start webserver +server.listen(config.port); + +//make libraries static +app.use('/libs',express.static(__dirname + '/../../web/libs')); +app.use('/',express.static(__dirname + '/')); + +//homepage with video element. +//static file send of index.html +app.get('/', function (req, res) { + res.sendFile(__dirname + '/index.html'); +}) + +//// FLV over HTTP, this URL goes in the flv.js javascript player +// see ./index.html + + +io.on('connection', function (socket) { + var emitter = initEmitter(1) + var contentWriter; + + socket.emit('data',initFirstChunk('1')) + + emitter.on('data',contentWriter=function(buffer){ + socket.emit('flvData',buffer) + }) + socket.on('disconnect', function (socket) { + emitter.removeListener('data',contentWriter) + }) +}); + +//ffmpeg +console.log('Starting FFMPEG') +//var ffmpegString = config.ffmpegInput+' -r 15 -tune zerolatency -c:v libx264 -b:v 200k -crf 1 -an -f mpegts pipe:1' +var ffmpegString = config.ffmpegInput+' -an -c:v h264_nvenc -r 1 -f hls -tune zerolatency -g 1 -hls_time 0.1 -hls_list_size 2 -start_number 0 -live_start_index -3 -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist '+__dirname+'s.m3u8' +//var ffmpegString = config.ffmpegInput+' -r 15 -tune zerolatency -c:v h264_nvenc -crf 1 -vprofile baseline -preset ultrafast -pix_fmt yuv420p -b:v 400k -r 30 -threads 4 -fflags nobuffer -an -f mpegts pipe:1' +//+'-c:v h264_nvenc -an '+moment(new Date()).format('YYYY-MM-DDTHH-mm-ss')+'.mp4' +//var ffmpegString = '-i '+config.url+' -c:v libx264 -preset superfast -tune zerolatency -c:a aac -ar 44100 -f flv pipe:4' +//ffmpegString += ' -f mpegts -c:v mpeg1video -an http://localhost:'+config.port+'/streamIn/2' +if(ffmpegString.indexOf('rtsp://')>-1){ + ffmpegString='-rtsp_transport tcp '+ffmpegString +} +console.log('Executing : '+config.ffmpegDir+' '+ffmpegString) +var ffmpeg = spawn(config.ffmpegDir,ffmpegString.split(' '),{stdio:['pipe','pipe','pipe','pipe','pipe']}); +ffmpeg.on('close', function (buffer) { + console.log('ffmpeg died') +}) +//// FFMPEG Error Logs +ffmpeg.stderr.on('data', function (buffer) { + console.log(buffer.toString()) +}); +//data from pipe:1 output of ffmpeg + +var onFFmpegData = function (buffer) { + initFirstChunk('1',buffer) + onFFmpegData = function (buffer) { + initEmitter('1').emit('data',buffer) + } + onFFmpegData(buffer) +} + +ffmpeg.stdio[1].on('data', onFFmpegData); \ No newline at end of file diff --git a/tools/FLV Stream/flv.min.js b/tools/FLV Stream/flv.min.js new file mode 100644 index 0000000..94f1ddc --- /dev/null +++ b/tools/FLV Stream/flv.min.js @@ -0,0 +1,7 @@ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.flvjs=e()}}(function(){var e;return function e(t,n,i){function r(a,o){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!o&&u)return u(a,!0);if(s)return s(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var d=n[a]={exports:{}};t[a][0].call(d.exports,function(e){var n=t[a][1][e];return r(n||e)},d,d.exports,e,t,n,i)}return n[a].exports}for(var s="function"==typeof require&&require,a=0;a0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},i.prototype.on=i.prototype.addListener,i.prototype.once=function(e,t){function n(){this.removeListener(e,n),i||(i=!0,t.apply(this,arguments))}if(!r(t))throw TypeError("listener must be a function");var i=!1;return n.listener=t,this.on(e,n),this},i.prototype.removeListener=function(e,t){var n,i,s,o;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],s=n.length,i=-1,n===t||r(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(a(n)){for(o=s;o-- >0;)if(n[o]===t||n[o].listener&&n[o].listener===t){i=o;break}if(i<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(i,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},i.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],r(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},i.prototype.listeners=function(e){return this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},i.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(r(t))return 1;if(t)return t.length}return 0},i.listenerCount=function(e,t){return e.listenerCount(t)}},{}],3:[function(e,t,n){function i(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function s(e){if(h===setTimeout)return setTimeout(e,0);if((h===i||!h)&&setTimeout)return h=setTimeout,setTimeout(e,0);try{return h(e,0)}catch(t){try{return h.call(null,e,0)}catch(t){return h.call(this,e,0)}}}function a(e){if(f===clearTimeout)return clearTimeout(e);if((f===r||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(e);try{return f(e)}catch(t){try{return f.call(null,e)}catch(t){return f.call(this,e)}}}function o(){p&&_&&(p=!1,_.length?m=_.concat(m):v=-1,m.length&&u())}function u(){if(!p){var e=s(o);p=!0;for(var t=m.length;t;){for(_=m,m=[];++v1)for(var n=1;n=e[r]&&t0&&e[0].originalDts=t[r].dts&&et[i].lastSample.originalDts&&e=t[i].lastSample.originalDts&&(i===t.length-1||i0&&(r=this._searchNearestSegmentBefore(n.originalBeginDts)+1),this._lastAppendLocation=r,this._list.splice(r,0,n)}},{key:"getLastSegmentBefore",value:function(e){var t=this._searchNearestSegmentBefore(e);return t>=0?this._list[t]:null}},{key:"getLastSampleBefore",value:function(e){var t=this.getLastSegmentBefore(e);return null!=t?t.lastSample:null}},{key:"getLastSyncPointBefore",value:function(e){for(var t=this._searchNearestSegmentBefore(e),n=this._list[t].syncPoints;0===n.length&&t>0;)t--,n=this._list[t].syncPoints;return n.length>0?n[n.length-1]:null}},{key:"type",get:function(){return this._type}},{key:"length",get:function(){return this._list.length}}]),e}()},{}],9:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0&&(i+=";codecs="+n.codec);var r=!1;if(l.default.v(this.TAG,"Received Initialization Segment, mimeType: "+i),this._lastInitSegments[n.type]=n,i!==this._mimeTypes[n.type]){if(this._mimeTypes[n.type])l.default.v(this.TAG,"Notice: "+n.type+" mimeType changed, origin: "+this._mimeTypes[n.type]+", target: "+i);else{r=!0;try{var s=this._sourceBuffers[n.type]=this._mediaSource.addSourceBuffer(i);s.addEventListener("error",this.e.onSourceBufferError),s.addEventListener("updateend",this.e.onSourceBufferUpdateEnd)}catch(e){return l.default.e(this.TAG,e.message),void this._emitter.emit(c.default.ERROR,{code:e.code,msg:e.message})}}this._mimeTypes[n.type]=i}t||this._pendingSegments[n.type].push(n),r||this._sourceBuffers[n.type]&&!this._sourceBuffers[n.type].updating&&this._doAppendSegments(),h.default.safari&&"audio/mpeg"===n.container&&n.mediaDuration>0&&(this._requireSetMediaDuration=!0,this._pendingMediaDuration=n.mediaDuration/1e3,this._updateMediaSourceDuration())}},{key:"appendMediaSegment",value:function(e){var t=e;this._pendingSegments[t.type].push(t),this._config.autoCleanupSourceBuffer&&this._needCleanupSourceBuffer()&&this._doCleanupSourceBuffer();var n=this._sourceBuffers[t.type];!n||n.updating||this._hasPendingRemoveRanges()||this._doAppendSegments()}},{key:"seek",value:function(e){for(var t in this._sourceBuffers)if(this._sourceBuffers[t]){var n=this._sourceBuffers[t];if("open"===this._mediaSource.readyState)try{n.abort()}catch(e){l.default.e(this.TAG,e.message)}this._idrList.clear();var i=this._pendingSegments[t];if(i.splice(0,i.length),"closed"!==this._mediaSource.readyState){for(var r=0;r=1&&e-i.start(0)>=this._config.autoCleanupMaxBackwardDuration)return!0}}return!1}},{key:"_doCleanupSourceBuffer",value:function(){var e=this._mediaElement.currentTime;for(var t in this._sourceBuffers){var n=this._sourceBuffers[t];if(n){for(var i=n.buffered,r=!1,s=0;s=this._config.autoCleanupMaxBackwardDuration){r=!0;var u=e-this._config.autoCleanupMinBackwardDuration;this._pendingRemoveRanges[t].push({start:a,end:u})}}else o0&&(isNaN(t)||n>t)&&(l.default.v(this.TAG,"Update MediaSource duration from "+t+" to "+n),this._mediaSource.duration=n),this._requireSetMediaDuration=!1,this._pendingMediaDuration=0}}},{key:"_doRemoveRanges",value:function(){for(var e in this._pendingRemoveRanges)if(this._sourceBuffers[e]&&!this._sourceBuffers[e].updating)for(var t=this._sourceBuffers[e],n=this._pendingRemoveRanges[e];n.length&&!t.updating;){var i=n.shift();t.remove(i.start,i.end)}}},{key:"_doAppendSegments",value:function(){var e=this._pendingSegments;for(var t in e)if(this._sourceBuffers[t]&&!this._sourceBuffers[t].updating&&e[t].length>0){var n=e[t].shift();if(n.timestampOffset){var i=this._sourceBuffers[t].timestampOffset,r=n.timestampOffset/1e3,s=Math.abs(i-r);s>.1&&(l.default.v(this.TAG,"Update MPEG audio timestampOffset from "+i+" to "+r),this._sourceBuffers[t].timestampOffset=r),delete n.timestampOffset}if(!n.data||0===n.data.byteLength)continue;try{this._sourceBuffers[t].appendBuffer(n.data),this._isBufferFull=!1,"video"===t&&n.hasOwnProperty("info")&&this._idrList.appendArray(n.info.syncPoints)}catch(e){this._pendingSegments[t].unshift(n),22===e.code?(this._isBufferFull||this._emitter.emit(c.default.BUFFER_FULL),this._isBufferFull=!0):(l.default.e(this.TAG,e.message),this._emitter.emit(c.default.ERROR,{code:e.code,msg:e.message}))}}}},{key:"_onSourceOpen",value:function(){if(l.default.v(this.TAG,"MediaSource onSourceOpen"),this._mediaSource.removeEventListener("sourceopen",this.e.onSourceOpen),this._pendingSourceBufferInit.length>0)for(var e=this._pendingSourceBufferInit;e.length;){var t=e.shift();this.appendInitSegment(t,!0)}this._hasPendingSegments()&&this._doAppendSegments(),this._emitter.emit(c.default.SOURCE_OPEN)}},{key:"_onSourceEnded",value:function(){l.default.v(this.TAG,"MediaSource onSourceEnded")}},{key:"_onSourceClose",value:function(){l.default.v(this.TAG,"MediaSource onSourceClose"),this._mediaSource&&null!=this.e&&(this._mediaSource.removeEventListener("sourceopen",this.e.onSourceOpen),this._mediaSource.removeEventListener("sourceended",this.e.onSourceEnded),this._mediaSource.removeEventListener("sourceclose",this.e.onSourceClose))}},{key:"_hasPendingSegments",value:function(){var e=this._pendingSegments;return e.video.length>0||e.audio.length>0}},{key:"_hasPendingRemoveRanges",value:function(){var e=this._pendingRemoveRanges;return e.video.length>0||e.audio.length>0}},{key:"_onSourceBufferUpdateEnd",value:function(){this._requireSetMediaDuration?this._updateMediaSourceDuration():this._hasPendingRemoveRanges()?this._doRemoveRanges():this._hasPendingSegments()?this._doAppendSegments():this._hasPendingEos&&this.endOfStream(),this._emitter.emit(c.default.UPDATE_END)}},{key:"_onSourceBufferError",value:function(e){l.default.e(this.TAG,"SourceBuffer Error: "+e)}}]),e}();n.default=p},{"../utils/browser.js":39,"../utils/exception.js":40,"../utils/logger.js":41,"./media-segment-info.js":8,"./mse-events.js":10,events:2}],10:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i={ERROR:"error",SOURCE_OPEN:"source_open",UPDATE_END:"update_end",BUFFER_FULL:"buffer_full"};n.default=i},{}],11:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0)this._demuxer.bindDataSource(this._ioctl),this._demuxer.timestampBase=this._mediaDataSource.segments[this._currentSegmentIndex].timestampBase,r=this._demuxer.parseChunks(e,t);else if((i=m.default.probe(e)).match){this._demuxer=new m.default(i,this._config),this._remuxer||(this._remuxer=new v.default(this._config));var s=this._mediaDataSource;void 0==s.duration||isNaN(s.duration)||(this._demuxer.overridedDuration=s.duration),"boolean"==typeof s.hasAudio&&(this._demuxer.overridedHasAudio=s.hasAudio),"boolean"==typeof s.hasVideo&&(this._demuxer.overridedHasVideo=s.hasVideo),this._demuxer.timestampBase=s.segments[this._currentSegmentIndex].timestampBase,this._demuxer.onError=this._onDemuxException.bind(this),this._demuxer.onMediaInfo=this._onMediaInfo.bind(this),this._remuxer.bindDataSource(this._demuxer.bindDataSource(this._ioctl)),this._remuxer.onInitSegment=this._onRemuxerInitSegmentArrival.bind(this),this._remuxer.onMediaSegment=this._onRemuxerMediaSegmentArrival.bind(this),r=this._demuxer.parseChunks(e,t)}else i=null,l.default.e(this.TAG,"Non-FLV, Unsupported media type!"),Promise.resolve().then(function(){n._internalAbort()}),this._emitter.emit(k.default.DEMUX_ERROR,y.default.FORMAT_UNSUPPORTED,"Non-FLV, Unsupported media type"),r=0;return r}},{key:"_onMediaInfo",value:function(e){var t=this;null==this._mediaInfo&&(this._mediaInfo=Object.assign({},e),this._mediaInfo.keyframesIndex=null,this._mediaInfo.segments=[],this._mediaInfo.segmentCount=this._mediaDataSource.segments.length,Object.setPrototypeOf(this._mediaInfo,c.default.prototype));var n=Object.assign({},e);Object.setPrototypeOf(n,c.default.prototype),this._mediaInfo.segments[this._currentSegmentIndex]=n,this._reportSegmentMediaInfo(this._currentSegmentIndex),null!=this._pendingSeekTime&&Promise.resolve().then(function(){var e=t._pendingSeekTime;t._pendingSeekTime=null,t.seek(e)})}},{key:"_onIOSeeked",value:function(){this._remuxer.insertDiscontinuity()}},{key:"_onIOComplete",value:function(e){var t=e,n=t+1;n0&&n[0].originalDts===i&&(i=n[0].pts),this._emitter.emit(k.default.RECOMMEND_SEEKPOINT,i)}}},{key:"_enableStatisticsReporter",value:function(){null==this._statisticsReporter&&(this._statisticsReporter=self.setInterval(this._reportStatisticsInfo.bind(this),this._config.statisticsInfoReportInterval))}},{key:"_disableStatisticsReporter",value:function(){this._statisticsReporter&&(self.clearInterval(this._statisticsReporter),this._statisticsReporter=null)}},{key:"_reportSegmentMediaInfo",value:function(e){var t=this._mediaInfo.segments[e],n=Object.assign({},t);n.duration=this._mediaInfo.duration,n.segmentCount=this._mediaInfo.segmentCount,delete n.segments,delete n.keyframesIndex,this._emitter.emit(k.default.MEDIA_INFO,n)}},{key:"_reportStatisticsInfo",value:function(){var e={};e.url=this._ioctl.currentURL,e.hasRedirect=this._ioctl.hasRedirect,e.hasRedirect&&(e.redirectedURL=this._ioctl.currentRedirectedURL),e.speed=this._ioctl.currentSpeed,e.loaderType=this._ioctl.loaderType,e.currentSegmentIndex=this._currentSegmentIndex,e.totalSegmentCount=this._mediaDataSource.segments.length,this._emitter.emit(k.default.STATISTICS_INFO,e)}}]),e}());n.default=L},{"../demux/demux-errors.js":16,"../demux/flv-demuxer.js":18,"../io/io-controller.js":23,"../io/loader.js":24,"../remux/mp4-remuxer.js":38,"../utils/browser.js":39,"../utils/logger.js":41,"./media-info.js":7,"./transmuxing-events.js":13,events:2}],13:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i={IO_ERROR:"io_error",DEMUX_ERROR:"demux_error",INIT_SEGMENT:"init_segment",MEDIA_SEGMENT:"media_segment",LOADING_COMPLETE:"loading_complete",RECOVERED_EARLY_EOF:"recovered_early_eof",MEDIA_INFO:"media_info",STATISTICS_INFO:"statistics_info",RECOMMEND_SEEKPOINT:"recommend_seekpoint"};n.default=i},{}],14:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(n,"__esModule",{value:!0});var r=e("../utils/logger.js"),s=(i(r),e("../utils/logging-control.js")),a=i(s),o=e("../utils/polyfill.js"),u=i(o),l=e("./transmuxing-controller.js"),d=i(l),h=e("./transmuxing-events.js"),f=i(h),c=function(e){function t(t,n){var i={msg:f.default.INIT_SEGMENT,data:{type:t,data:n}};e.postMessage(i,[n.data])}function n(t,n){var i={msg:f.default.MEDIA_SEGMENT,data:{type:t,data:n}};e.postMessage(i,[n.data])}function i(){var t={msg:f.default.LOADING_COMPLETE};e.postMessage(t)}function r(){var t={msg:f.default.RECOVERED_EARLY_EOF};e.postMessage(t)}function s(t){var n={msg:f.default.MEDIA_INFO,data:t};e.postMessage(n)}function o(t){var n={msg:f.default.STATISTICS_INFO,data:t};e.postMessage(n)}function l(t,n){e.postMessage({msg:f.default.IO_ERROR,data:{type:t,info:n}})}function h(t,n){e.postMessage({msg:f.default.DEMUX_ERROR,data:{type:t,info:n}})}function c(t){e.postMessage({msg:f.default.RECOMMEND_SEEKPOINT,data:t})}function _(t,n){e.postMessage({msg:"logcat_callback",data:{type:t,logcat:n}})}var m=null,p=_.bind(this);u.default.install(),e.addEventListener("message",function(u){switch(u.data.cmd){case"init":m=new d.default(u.data.param[0],u.data.param[1]),m.on(f.default.IO_ERROR,l.bind(this)),m.on(f.default.DEMUX_ERROR,h.bind(this)),m.on(f.default.INIT_SEGMENT,t.bind(this)),m.on(f.default.MEDIA_SEGMENT,n.bind(this)),m.on(f.default.LOADING_COMPLETE,i.bind(this)),m.on(f.default.RECOVERED_EARLY_EOF,r.bind(this)),m.on(f.default.MEDIA_INFO,s.bind(this)),m.on(f.default.STATISTICS_INFO,o.bind(this)),m.on(f.default.RECOMMEND_SEEKPOINT,c.bind(this));break;case"destroy":m&&(m.destroy(),m=null),e.postMessage({msg:"destroyed"});break;case"start":m.start();break;case"stop":m.stop();break;case"seek":m.seek(u.data.param);break;case"pause":m.pause();break;case"resume":m.resume();break;case"logging_config":var _=u.data.param;a.default.applyConfig(_),!0===_.enableCallback?a.default.addLogListener(p):a.default.removeLogListener(p)}})};n.default=c},{"../utils/logger.js":41,"../utils/logging-control.js":42,"../utils/polyfill.js":43,"./transmuxing-controller.js":12,"./transmuxing-events.js":13}],15:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0?(0,l.default)(new Uint8Array(e,t+2,r)):"",{data:s,size:2+r}}},{key:"parseLongString",value:function(e,t,n){if(n<4)throw new d.IllegalStateException("Data not enough when parse LongString");var i=new DataView(e,t,n),r=i.getUint32(0,!h),s=void 0;return s=r>0?(0,l.default)(new Uint8Array(e,t+4,r)):"",{data:s,size:4+r}}},{key:"parseDate",value:function(e,t,n){if(n<10)throw new d.IllegalStateException("Data size invalid when parse Date");var i=new DataView(e,t,n),r=i.getFloat64(0,!h);return r+=60*i.getInt16(8,!h)*1e3,{data:new Date(r),size:10}}},{key:"parseValue",value:function(t,n,i){if(i<1)throw new d.IllegalStateException("Data not enough when parse Value");var r=new DataView(t,n,i),s=1,a=r.getUint8(0),u=void 0,l=!1;try{switch(a){case 0:u=r.getFloat64(1,!h),s+=8;break;case 1:u=!!r.getUint8(1),s+=1;break;case 2:var f=e.parseString(t,n+1,i-1);u=f.data,s+=f.size;break;case 3:u={};var c=0;for(9==(16777215&r.getUint32(i-4,!h))&&(c=3);s32)throw new s.InvalidArgumentException("ExpGolomb: readBits() bits exceeded max 32bits!");if(e<=this._current_word_bits_left){var t=this._current_word>>>32-e;return this._current_word<<=e,this._current_word_bits_left-=e,t}var n=this._current_word_bits_left?this._current_word:0;n>>>=32-this._current_word_bits_left;var i=e-this._current_word_bits_left;this._fillCurrentWord();var r=Math.min(i,this._current_word_bits_left),a=this._current_word>>>32-r;return this._current_word<<=r,this._current_word_bits_left-=r,n=n<>>e))return this._current_word<<=e,this._current_word_bits_left-=e,e;return this._fillCurrentWord(),e+this._skipLeadingZero()}},{key:"readUEG",value:function(){var e=this._skipLeadingZero();return this.readBits(e+1)-1}},{key:"readSEG",value:function(){var e=this.readUEG();return 1&e?e+1>>>1:-1*(e>>>1)}}]),e}();n.default=a},{"../utils/exception.js":40}],18:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]}Object.defineProperty(n,"__esModule",{value:!0});var a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=function(){function e(e,t){for(var n=0;n13))return 0;i=e.probe(t).dataOffset}if(this._firstParse){this._firstParse=!1,n+i!==this._dataOffset&&l.default.w(this.TAG,"First time parsing but chunk byteStart invalid!");0!==new DataView(t,i).getUint32(0,!r)&&l.default.w(this.TAG,"PrevTagSize0 !== 0 !!!"),i+=4}for(;it.byteLength)break;var a=s.getUint8(0),o=16777215&s.getUint32(0,!r);if(i+11+o+4>t.byteLength)break;if(8===a||9===a||18===a){var u=s.getUint8(4),d=s.getUint8(5),h=s.getUint8(6),f=s.getUint8(7),c=h|d<<8|u<<16|f<<24;0!==(16777215&s.getUint32(7,!r))&&l.default.w(this.TAG,"Meet tag which has StreamID != 0!");var _=i+11;switch(a){case 8:this._parseAudioData(t,_,o,c);break;case 9:this._parseVideoData(t,_,o,c,n+i);break;case 18:this._parseScriptData(t,_,o)}var m=s.getUint32(11+o,!r);m!==11+o&&l.default.w(this.TAG,"Invalid PrevTagSize "+m),i+=11+o+4}else l.default.w(this.TAG,"Unsupported tag type "+a+", skipped"),i+=11+o+4}return this._isInitialMetadataDispatched()&&this._dispatch&&(this._audioTrack.length||this._videoTrack.length)&&this._onDataAvailable(this._audioTrack,this._videoTrack),i}},{key:"_parseScriptData",value:function(e,t,n){var i=h.default.parseScriptData(e,t,n);if(i.hasOwnProperty("onMetaData")){if(null==i.onMetaData||"object"!==a(i.onMetaData))return void l.default.w(this.TAG,"Invalid onMetaData structure!");this._metadata&&l.default.w(this.TAG,"Found another onMetaData tag!"),this._metadata=i;var r=this._metadata.onMetaData;if("boolean"==typeof r.hasAudio&&!1===this._hasAudioFlagOverrided&&(this._hasAudio=r.hasAudio,this._mediaInfo.hasAudio=this._hasAudio),"boolean"==typeof r.hasVideo&&!1===this._hasVideoFlagOverrided&&(this._hasVideo=r.hasVideo,this._mediaInfo.hasVideo=this._hasVideo),"number"==typeof r.audiodatarate&&(this._mediaInfo.audioDataRate=r.audiodatarate),"number"==typeof r.videodatarate&&(this._mediaInfo.videoDataRate=r.videodatarate),"number"==typeof r.width&&(this._mediaInfo.width=r.width),"number"==typeof r.height&&(this._mediaInfo.height=r.height),"number"==typeof r.duration){if(!this._durationOverrided){var s=Math.floor(r.duration*this._timescale);this._duration=s,this._mediaInfo.duration=s}}else this._mediaInfo.duration=0;if("number"==typeof r.framerate){var o=Math.floor(1e3*r.framerate);if(o>0){var u=o/1e3;this._referenceFrameRate.fixed=!0,this._referenceFrameRate.fps=u,this._referenceFrameRate.fps_num=o,this._referenceFrameRate.fps_den=1e3,this._mediaInfo.fps=u}}if("object"===a(r.keyframes)){this._mediaInfo.hasKeyframesIndex=!0;var d=r.keyframes;this._mediaInfo.keyframesIndex=this._parseKeyframesIndex(d),r.keyframes=null}else this._mediaInfo.hasKeyframesIndex=!1;this._dispatch=!1,this._mediaInfo.metadata=r,l.default.v(this.TAG,"Parsed onMetaData"),this._mediaInfo.isComplete()&&this._onMediaInfo(this._mediaInfo)}}},{key:"_parseKeyframesIndex",value:function(e){for(var t=[],n=[],i=1;i>>4;if(2!==a&&10!==a)return void this._onError(m.default.CODEC_UNSUPPORTED,"Flv: Unsupported audio codec idx: "+a);var o=0,u=(12&s)>>>2;if(!(u>=0&&u<=4))return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid audio sample rate idx: "+u);o=this._flvSoundRateTable[u];var d=1&s,h=this._audioMetadata,f=this._audioTrack;if(h||(!1===this._hasAudio&&!1===this._hasAudioFlagOverrided&&(this._hasAudio=!0,this._mediaInfo.hasAudio=!0),h=this._audioMetadata={},h.type="audio",h.id=f.id,h.timescale=this._timescale,h.duration=this._duration,h.audioSampleRate=o,h.channelCount=0===d?1:2),10===a){var c=this._parseAACAudioData(e,t+1,n-1);if(void 0==c)return;if(0===c.packetType){h.config&&l.default.w(this.TAG,"Found another AudioSpecificConfig!");var _=c.data;h.audioSampleRate=_.samplingRate,h.channelCount=_.channelCount,h.codec=_.codec,h.originalCodec=_.originalCodec,h.config=_.config,h.refSampleDuration=1024/h.audioSampleRate*h.timescale,l.default.v(this.TAG,"Parsed AudioSpecificConfig"),this._isInitialMetadataDispatched()?this._dispatch&&(this._audioTrack.length||this._videoTrack.length)&&this._onDataAvailable(this._audioTrack,this._videoTrack):this._audioInitialMetadataDispatched=!0,this._dispatch=!1,this._onTrackMetadata("audio",h);var p=this._mediaInfo;p.audioCodec=h.originalCodec,p.audioSampleRate=h.audioSampleRate,p.audioChannelCount=h.channelCount,p.hasVideo?null!=p.videoCodec&&(p.mimeType='video/x-flv; codecs="'+p.videoCodec+","+p.audioCodec+'"'):p.mimeType='video/x-flv; codecs="'+p.audioCodec+'"',p.isComplete()&&this._onMediaInfo(p)}else if(1===c.packetType){var v=this._timestampBase+i,g={unit:c.data,dts:v,pts:v};f.samples.push(g),f.length+=c.data.length}else l.default.e(this.TAG,"Flv: Unsupported AAC data type "+c.packetType)}else if(2===a){if(!h.codec){var y=this._parseMP3AudioData(e,t+1,n-1,!0);if(void 0==y)return;h.audioSampleRate=y.samplingRate,h.channelCount=y.channelCount,h.codec=y.codec,h.originalCodec=y.originalCodec,h.refSampleDuration=1152/h.audioSampleRate*h.timescale,l.default.v(this.TAG,"Parsed MPEG Audio Frame Header"),this._audioInitialMetadataDispatched=!0,this._onTrackMetadata("audio",h);var E=this._mediaInfo;E.audioCodec=h.codec,E.audioSampleRate=h.audioSampleRate,E.audioChannelCount=h.channelCount,E.audioDataRate=y.bitRate,E.hasVideo?null!=E.videoCodec&&(E.mimeType='video/x-flv; codecs="'+E.videoCodec+","+E.audioCodec+'"'):E.mimeType='video/x-flv; codecs="'+E.audioCodec+'"',E.isComplete()&&this._onMediaInfo(E)}var b=this._parseMP3AudioData(e,t+1,n-1,!1);if(void 0==b)return;var S=this._timestampBase+i,k={unit:b,dts:S,pts:S};f.samples.push(k),f.length+=b.length}}}},{ +key:"_parseAACAudioData",value:function(e,t,n){if(n<=1)return void l.default.w(this.TAG,"Flv: Invalid AAC packet, missing AACPacketType or/and Data!");var i={},r=new Uint8Array(e,t,n);return i.packetType=r[0],0===r[0]?i.data=this._parseAACAudioSpecificConfig(e,t+1,n-1):i.data=r.subarray(1),i}},{key:"_parseAACAudioSpecificConfig",value:function(e,t,n){var i=new Uint8Array(e,t,n),r=null,s=0,a=0,o=0,u=null;if(s=a=i[0]>>>3,(o=(7&i[0])<<1|i[1]>>>7)<0||o>=this._mpegSamplingRates.length)return void this._onError(m.default.FORMAT_ERROR,"Flv: AAC invalid sampling frequency index!");var l=this._mpegSamplingRates[o],d=(120&i[1])>>>3;if(d<0||d>=8)return void this._onError(m.default.FORMAT_ERROR,"Flv: AAC invalid channel configuration");5===s&&(u=(7&i[1])<<1|i[2]>>>7,i[2]);var h=self.navigator.userAgent.toLowerCase();return-1!==h.indexOf("firefox")?o>=6?(s=5,r=new Array(4),u=o-3):(s=2,r=new Array(2),u=o):-1!==h.indexOf("android")?(s=2,r=new Array(2),u=o):(s=5,u=o,r=new Array(4),o>=6?u=o-3:1===d&&(s=2,r=new Array(2),u=o)),r[0]=s<<3,r[0]|=(15&o)>>>1,r[1]=(15&o)<<7,r[1]|=(15&d)<<3,5===s&&(r[1]|=(15&u)>>>1,r[2]=(1&u)<<7,r[2]|=8,r[3]=0),{config:r,samplingRate:l,channelCount:d,codec:"mp4a.40."+s,originalCodec:"mp4a.40."+a}}},{key:"_parseMP3AudioData",value:function(e,t,n,i){if(n<4)return void l.default.w(this.TAG,"Flv: Invalid MP3 packet, header missing!");var r=(this._littleEndian,new Uint8Array(e,t,n)),s=null;if(i){if(255!==r[0])return;var a=r[1]>>>3&3,o=(6&r[1])>>1,u=(240&r[2])>>>4,d=(12&r[2])>>>2,h=r[3]>>>6&3,f=3!==h?2:1,c=0,_=0;switch(a){case 0:c=this._mpegAudioV25SampleRateTable[d];break;case 2:c=this._mpegAudioV20SampleRateTable[d];break;case 3:c=this._mpegAudioV10SampleRateTable[d]}switch(o){case 1:34,u>>4,o=15&s;if(7!==o)return void this._onError(m.default.CODEC_UNSUPPORTED,"Flv: Unsupported codec in video frame: "+o);this._parseAVCVideoPacket(e,t+1,n-1,i,r,a)}}},{key:"_parseAVCVideoPacket",value:function(e,t,n,i,r,s){if(n<4)return void l.default.w(this.TAG,"Flv: Invalid AVC packet, missing AVCPacketType or/and CompositionTime");var a=this._littleEndian,o=new DataView(e,t,n),u=o.getUint8(0),d=16777215&o.getUint32(0,!a);if(0===u)this._parseAVCDecoderConfigurationRecord(e,t+4,n-4);else if(1===u)this._parseAVCVideoData(e,t+4,n-4,i,r,s,d);else if(2!==u)return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid video packet type "+u)}},{key:"_parseAVCDecoderConfigurationRecord",value:function(e,t,n){if(n<7)return void l.default.w(this.TAG,"Flv: Invalid AVCDecoderConfigurationRecord, lack of data!");var i=this._videoMetadata,r=this._videoTrack,s=this._littleEndian,a=new DataView(e,t,n);i?void 0!==i.avcc&&l.default.w(this.TAG,"Found another AVCDecoderConfigurationRecord!"):(!1===this._hasVideo&&!1===this._hasVideoFlagOverrided&&(this._hasVideo=!0,this._mediaInfo.hasVideo=!0),i=this._videoMetadata={},i.type="video",i.id=r.id,i.timescale=this._timescale,i.duration=this._duration);var o=a.getUint8(0),u=a.getUint8(1);a.getUint8(2),a.getUint8(3);if(1!==o||0===u)return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid AVCDecoderConfigurationRecord");if(this._naluLengthSize=1+(3&a.getUint8(4)),3!==this._naluLengthSize&&4!==this._naluLengthSize)return void this._onError(m.default.FORMAT_ERROR,"Flv: Strange NaluLengthSizeMinusOne: "+(this._naluLengthSize-1));var d=31&a.getUint8(5);if(0===d)return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid AVCDecoderConfigurationRecord: No SPS");d>1&&l.default.w(this.TAG,"Flv: Strange AVCDecoderConfigurationRecord: SPS Count = "+d);for(var h=6,f=0;f1&&l.default.w(this.TAG,"Flv: Strange AVCDecoderConfigurationRecord: PPS Count = "+w),h++;for(var R=0;R=n){l.default.w(this.TAG,"Malformed Nalu near timestamp "+_+", offset = "+f+", dataSize = "+n);break}var p=u.getUint32(f,!o);if(3===c&&(p>>>=8),p>n-c)return void l.default.w(this.TAG,"Malformed Nalus near timestamp "+_+", NaluSize > DataSize!");var v=31&u.getUint8(f+c);5===v&&(m=!0);var g=new Uint8Array(e,t+f,c+p),y={type:v,data:g};d.push(y),h+=g.byteLength,f+=c+p}if(d.length){var E=this._videoTrack,b={units:d,length:h,isKeyframe:m,dts:_,cts:a,pts:_+a};m&&(b.fileposition=r),E.samples.push(b),E.length+=h}}},{key:"onTrackMetadata",get:function(){return this._onTrackMetadata},set:function(e){this._onTrackMetadata=e}},{key:"onMediaInfo",get:function(){return this._onMediaInfo},set:function(e){this._onMediaInfo=e}},{key:"onError",get:function(){return this._onError},set:function(e){this._onError=e}},{key:"onDataAvailable",get:function(){return this._onDataAvailable},set:function(e){this._onDataAvailable=e}},{key:"timestampBase",get:function(){return this._timestampBase},set:function(e){this._timestampBase=e}},{key:"overridedDuration",get:function(){return this._duration},set:function(e){this._durationOverrided=!0,this._duration=e,this._mediaInfo.duration=e}},{key:"overridedHasAudio",set:function(e){this._hasAudioFlagOverrided=!0,this._hasAudio=e,this._mediaInfo.hasAudio=e}},{key:"overridedHasVideo",set:function(e){this._hasVideoFlagOverrided=!0,this._hasVideo=e,this._mediaInfo.hasVideo=e}}],[{key:"probe",value:function(e){var t=new Uint8Array(e),n={match:!1};if(70!==t[0]||76!==t[1]||86!==t[2]||1!==t[3])return n;var i=(4&t[4])>>>2!=0,r=0!=(1&t[4]),a=s(t,5);return a<9?n:{match:!0,consumed:a,dataOffset:a,hasAudioTrack:i,hasVideoTrack:r}}}]),e}();n.default=y},{"../core/media-info.js":7,"../utils/exception.js":40,"../utils/logger.js":41,"./amf-parser.js":15,"./demux-errors.js":16,"./sps-parser.js":19}],19:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=2&&3===t[s]&&0===t[s-1]&&0===t[s-2]||(i[r]=t[s],r++);return new Uint8Array(i.buffer,0,r)}},{key:"parseSPS",value:function(t){var n=e._ebsp2rbsp(t),i=new a.default(n);i.readByte();var r=i.readByte();i.readByte();var s=i.readByte();i.readUEG();var o=e.getProfileString(r),u=e.getLevelString(s),l=1,d=420,h=[0,420,422,444],f=8;if((100===r||110===r||122===r||244===r||44===r||83===r||86===r||118===r||128===r||138===r||144===r)&&(l=i.readUEG(),3===l&&i.readBits(1),l<=3&&(d=h[l]),f=i.readUEG()+8,i.readUEG(),i.readBits(1),i.readBool()))for(var c=3!==l?8:12,_=0;_0&&I<16?(w=x[I-1],R=M[I-1]):255===I&&(w=i.readByte()<<8|i.readByte(),R=i.readByte()<<8|i.readByte())}if(i.readBool()&&i.readBool(),i.readBool()&&(i.readBits(4),i.readBool()&&i.readBits(24)),i.readBool()&&(i.readUEG(),i.readUEG()),i.readBool()){var D=i.readBits(32),B=i.readBits(32);O=i.readBool(),T=B,C=2*D,A=T/C}}var j=1;1===w&&1===R||(j=w/R);var P=0,U=0;if(0===l)P=1,U=2-E;else{var N=3===l?1:2,F=1===l?2:1;P=N,U=F*(2-E)}var G=16*(g+1),V=16*(y+1)*(2-E);G-=(b+S)*P,V-=(k+L)*U;var z=Math.ceil(G*j);return i.destroy(),i=null,{profile_string:o,level_string:u,bit_depth:f,chroma_format:d,chroma_format_string:e.getChromaFormatString(d),frame_rate:{fixed:O,fps:A,fps_den:C,fps_num:T},sar_ratio:{width:w,height:R},codec_size:{width:G,height:V},present_size:{width:z,height:V}}}},{key:"_skipScalingList",value:function(e,t){for(var n=8,i=8,r=0,s=0;s=15048,t=!f.default.msedge||e;return self.fetch&&self.ReadableStream&&t}catch(e){return!1}}}]),l(t,[{key:"destroy",value:function(){this.isWorking()&&this.abort(),u(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"destroy",this).call(this)}},{key:"open",value:function(e,t){var n=this;this._dataSource=e,this._range=t;var i=e.url;this._config.reuseRedirectedURL&&void 0!=e.redirectedURL&&(i=e.redirectedURL);var r=this._seekHandler.getConfig(i,t),s=new self.Headers;if("object"===o(r.headers)){var a=r.headers;for(var u in a)a.hasOwnProperty(u)&&s.append(u,a[u])}var l={method:"GET",headers:s,mode:"cors",cache:"default",referrerPolicy:"no-referrer-when-downgrade"};!1===e.cors&&(l.mode="same-origin"),e.withCredentials&&(l.credentials="include"),e.referrerPolicy&&(l.referrerPolicy=e.referrerPolicy),this._status=c.LoaderStatus.kConnecting,self.fetch(r.url,l).then(function(e){if(n._requestAbort)return n._requestAbort=!1,void(n._status=c.LoaderStatus.kIdle);if(e.ok&&e.status>=200&&e.status<=299){if(e.url!==r.url&&n._onURLRedirect){var t=n._seekHandler.removeURLParameters(e.url);n._onURLRedirect(t)}var i=e.headers.get("Content-Length");return null!=i&&(n._contentLength=parseInt(i),0!==n._contentLength&&n._onContentLengthKnown&&n._onContentLengthKnown(n._contentLength)),n._pump.call(n,e.body.getReader())}if(n._status=c.LoaderStatus.kError,!n._onError)throw new _.RuntimeException("FetchStreamLoader: Http code invalid, "+e.status+" "+e.statusText);n._onError(c.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:e.status,msg:e.statusText})}).catch(function(e){if(n._status=c.LoaderStatus.kError,!n._onError)throw e;n._onError(c.LoaderErrors.EXCEPTION,{code:-1,msg:e.message})})}},{key:"abort",value:function(){this._requestAbort=!0}},{key:"_pump",value:function(e){var t=this;return e.read().then(function(n){if(n.done)t._status=c.LoaderStatus.kComplete,t._onComplete&&t._onComplete(t._range.from,t._range.from+t._receivedLength-1);else{if(!0===t._requestAbort)return t._requestAbort=!1,t._status=c.LoaderStatus.kComplete,e.cancel();t._status=c.LoaderStatus.kBuffering;var i=n.value.buffer,r=t._range.from+t._receivedLength;t._receivedLength+=i.byteLength,t._onDataArrival&&t._onDataArrival(i,r,t._receivedLength),t._pump(e)}}).catch(function(e){if(11!==e.code||!f.default.msedge){t._status=c.LoaderStatus.kError;var n=0,i=null;if(19!==e.code&&"network error"!==e.message||!(null===t._contentLength||null!==t._contentLength&&t._receivedLength0&&(this._stashInitialSize=n.stashInitialSize),this._stashUsed=0,this._stashSize=this._stashInitialSize,this._bufferSize=3145728,this._stashBuffer=new ArrayBuffer(this._bufferSize),this._stashByteStart=0,this._enableStash=!0,!1===n.enableStashBuffer&&(this._enableStash=!1),this._loader=null,this._loaderClass=null,this._seekHandler=null,this._dataSource=t,this._isWebSocketURL=/wss?:\/\/(.+?)/.test(t.url),this._refTotalLength=t.filesize?t.filesize:null,this._totalLength=this._refTotalLength,this._fullRequestFlag=!1,this._currentRange=null,this._redirectedURL=null,this._speedNormalized=0,this._speedSampler=new l.default,this._speedNormalizeList=[64,128,256,384,512,768,1024,1536,2048,3072,4096],this._isEarlyEofReconnecting=!1,this._paused=!1,this._resumeFrom=0,this._onDataArrival=null,this._onSeeked=null,this._onError=null,this._onComplete=null,this._onRedirect=null,this._onRecoveredEarlyEof=null,this._selectSeekHandler(),this._selectLoader(),this._createLoader()}return s(e,[{key:"destroy",value:function(){this._loader.isWorking()&&this._loader.abort(),this._loader.destroy(),this._loader=null,this._loaderClass=null,this._dataSource=null,this._stashBuffer=null,this._stashUsed=this._stashSize=this._bufferSize=this._stashByteStart=0,this._currentRange=null,this._speedSampler=null,this._isEarlyEofReconnecting=!1,this._onDataArrival=null,this._onSeeked=null,this._onError=null,this._onComplete=null,this._onRedirect=null,this._onRecoveredEarlyEof=null,this._extraData=null}},{key:"isWorking",value:function(){return this._loader&&this._loader.isWorking()&&!this._paused}},{key:"isPaused",value:function(){return this._paused}},{key:"_selectSeekHandler",value:function(){var e=this._config;if("range"===e.seekType)this._seekHandler=new b.default(this._config.rangeLoadZeroStart);else if("param"===e.seekType){var t=e.seekParamStart||"bstart",n=e.seekParamEnd||"bend";this._seekHandler=new k.default(t,n)}else{if("custom"!==e.seekType)throw new L.InvalidArgumentException("Invalid seekType in config: "+e.seekType);if("function"!=typeof e.customSeekHandler)throw new L.InvalidArgumentException("Custom seekType specified in config but invalid customSeekHandler!");this._seekHandler=new e.customSeekHandler}}},{key:"_selectLoader",value:function(){if(this._isWebSocketURL)this._loaderClass=y.default;else if(f.default.isSupported())this._loaderClass=f.default;else if(_.default.isSupported())this._loaderClass=_.default;else{if(!v.default.isSupported())throw new L.RuntimeException("Your browser doesn't support xhr with arraybuffer responseType!");this._loaderClass=v.default}}},{key:"_createLoader",value:function(){this._loader=new this._loaderClass(this._seekHandler,this._config),!1===this._loader.needStashBuffer&&(this._enableStash=!1),this._loader.onContentLengthKnown=this._onContentLengthKnown.bind(this),this._loader.onURLRedirect=this._onURLRedirect.bind(this),this._loader.onDataArrival=this._onLoaderChunkArrival.bind(this),this._loader.onComplete=this._onLoaderComplete.bind(this),this._loader.onError=this._onLoaderError.bind(this)}},{key:"open",value:function(e){this._currentRange={from:0,to:-1},e&&(this._currentRange.from=e),this._speedSampler.reset(),e||(this._fullRequestFlag=!0),this._loader.open(this._dataSource,Object.assign({},this._currentRange))}},{key:"abort",value:function(){this._loader.abort(),this._paused&&(this._paused=!1,this._resumeFrom=0)}},{key:"pause",value:function(){this.isWorking()&&(this._loader.abort(),0!==this._stashUsed?(this._resumeFrom=this._stashByteStart,this._currentRange.to=this._stashByteStart-1):this._resumeFrom=this._currentRange.to+1,this._stashUsed=0,this._stashByteStart=0,this._paused=!0)}},{key:"resume",value:function(){if(this._paused){this._paused=!1;var e=this._resumeFrom;this._resumeFrom=0,this._internalSeek(e,!0)}}},{key:"seek",value:function(e){this._paused=!1,this._stashUsed=0,this._stashByteStart=0,this._internalSeek(e,!0)}},{key:"_internalSeek",value:function(e,t){this._loader.isWorking()&&this._loader.abort(),this._flushStashBuffer(t),this._loader.destroy(),this._loader=null;var n={from:e,to:-1};this._currentRange={from:n.from,to:-1},this._speedSampler.reset(),this._stashSize=this._stashInitialSize,this._createLoader(),this._loader.open(this._dataSource,n),this._onSeeked&&this._onSeeked()}},{key:"updateUrl",value:function(e){if(!e||"string"!=typeof e||0===e.length)throw new L.InvalidArgumentException("Url must be a non-empty string!");this._dataSource.url=e}},{key:"_expandBuffer",value:function(e){for(var t=this._stashSize;t+10485760){var i=new Uint8Array(this._stashBuffer,0,this._stashUsed);new Uint8Array(n,0,t).set(i,0)}this._stashBuffer=n,this._bufferSize=t}}},{key:"_normalizeSpeed",value:function(e){var t=this._speedNormalizeList,n=t.length-1,i=0,r=0,s=n;if(e=t[i]&&e=512&&e<=1024?Math.floor(1.5*e):2*e)>8192&&(t=8192);var n=1024*t+1048576;this._bufferSize0){var o=this._stashBuffer.slice(0,this._stashUsed),u=this._dispatchChunks(o,this._stashByteStart);if(u0){var l=new Uint8Array(o,u);a.set(l,0),this._stashUsed=l.byteLength,this._stashByteStart+=u}}else this._stashUsed=0,this._stashByteStart+=u;this._stashUsed+e.byteLength>this._bufferSize&&(this._expandBuffer(this._stashUsed+e.byteLength),a=new Uint8Array(this._stashBuffer,0,this._bufferSize)),a.set(new Uint8Array(e),this._stashUsed),this._stashUsed+=e.byteLength}else{var d=this._dispatchChunks(e,t);if(dthis._bufferSize&&(this._expandBuffer(h),a=new Uint8Array(this._stashBuffer,0,this._bufferSize)),a.set(new Uint8Array(e,d),0),this._stashUsed+=h,this._stashByteStart=t+d}}}else if(0===this._stashUsed){var f=this._dispatchChunks(e,t);if(fthis._bufferSize&&this._expandBuffer(c);var _=new Uint8Array(this._stashBuffer,0,this._bufferSize);_.set(new Uint8Array(e,f),0),this._stashUsed+=c,this._stashByteStart=t+f}}else{this._stashUsed+e.byteLength>this._bufferSize&&this._expandBuffer(this._stashUsed+e.byteLength);var m=new Uint8Array(this._stashBuffer,0,this._bufferSize);m.set(new Uint8Array(e),this._stashUsed),this._stashUsed+=e.byteLength;var p=this._dispatchChunks(this._stashBuffer.slice(0,this._stashUsed),this._stashByteStart);if(p0){var v=new Uint8Array(this._stashBuffer,p);m.set(v,0)}this._stashUsed-=p,this._stashByteStart+=p}}}},{key:"_flushStashBuffer",value:function(e){if(this._stashUsed>0){var t=this._stashBuffer.slice(0,this._stashUsed),n=this._dispatchChunks(t,this._stashByteStart),i=t.byteLength-n;if(n0){var r=new Uint8Array(this._stashBuffer,0,this._bufferSize),s=new Uint8Array(t,n);r.set(s,0),this._stashUsed=s.byteLength,this._stashByteStart+=n}return 0}o.default.w(this.TAG,i+" bytes unconsumed data remain when flush buffer, dropped")}return this._stashUsed=0,this._stashByteStart=0,i}return 0}},{key:"_onLoaderComplete",value:function(e,t){this._flushStashBuffer(!0),this._onComplete&&this._onComplete(this._extraData)}},{key:"_onLoaderError",value:function(e,t){switch(o.default.e(this.TAG,"Loader error, code = "+t.code+", msg = "+t.msg),this._flushStashBuffer(!1),this._isEarlyEofReconnecting&&(this._isEarlyEofReconnecting=!1,e=d.LoaderErrors.UNRECOVERABLE_EARLY_EOF),e){case d.LoaderErrors.EARLY_EOF:if(!this._config.isLive&&this._totalLength){var n=this._currentRange.to+1;return void(n0)for(var s=n.split("&"),a=0;a0;o[0]!==this._startName&&o[0]!==this._endName&&(u&&(r+="&"),r+=s[a])}return 0===r.length?t:t+"?"+r}}]),e}();n.default=s},{}],26:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=500?this.currentKBps:0}},{key:"averageKBps",get:function(){var e=(this._now()-this._firstCheckpoint)/1e3;return this._totalBytes/e/1024}}]),e}();n.default=s},{}],28:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(n,"__esModule",{value:!0});var a=function e(t,n,i){null===t&&(t=Function.prototype);var r=Object.getOwnPropertyDescriptor(t,n);if(void 0===r){var s=Object.getPrototypeOf(t);return null===s?void 0:e(s,n,i)}if("value"in r)return r.value;var a=r.get;if(void 0!==a)return a.call(i)},o=function(){function e(e,t){for(var n=0;n299)){if(this._status=h.LoaderStatus.kError,!this._onError)throw new f.RuntimeException("MozChunkedLoader: Http code invalid, "+t.status+" "+t.statusText);this._onError(h.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:t.status,msg:t.statusText})}else this._status=h.LoaderStatus.kBuffering}}},{key:"_onProgress",value:function(e){if(this._status!==h.LoaderStatus.kError){null===this._contentLength&&null!==e.total&&0!==e.total&&(this._contentLength=e.total,this._onContentLengthKnown&&this._onContentLengthKnown(this._contentLength));var t=e.target.response,n=this._range.from+this._receivedLength;this._receivedLength+=t.byteLength,this._onDataArrival&&this._onDataArrival(t,n,this._receivedLength)}}},{key:"_onLoadEnd",value:function(e){if(!0===this._requestAbort)return void(this._requestAbort=!1);this._status!==h.LoaderStatus.kError&&(this._status=h.LoaderStatus.kComplete,this._onComplete&&this._onComplete(this._range.from,this._range.from+this._receivedLength-1))}},{key:"_onXhrError",value:function(e){this._status=h.LoaderStatus.kError;var t=0,n=null;if(this._contentLength&&e.loaded=200&&t.status<=299){if(this._status=h.LoaderStatus.kBuffering,void 0!=t.responseURL){var n=this._seekHandler.removeURLParameters(t.responseURL);t.responseURL!==this._currentRequestURL&&n!==this._currentRedirectedURL&&(this._currentRedirectedURL=n,this._onURLRedirect&&this._onURLRedirect(n))}var i=t.getResponseHeader("Content-Length");if(null!=i&&null==this._contentLength){var r=parseInt(i);r>0&&(this._contentLength=r,this._onContentLengthKnown&&this._onContentLengthKnown(this._contentLength))}}else{if(this._status=h.LoaderStatus.kError,!this._onError)throw new f.RuntimeException("MSStreamLoader: Http code invalid, "+t.status+" "+t.statusText);this._onError(h.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:t.status,msg:t.statusText})}else if(3===t.readyState&&t.status>=200&&t.status<=299){this._status=h.LoaderStatus.kBuffering;var s=t.response;this._reader.readAsArrayBuffer(s)}}},{key:"_xhrOnError",value:function(e){this._status=h.LoaderStatus.kError;var t=h.LoaderErrors.EXCEPTION,n={code:-1,msg:e.constructor.name+" "+e.type};if(!this._onError)throw new f.RuntimeException(n.msg);this._onError(t,n)}},{key:"_msrOnProgress",value:function(e){var t=e.target,n=t.result;if(null==n)return void this._doReconnectIfNeeded();var i=n.slice(this._lastTimeBufferSize);this._lastTimeBufferSize=n.byteLength;var r=this._totalRange.from+this._receivedLength;this._receivedLength+=i.byteLength,this._onDataArrival&&this._onDataArrival(i,r,this._receivedLength),n.byteLength>=this._bufferLimit&&(d.default.v(this.TAG,"MSStream buffer exceeded max size near "+(r+i.byteLength)+", reconnecting..."),this._doReconnectIfNeeded())}},{key:"_doReconnectIfNeeded",value:function(){if(null==this._contentLength||this._receivedLength=this._contentLength&&(n=this._range.from+this._contentLength-1),this._currentRequestRange={from:t,to:n},this._internalOpen(this._dataSource,this._currentRequestRange)}},{key:"_internalOpen",value:function(e,t){this._lastTimeLoaded=0;var n=e.url;this._config.reuseRedirectedURL&&(void 0!=this._currentRedirectedURL?n=this._currentRedirectedURL:void 0!=e.redirectedURL&&(n=e.redirectedURL));var i=this._seekHandler.getConfig(n,t);this._currentRequestURL=i.url;var r=this._xhr=new XMLHttpRequest;if(r.open("GET",i.url,!0),r.responseType="arraybuffer",r.onreadystatechange=this._onReadyStateChange.bind(this),r.onprogress=this._onProgress.bind(this),r.onload=this._onLoad.bind(this),r.onerror=this._onXhrError.bind(this),e.withCredentials&&r.withCredentials&&(r.withCredentials=!0),"object"===o(i.headers)){var s=i.headers;for(var a in s)s.hasOwnProperty(a)&&r.setRequestHeader(a,s[a])}r.send()}},{key:"abort",value:function(){this._requestAbort=!0,this._internalAbort(),this._status=_.LoaderStatus.kComplete}},{key:"_internalAbort",value:function(){this._xhr&&(this._xhr.onreadystatechange=null,this._xhr.onprogress=null,this._xhr.onload=null,this._xhr.onerror=null,this._xhr.abort(),this._xhr=null)}},{key:"_onReadyStateChange",value:function(e){var t=e.target;if(2===t.readyState){if(void 0!=t.responseURL){var n=this._seekHandler.removeURLParameters(t.responseURL);t.responseURL!==this._currentRequestURL&&n!==this._currentRedirectedURL&&(this._currentRedirectedURL=n,this._onURLRedirect&&this._onURLRedirect(n))}if(t.status>=200&&t.status<=299){if(this._waitForTotalLength)return;this._status=_.LoaderStatus.kBuffering}else{if(this._status=_.LoaderStatus.kError,!this._onError)throw new m.RuntimeException("RangeLoader: Http code invalid, "+t.status+" "+t.statusText);this._onError(_.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:t.status,msg:t.statusText})}}}},{key:"_onProgress",value:function(e){if(this._status!==_.LoaderStatus.kError){if(null===this._contentLength){var t=!1;if(this._waitForTotalLength){this._waitForTotalLength=!1,this._totalLengthReceived=!0,t=!0;var n=e.total;this._internalAbort(),null!=n&0!==n&&(this._totalLength=n)}if(-1===this._range.to?this._contentLength=this._totalLength-this._range.from:this._contentLength=this._range.to-this._range.from+1,t)return void this._openSubRange();this._onContentLengthKnown&&this._onContentLengthKnown(this._contentLength)}var i=e.loaded-this._lastTimeLoaded;this._lastTimeLoaded=e.loaded,this._speedSampler.addBytes(i)}}},{key:"_normalizeSpeed",value:function(e){var t=this._chunkSizeKBList,n=t.length-1,i=0,r=0,s=n;if(e=t[i]&&e=3&&(t=this._speedSampler.currentKBps),0!==t){var n=this._normalizeSpeed(t);this._currentSpeedNormalized!==n&&(this._currentSpeedNormalized=n,this._currentChunkSizeKB=n)}var i=e.target.response,r=this._range.from+this._receivedLength;this._receivedLength+=i.byteLength;var s=!1;null!=this._contentLength&&this._receivedLength0&&this._receivedLength0&&(this._requestSetTime=!0,this._mediaElement.currentTime=0),this._transmuxer=new p.default(this._mediaDataSource,this._config),this._transmuxer.on(g.default.INIT_SEGMENT,function(t,n){e._msectl.appendInitSegment(n)}),this._transmuxer.on(g.default.MEDIA_SEGMENT,function(t,n){if(e._msectl.appendMediaSegment(n),e._config.lazyLoad&&!e._config.isLive){var i=e._mediaElement.currentTime;n.info.endDts>=1e3*(i+e._config.lazyLoadMaxDuration)&&null==e._progressChecker&&(d.default.v(e.TAG,"Maximum buffering duration exceeded, suspend transmuxing task"),e._suspendTransmuxer())}}),this._transmuxer.on(g.default.LOADING_COMPLETE,function(){e._msectl.endOfStream(),e._emitter.emit(_.default.LOADING_COMPLETE)}),this._transmuxer.on(g.default.RECOVERED_EARLY_EOF,function(){e._emitter.emit(_.default.RECOVERED_EARLY_EOF)}),this._transmuxer.on(g.default.IO_ERROR,function(t,n){e._emitter.emit(_.default.ERROR,k.ErrorTypes.NETWORK_ERROR,t,n)}),this._transmuxer.on(g.default.DEMUX_ERROR,function(t,n){e._emitter.emit(_.default.ERROR,k.ErrorTypes.MEDIA_ERROR,t,{code:-1,msg:n})}), +this._transmuxer.on(g.default.MEDIA_INFO,function(t){e._mediaInfo=t,e._emitter.emit(_.default.MEDIA_INFO,Object.assign({},t))}),this._transmuxer.on(g.default.STATISTICS_INFO,function(t){e._statisticsInfo=e._fillStatisticsInfo(t),e._emitter.emit(_.default.STATISTICS_INFO,Object.assign({},e._statisticsInfo))}),this._transmuxer.on(g.default.RECOMMEND_SEEKPOINT,function(t){e._mediaElement&&!e._config.accurateSeek&&(e._requestSetTime=!0,e._mediaElement.currentTime=t/1e3)}),this._transmuxer.open()}}},{key:"unload",value:function(){this._mediaElement&&this._mediaElement.pause(),this._msectl&&this._msectl.seek(0),this._transmuxer&&(this._transmuxer.close(),this._transmuxer.destroy(),this._transmuxer=null)}},{key:"play",value:function(){return this._mediaElement.play()}},{key:"pause",value:function(){this._mediaElement.pause()}},{key:"_fillStatisticsInfo",value:function(e){if(e.playerType=this._type,!(this._mediaElement instanceof HTMLVideoElement))return e;var t=!0,n=0,i=0;if(this._mediaElement.getVideoPlaybackQuality){var r=this._mediaElement.getVideoPlaybackQuality();n=r.totalVideoFrames,i=r.droppedVideoFrames}else void 0!=this._mediaElement.webkitDecodedFrameCount?(n=this._mediaElement.webkitDecodedFrameCount,i=this._mediaElement.webkitDroppedFrameCount):t=!1;return t&&(e.decodedFrames=n,e.droppedFrames=i),e}},{key:"_onmseUpdateEnd",value:function(){if(this._config.lazyLoad&&!this._config.isLive){for(var e=this._mediaElement.buffered,t=this._mediaElement.currentTime,n=0,i=0;i=t+this._config.lazyLoadMaxDuration&&null==this._progressChecker&&(d.default.v(this.TAG,"Maximum buffering duration exceeded, suspend transmuxing task"),this._suspendTransmuxer())}}},{key:"_onmseBufferFull",value:function(){d.default.v(this.TAG,"MSE SourceBuffer is full, suspend transmuxing task"),null==this._progressChecker&&this._suspendTransmuxer()}},{key:"_suspendTransmuxer",value:function(){this._transmuxer&&(this._transmuxer.pause(),null==this._progressChecker&&(this._progressChecker=window.setInterval(this._checkProgressAndResume.bind(this),1e3)))}},{key:"_checkProgressAndResume",value:function(){for(var e=this._mediaElement.currentTime,t=this._mediaElement.buffered,n=!1,i=0;i=r&&e=s-this._config.lazyLoadRecoverDuration&&(n=!0);break}}n&&(window.clearInterval(this._progressChecker),this._progressChecker=null,n&&(d.default.v(this.TAG,"Continue loading from paused position"),this._transmuxer.resume()))}},{key:"_isTimepointBuffered",value:function(e){for(var t=this._mediaElement.buffered,n=0;n=i&&e0){var r=this._mediaElement.buffered.start(0);(r<1&&e0&&t.currentTime0){var i=n.start(0);if(i<1&&t0&&(this._mediaElement.currentTime=0),this._mediaElement.preload="auto",this._mediaElement.load(),this._statisticsReporter=window.setInterval(this._reportStatisticsInfo.bind(this),this._config.statisticsInfoReportInterval)}},{key:"unload",value:function(){this._mediaElement&&(this._mediaElement.src="",this._mediaElement.removeAttribute("src")),null!=this._statisticsReporter&&(window.clearInterval(this._statisticsReporter),this._statisticsReporter=null)}},{key:"play",value:function(){return this._mediaElement.play()}},{key:"pause",value:function(){this._mediaElement.pause()}},{key:"_onvLoadedMetadata",value:function(e){null!=this._pendingSeekTime&&(this._mediaElement.currentTime=this._pendingSeekTime,this._pendingSeekTime=null),this._emitter.emit(d.default.MEDIA_INFO,this.mediaInfo)}},{key:"_reportStatisticsInfo",value:function(){this._emitter.emit(d.default.STATISTICS_INFO,this.statisticsInfo)}},{key:"type",get:function(){return this._type}},{key:"buffered",get:function(){return this._mediaElement.buffered}},{key:"duration",get:function(){return this._mediaElement.duration}},{key:"volume",get:function(){return this._mediaElement.volume},set:function(e){this._mediaElement.volume=e}},{key:"muted",get:function(){return this._mediaElement.muted},set:function(e){this._mediaElement.muted=e}},{key:"currentTime",get:function(){return this._mediaElement?this._mediaElement.currentTime:0},set:function(e){this._mediaElement?this._mediaElement.currentTime=e:this._pendingSeekTime=e}},{key:"mediaInfo",get:function(){var e=this._mediaElement instanceof HTMLAudioElement?"audio/":"video/",t={mimeType:e+this._mediaDataSource.type};return this._mediaElement&&(t.duration=Math.floor(1e3*this._mediaElement.duration),this._mediaElement instanceof HTMLVideoElement&&(t.width=this._mediaElement.videoWidth,t.height=this._mediaElement.videoHeight)),t}},{key:"statisticsInfo",get:function(){var e={playerType:this._type,url:this._mediaDataSource.url};if(!(this._mediaElement instanceof HTMLVideoElement))return e;var t=!0,n=0,i=0;if(this._mediaElement.getVideoPlaybackQuality){var r=this._mediaElement.getVideoPlaybackQuality();n=r.totalVideoFrames,i=r.droppedVideoFrames}else void 0!=this._mediaElement.webkitDecodedFrameCount?(n=this._mediaElement.webkitDecodedFrameCount,i=this._mediaElement.webkitDroppedFrameCount):t=!1;return t&&(e.decodedFrames=n,e.droppedFrames=i),e}}]),e}();n.default=c},{"../config.js":5,"../utils/exception.js":40,"./player-events.js":35,events:2}],34:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.ErrorDetails=n.ErrorTypes=void 0;var i=e("../io/loader.js"),r=e("../demux/demux-errors.js"),s=function(e){return e&&e.__esModule?e:{default:e}}(r);n.ErrorTypes={NETWORK_ERROR:"NetworkError",MEDIA_ERROR:"MediaError",OTHER_ERROR:"OtherError"},n.ErrorDetails={NETWORK_EXCEPTION:i.LoaderErrors.EXCEPTION,NETWORK_STATUS_CODE_INVALID:i.LoaderErrors.HTTP_STATUS_CODE_INVALID,NETWORK_TIMEOUT:i.LoaderErrors.CONNECTING_TIMEOUT,NETWORK_UNRECOVERABLE_EARLY_EOF:i.LoaderErrors.UNRECOVERABLE_EARLY_EOF,MEDIA_MSE_ERROR:"MediaMSEError",MEDIA_FORMAT_ERROR:s.default.FORMAT_ERROR,MEDIA_FORMAT_UNSUPPORTED:s.default.FORMAT_UNSUPPORTED,MEDIA_CODEC_UNSUPPORTED:s.default.CODEC_UNSUPPORTED}},{"../demux/demux-errors.js":16,"../io/loader.js":24}],35:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i={ERROR:"error",LOADING_COMPLETE:"loading_complete",RECOVERED_EARLY_EOF:"recovered_early_eof",MEDIA_INFO:"media_info",STATISTICS_INFO:"statistics_info"};n.default=i},{}],36:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n>>24&255,n[1]=t>>>16&255,n[2]=t>>>8&255,n[3]=255&t,n.set(e,4);for(var a=8,o=0;o>>24&255,t>>>16&255,t>>>8&255,255&t,n>>>24&255,n>>>16&255,n>>>8&255,255&n,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]))}},{key:"trak",value:function(t){return e.box(e.types.trak,e.tkhd(t),e.mdia(t))}},{key:"tkhd",value:function(t){var n=t.id,i=t.duration,r=t.presentWidth,s=t.presentHeight;return e.box(e.types.tkhd,new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,0,0,0,0,i>>>24&255,i>>>16&255,i>>>8&255,255&i,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,r>>>8&255,255&r,0,0,s>>>8&255,255&s,0,0]))}},{key:"mdia",value:function(t){return e.box(e.types.mdia,e.mdhd(t),e.hdlr(t),e.minf(t))}},{key:"mdhd",value:function(t){var n=t.timescale,i=t.duration;return e.box(e.types.mdhd,new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,i>>>24&255,i>>>16&255,i>>>8&255,255&i,85,196,0,0]))}},{key:"hdlr",value:function(t){var n=null;return n="audio"===t.type?e.constants.HDLR_AUDIO:e.constants.HDLR_VIDEO,e.box(e.types.hdlr,n)}},{key:"minf",value:function(t){var n=null;return n="audio"===t.type?e.box(e.types.smhd,e.constants.SMHD):e.box(e.types.vmhd,e.constants.VMHD),e.box(e.types.minf,n,e.dinf(),e.stbl(t))}},{key:"dinf",value:function(){return e.box(e.types.dinf,e.box(e.types.dref,e.constants.DREF))}},{key:"stbl",value:function(t){return e.box(e.types.stbl,e.stsd(t),e.box(e.types.stts,e.constants.STTS),e.box(e.types.stsc,e.constants.STSC),e.box(e.types.stsz,e.constants.STSZ),e.box(e.types.stco,e.constants.STCO))}},{key:"stsd",value:function(t){return"audio"===t.type?"mp3"===t.codec?e.box(e.types.stsd,e.constants.STSD_PREFIX,e.mp3(t)):e.box(e.types.stsd,e.constants.STSD_PREFIX,e.mp4a(t)):e.box(e.types.stsd,e.constants.STSD_PREFIX,e.avc1(t))}},{key:"mp3",value:function(t){var n=t.channelCount,i=t.audioSampleRate,r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,n,0,16,0,0,0,0,i>>>8&255,255&i,0,0]);return e.box(e.types[".mp3"],r)}},{key:"mp4a",value:function(t){var n=t.channelCount,i=t.audioSampleRate,r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,n,0,16,0,0,0,0,i>>>8&255,255&i,0,0]);return e.box(e.types.mp4a,r,e.esds(t))}},{key:"esds",value:function(t){var n=t.config||[],i=n.length,r=new Uint8Array([0,0,0,0,3,23+i,0,1,0,4,15+i,64,21,0,0,0,0,0,0,0,0,0,0,0,5].concat([i]).concat(n).concat([6,1,2]));return e.box(e.types.esds,r)}},{key:"avc1",value:function(t){var n=t.avcc,i=t.codecWidth,r=t.codecHeight,s=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i>>>8&255,255&i,r>>>8&255,255&r,0,72,0,0,0,72,0,0,0,0,0,0,0,1,10,120,113,113,47,102,108,118,46,106,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,255,255]);return e.box(e.types.avc1,s,e.box(e.types.avcC,n))}},{key:"mvex",value:function(t){return e.box(e.types.mvex,e.trex(t))}},{key:"trex",value:function(t){var n=t.id,i=new Uint8Array([0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return e.box(e.types.trex,i)}},{key:"moof",value:function(t,n){return e.box(e.types.moof,e.mfhd(t.sequenceNumber),e.traf(t,n))}},{key:"mfhd",value:function(t){var n=new Uint8Array([0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,255&t]);return e.box(e.types.mfhd,n)}},{key:"traf",value:function(t,n){var i=t.id,r=e.box(e.types.tfhd,new Uint8Array([0,0,0,0,i>>>24&255,i>>>16&255,i>>>8&255,255&i])),s=e.box(e.types.tfdt,new Uint8Array([0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n])),a=e.sdtp(t),o=e.trun(t,a.byteLength+16+16+8+16+8+8);return e.box(e.types.traf,r,s,o,a)}},{key:"sdtp",value:function(t){for(var n=t.samples||[],i=n.length,r=new Uint8Array(4+i),s=0;s>>24&255,r>>>16&255,r>>>8&255,255&r,n>>>24&255,n>>>16&255,n>>>8&255,255&n],0);for(var o=0;o>>24&255,u>>>16&255,u>>>8&255,255&u,l>>>24&255,l>>>16&255,l>>>8&255,255&l,d.isLeading<<2|d.dependsOn,d.isDependedOn<<6|d.hasRedundancy<<4|d.isNonSync,0,0,h>>>24&255,h>>>16&255,h>>>8&255,255&h],12+16*o)}return e.box(e.types.trun,a)}},{key:"mdat",value:function(t){return e.box(e.types.mdat,t)}}]),e}();s.init(),n.default=s},{}],38:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n=1?A[A.length-1].duration:Math.floor(a);var D=!1,B=null;if(M>1.5*a&&"mp3"!==this._audioMeta.codec&&this._fillAudioTimestampGap&&!c.default.safari){D=!0;var j=Math.abs(M-a),P=Math.ceil(j/a),U=x+a;o.default.w(this.TAG,"Large audio timestamp gap detected, may cause AV sync to drift. Silent frames will be generated to avoid unsync.\ndts: "+(x+M)+" ms, expected: "+(x+Math.round(a))+" ms, delta: "+Math.round(j)+" ms, generate: "+P+" frames");var N=h.default.getSilentFrame(this._audioMeta.originalCodec,this._audioMeta.channelCount);null==N&&(o.default.w(this.TAG,"Unable to generate silent frame for "+this._audioMeta.originalCodec+" with "+this._audioMeta.channelCount+" channels, repeat last frame"),N=C),B=[];for(var F=0;F0){var V=B[B.length-1];V.duration=G-V.dts}var z={dts:G,pts:G,cts:0,unit:N,size:N.byteLength,duration:0,originalDts:I,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0}};B.push(z),v+=C.byteLength,U+=a}var H=B[B.length-1];H.duration=x+M-H.dts,M=Math.round(a)}A.push({dts:x,pts:x,cts:0,unit:T.unit,size:T.unit.byteLength,duration:M,originalDts:I,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0}}),D&&A.push.apply(A,B)}u?p=new Uint8Array(v):(p=new Uint8Array(v),p[0]=v>>>24&255,p[1]=v>>>16&255,p[2]=v>>>8&255,p[3]=255&v,p.set(l.default.types.mdat,4));for(var K=0;K>>24&255,h[1]=d>>>16&255,h[2]=d>>>8&255,h[3]=255&d,h.set(l.default.types.mdat,4);var f=n[0].dts-this._dtsBase;if(this._videoNextDts)i=f-this._videoNextDts;else if(this._videoSegmentInfoList.isEmpty())i=0;else{var c=this._videoSegmentInfoList.getLastSampleBefore(f);if(null!=c){var m=f-(c.originalDts+c.duration);m<=3&&(m=0);var p=c.dts+c.duration+m;i=f-p}else i=0}for(var v=new _.MediaSegmentInfo,g=[],y=0;y=1?g[g.length-1].duration:Math.floor(this._videoMeta.refSampleDuration);if(S){var A=new _.SampleInfo(k,w,R,E.dts,!0);A.fileposition=E.fileposition,v.appendSyncPoint(A)}g.push({dts:k,pts:w,cts:L,units:E.units,size:E.length,isKeyframe:S,duration:R,originalDts:b,flags:{isLeading:0,dependsOn:S?2:1,isDependedOn:S?1:0,hasRedundancy:0,isNonSync:S?0:1}})}for(var O=0;O=0&&/(rv)(?::| )([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(firefox)[ \/]([\w.]+)/.exec(e)||[],n=/(ipad)/.exec(e)||/(ipod)/.exec(e)||/(windows phone)/.exec(e)||/(iphone)/.exec(e)||/(kindle)/.exec(e)||/(android)/.exec(e)||/(windows)/.exec(e)||/(mac)/.exec(e)||/(linux)/.exec(e)||/(cros)/.exec(e)||[],r={browser:t[5]||t[3]||t[1]||"",version:t[2]||t[4]||"0",majorVersion:t[4]||t[2]||"0",platform:n[0]||""},s={};if(r.browser){s[r.browser]=!0;var a=r.majorVersion.split(".");s.version={major:parseInt(r.majorVersion,10),string:r.version},a.length>1&&(s.version.minor=parseInt(a[1],10)),a.length>2&&(s.version.build=parseInt(a[2],10))}r.platform&&(s[r.platform]=!0), +(s.chrome||s.opr||s.safari)&&(s.webkit=!0),(s.rv||s.iemobile)&&(s.rv&&delete s.rv,r.browser="msie",s.msie=!0),s.edge&&(delete s.edge,r.browser="msedge",s.msedge=!0),s.opr&&(r.browser="opera",s.opera=!0),s.safari&&s.android&&(r.browser="android",s.android=!0),s.name=r.browser,s.platform=r.platform;for(var o in i)i.hasOwnProperty(o)&&delete i[o];Object.assign(i,s)}(),n.default=i},{}],40:[function(e,t,n){"use strict";function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function r(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","error",i),e.ENABLE_ERROR&&(console.error?console.error(i):console.warn?console.warn(i):console.log(i))}},{key:"i",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","info",i),e.ENABLE_INFO&&(console.info?console.info(i):console.log(i))}},{key:"w",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","warn",i),e.ENABLE_WARN&&(console.warn?console.warn(i):console.log(i))}},{key:"d",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","debug",i),e.ENABLE_DEBUG&&(console.debug?console.debug(i):console.log(i))}},{key:"v",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","verbose",i),e.ENABLE_VERBOSE&&console.log(i)}}]),e}();o.GLOBAL_TAG="flv.js",o.FORCE_GLOBAL_TAG=!1,o.ENABLE_ERROR=!0,o.ENABLE_INFO=!0,o.ENABLE_WARN=!0,o.ENABLE_DEBUG=!0,o.ENABLE_VERBOSE=!0,o.ENABLE_CALLBACK=!1,o.emitter=new a.default,n.default=o},{events:2}],42:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0){var n=e.getConfig();t.emit("change",n)}}},{key:"registerListener",value:function(t){e.emitter.addListener("change",t)}},{key:"removeListener",value:function(t){e.emitter.removeListener("change",t)}},{key:"addLogListener",value:function(t){l.default.emitter.addListener("log",t),l.default.emitter.listenerCount("log")>0&&(l.default.ENABLE_CALLBACK=!0,e._notifyChange())}},{key:"removeLogListener",value:function(t){l.default.emitter.removeListener("log",t),0===l.default.emitter.listenerCount("log")&&(l.default.ENABLE_CALLBACK=!1,e._notifyChange())}},{key:"forceGlobalTag",get:function(){return l.default.FORCE_GLOBAL_TAG},set:function(t){l.default.FORCE_GLOBAL_TAG=t,e._notifyChange()}},{key:"globalTag",get:function(){return l.default.GLOBAL_TAG},set:function(t){l.default.GLOBAL_TAG=t,e._notifyChange()}},{key:"enableAll",get:function(){return l.default.ENABLE_VERBOSE&&l.default.ENABLE_DEBUG&&l.default.ENABLE_INFO&&l.default.ENABLE_WARN&&l.default.ENABLE_ERROR},set:function(t){l.default.ENABLE_VERBOSE=t,l.default.ENABLE_DEBUG=t,l.default.ENABLE_INFO=t,l.default.ENABLE_WARN=t,l.default.ENABLE_ERROR=t,e._notifyChange()}},{key:"enableDebug",get:function(){return l.default.ENABLE_DEBUG},set:function(t){l.default.ENABLE_DEBUG=t,e._notifyChange()}},{key:"enableVerbose",get:function(){return l.default.ENABLE_VERBOSE},set:function(t){l.default.ENABLE_VERBOSE=t,e._notifyChange()}},{key:"enableInfo",get:function(){return l.default.ENABLE_INFO},set:function(t){l.default.ENABLE_INFO=t,e._notifyChange()}},{key:"enableWarn",get:function(){return l.default.ENABLE_WARN},set:function(t){l.default.ENABLE_WARN=t,e._notifyChange()}},{key:"enableError",get:function(){return l.default.ENABLE_ERROR},set:function(t){l.default.ENABLE_ERROR=t,e._notifyChange()}}]),e}();d.emitter=new o.default,n.default=d},{"./logger.js":41,events:2}],43:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=128){t.push(String.fromCharCode(65535&a)),r+=2;continue}}}else if(n[r]<240){if(i(n,r,2)){var o=(15&n[r])<<12|(63&n[r+1])<<6|63&n[r+2];if(o>=2048&&55296!=(63488&o)){t.push(String.fromCharCode(65535&o)),r+=3;continue}}}else if(n[r]<248&&i(n,r,3)){var u=(7&n[r])<<18|(63&n[r+1])<<12|(63&n[r+2])<<6|63&n[r+3];if(u>65536&&u<1114112){u-=65536,t.push(String.fromCharCode(u>>>10|55296)),t.push(String.fromCharCode(1023&u|56320)),r+=4;continue}}t.push(String.fromCharCode(65533)),++r}return t.join("")}Object.defineProperty(n,"__esModule",{value:!0}),n.default=r},{}]},{},[21])(21)}); +//# sourceMappingURL=flv.min.js.map diff --git a/tools/FLV Stream/flv.min.js.map b/tools/FLV Stream/flv.min.js.map new file mode 100644 index 0000000..05e110e --- /dev/null +++ b/tools/FLV Stream/flv.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/es6-promise/dist/es6-promise.js","node_modules/events/events.js","node_modules/process/browser.js","node_modules/webworkify/index.js","src/config.js","src/core/features.js","src/core/media-info.js","src/core/media-segment-info.js","src/core/mse-controller.js","src/core/mse-events.js","src/core/transmuxer.js","src/core/transmuxing-controller.js","src/core/transmuxing-events.js","src/core/transmuxing-worker.js","src/demux/amf-parser.js","src/demux/demux-errors.js","src/demux/exp-golomb.js","src/demux/flv-demuxer.js","src/demux/sps-parser.js","src/flv.js","src/index.js","src/io/fetch-stream-loader.js","src/io/io-controller.js","src/io/loader.js","src/io/param-seek-handler.js","src/io/range-seek-handler.js","src/io/speed-sampler.js","src/io/websocket-loader.js","src/io/xhr-moz-chunked-loader.js","src/io/xhr-msstream-loader.js","src/io/xhr-range-loader.js","src/player/flv-player.js","src/player/native-player.js","src/player/player-errors.js","src/player/player-events.js","src/remux/aac-silent.js","src/remux/mp4-generator.js","src/remux/mp4-remuxer.js","src/utils/browser.js","src/utils/exception.js","src/utils/logger.js","src/utils/logging-control.js","src/utils/polyfill.js","src/utils/utf8-conv.js"],"names":["f","exports","module","define","amd","g","window","global","self","this","flvjs","e","t","n","r","s","o","u","a","require","i","Error","code","l","call","length","1","_dereq_","factory","ES6Promise","objectOrFunction","x","isFunction","setScheduler","scheduleFn","customSchedulerFn","setAsap","asapFn","asap","useVertxTimer","vertxNext","flush","useSetTimeout","globalSetTimeout","setTimeout","len","callback","queue","undefined","then","onFulfillment","onRejection","_arguments","arguments","parent","child","constructor","noop","PROMISE_ID","makePromise","_state","invokeCallback","_result","subscribe","resolve","object","Constructor","promise","_resolve","selfFulfillment","TypeError","cannotReturnOwn","getThen","error","GET_THEN_ERROR","tryThen","value","fulfillmentHandler","rejectionHandler","handleForeignThenable","thenable","sealed","fulfill","reason","_reject","_label","handleOwnThenable","FULFILLED","REJECTED","handleMaybeThenable","maybeThenable","then$$","publishRejection","_onerror","publish","PENDING","_subscribers","subscribers","settled","detail","ErrorObject","tryCatch","TRY_CATCH_ERROR","hasCallback","succeeded","failed","initializePromise","resolver","nextId","id","Enumerator","input","_instanceConstructor","isArray","_input","_remaining","Array","_enumerate","validationError","all","entries","race","reject","_","needsResolver","needsNew","Promise","polyfill","local","Function","P","promiseToString","Object","prototype","toString","cast","_isArray","arg","scheduleFlush","browserWindow","browserGlobal","BrowserMutationObserver","MutationObserver","WebKitMutationObserver","isNode","process","isWorker","Uint8ClampedArray","importScripts","MessageChannel","nextTick","iterations","observer","node","document","createTextNode","observe","characterData","data","channel","port1","onmessage","port2","postMessage","vertx","runOnLoop","runOnContext","Math","random","substring","_eachEntry","entry","c","resolve$$","_then","_settledAt","_willSettleAt","state","enumerator","_setScheduler","_setAsap","_asap","catch","EventEmitter","_events","_maxListeners","isNumber","isObject","isUndefined","defaultMaxListeners","setMaxListeners","isNaN","emit","type","er","handler","args","listeners","err","context","slice","apply","addListener","listener","m","newListener","push","warned","console","trace","on","once","removeListener","fired","list","position","splice","removeAllListeners","key","listenerCount","evlistener","emitter","defaultSetTimout","defaultClearTimeout","runTimeout","fun","cachedSetTimeout","runClearTimeout","marker","cachedClearTimeout","clearTimeout","cleanUpNextTick","draining","currentQueue","concat","queueIndex","drainQueue","timeout","run","Item","array","title","browser","env","argv","version","versions","off","prependListener","prependOnceListener","name","binding","cwd","chdir","dir","umask","bundleFn","sources","cache","stringify","JSON","fn","options","resolveSources","workerSources","depPath","depKey","wkey","cacheKeys","keys","exp","default","floor","pow","wcache","skey","scache","src","map","join","URL","webkitURL","mozURL","msURL","blob","Blob","bare","workerUrl","createObjectURL","worker","Worker","objectURL","createDefaultConfig","assign","defaultConfig","enableWorker","enableStashBuffer","stashInitialSize","isLive","lazyLoad","lazyLoadMaxDuration","lazyLoadRecoverDuration","deferLoadAfterSourceOpen","autoCleanupMaxBackwardDuration","autoCleanupMinBackwardDuration","statisticsInfoReportInterval","fixAudioTimestampGap","accurateSeek","seekType","seekParamStart","seekParamEnd","rangeLoadZeroStart","customSeekHandler","reuseRedirectedURL","_ioController","_config","Features","MediaSource","isTypeSupported","ioctl","_ioController2","loaderType","destroy","mimeType","videoElement","createElement","canPlay","canPlayType","features","mseFlvPlayback","mseLiveFlvPlayback","networkStreamIO","networkLoaderName","nativeMP4H264Playback","nativeWebmVP8Playback","nativeWebmVP9Playback","supportMSEH264Playback","supportNetworkStreamIO","getNetworkLoaderTypeName","supportNativeMediaPlayback","MediaInfo","_classCallCheck","duration","hasAudio","hasVideo","audioCodec","videoCodec","audioDataRate","videoDataRate","audioSampleRate","audioChannelCount","width","height","fps","profile","level","chromaFormat","sarNum","sarDen","metadata","segments","segmentCount","hasKeyframesIndex","keyframesIndex","audioInfoComplete","videoInfoComplete","milliseconds","table","keyframeIdx","_search","times","index","fileposition","filepositions","idx","last","mid","lbound","ubound","SampleInfo","dts","pts","originalDts","isSync","isSyncPoint","MediaSegmentInfo","beginDts","endDts","beginPts","endPts","originalBeginDts","originalEndDts","syncPoints","firstSample","lastSample","sampleInfo","IDRSampleList","_list","clear","MediaSegmentInfoList","_type","_lastAppendLocation","_searchNearestSegmentBefore","mediaSegmentInfo","msi","lastAppendIdx","insertIdx","segment","getLastSegmentBefore","segmentIdx","_logger","_browser","_mseEvents","_mediaSegmentInfo","_exception","MSEController","config","TAG","_emitter","_events2","autoCleanupSourceBuffer","onSourceOpen","_onSourceOpen","bind","onSourceEnded","_onSourceEnded","onSourceClose","_onSourceClose","onSourceBufferError","_onSourceBufferError","onSourceBufferUpdateEnd","_onSourceBufferUpdateEnd","_mediaSource","_mediaSourceObjectURL","_mediaElement","_isBufferFull","_hasPendingEos","_requireSetMediaDuration","_pendingMediaDuration","_pendingSourceBufferInit","_mimeTypes","video","audio","_sourceBuffers","_lastInitSegments","_pendingSegments","_pendingRemoveRanges","_idrList","detachMediaElement","event","mediaElement","IllegalStateException","ms","addEventListener","ps","sb","readyState","removeSourceBuffer","removeEventListener","endOfStream","_logger2","message","removeAttribute","revokeObjectURL","initSegment","deferred","is","container","codec","firstInitSegment","v","addSourceBuffer","_mseEvents2","ERROR","msg","updating","_doAppendSegments","_browser2","safari","mediaDuration","_updateMediaSourceDuration","mediaSegment","_needCleanupSourceBuffer","_doCleanupSourceBuffer","_hasPendingRemoveRanges","seconds","abort","buffered","start","end","_doRemoveRanges","lastInitSegment","_hasPendingSegments","getLastSyncPointBeforeDts","currentTime","doRemove","removeEnd","current","target","ranges","range","shift","remove","pendingSegments","timestampOffset","currentOffset","targetOffset","delta","abs","byteLength","appendBuffer","hasOwnProperty","appendArray","info","unshift","BUFFER_FULL","pendings","appendInitSegment","SOURCE_OPEN","prr","UPDATE_END","MSEEvents","_loggingControl","_transmuxingController","_transmuxingEvents","_transmuxingWorker","_mediaInfo","Transmuxer","mediaDataSource","work","_worker","_transmuxingWorker2","_workerDestroying","_onWorkerMessage","cmd","param","onLoggingConfigChanged","_onLoggingConfigChanged","_loggingControl2","registerListener","getConfig","_controller","_transmuxingController2","ctl","_transmuxingEvents2","IO_ERROR","_onIOError","DEMUX_ERROR","_onDemuxError","INIT_SEGMENT","_onInitSegment","MEDIA_SEGMENT","_onMediaSegment","LOADING_COMPLETE","_onLoadingComplete","RECOVERED_EARLY_EOF","_onRecoveredEarlyEof","MEDIA_INFO","_onMediaInfo","STATISTICS_INFO","_onStatisticsInfo","RECOMMEND_SEEKPOINT","_onRecommendSeekpoint","stop","seek","pause","resume","_this","_this2","_this3","_this4","mediaInfo","_this5","statisticsInfo","_this6","_this7","_this8","_this9","terminate","setPrototypeOf","_mediaInfo2","logcat","_flvDemuxer","_mp4Remuxer","_demuxErrors","TransmuxingController","filesize","url","cors","withCredentials","_mediaDataSource","_currentSegmentIndex","totalDuration","forEach","timestampBase","referrerPolicy","_demuxer","_remuxer","_ioctl","_pendingSeekTime","_pendingResolveSeekPoint","_statisticsReporter","_disableStatisticsReporter","_loadSegment","_enableStatisticsReporter","segmentIndex","optionalFrom","dataSource","onError","_onIOException","onSeeked","_onIOSeeked","onComplete","_onIOComplete","onRedirect","_onIORedirect","onRecoveredEarlyEof","_onIORecoveredEarlyEof","bindDataSource","onDataArrival","_onInitChunkArrival","open","_internalAbort","isWorking","isPaused","isSeekable","targetSegmentIndex","_searchSegmentIndexContains","segmentInfo","keyframe","getNearestKeyframe","targetSegmentInfo","insertDiscontinuity","_keyframe","resetMediaInfo","_reportSegmentMediaInfo","byteStart","probeData","consumed","parseChunks","_flvDemuxer2","probe","match","_mp4Remuxer2","mds","overridedDuration","overridedHasAudio","overridedHasVideo","_onDemuxException","onMediaInfo","onInitSegment","_onRemuxerInitSegmentArrival","onMediaSegment","_onRemuxerMediaSegmentArrival","_demuxErrors2","FORMAT_UNSUPPORTED","extraData","nextSegmentIndex","redirectedURL","seekpoint","setInterval","_reportStatisticsInfo","clearInterval","exportInfo","currentURL","hasRedirect","currentRedirectedURL","speed","currentSpeed","currentSegmentIndex","totalSegmentCount","TransmuxingEvents","_polyfill","TransmuxingWorker","obj","onLoadingComplete","onStatisticsInfo","statInfo","onIOError","onDemuxError","onRecommendSeekpoint","onLogcatCallback","str","controller","logcatListener","_polyfill2","install","applyConfig","enableCallback","addLogListener","removeLogListener","_utf8Conv","le","buf","ArrayBuffer","DataView","setInt16","Int16Array","AMF","arrayBuffer","dataOffset","dataSize","parseValue","size","parseString","isObjectEnd","objectEnd","parseObject","getUint16","_utf8Conv2","Uint8Array","getUint32","timestamp","getFloat64","getInt16","Date","offset","getUint8","amfstr","terminal","amfobj","_terminal","amfvar","parseVariable","strictArrayLength","val","date","parseDate","amfLongStr","w","DemuxErrors","OK","FORMAT_ERROR","CODEC_UNSUPPORTED","ExpGolomb","uint8array","_buffer","_buffer_index","_total_bytes","_total_bits","_current_word","_current_word_bits_left","buffer_bytes_left","bytes_read","min","word","set","subarray","buffer","bits","InvalidArgumentException","result","bits_need_left","_fillCurrentWord","bits_read_next","result2","readBits","zero_count","_skipLeadingZero","leading_zeros","readUEG","ReadBig32","_amfParser","_spsParser","FLVDemuxer","_onError","_onTrackMetadata","_onDataAvailable","_dataOffset","_firstParse","_dispatch","_hasAudio","hasAudioTrack","_hasVideo","hasVideoTrack","_hasAudioFlagOverrided","_hasVideoFlagOverrided","_audioInitialMetadataDispatched","_videoInitialMetadataDispatched","_metadata","_audioMetadata","_videoMetadata","_naluLengthSize","_timestampBase","_timescale","_duration","_durationOverrided","_referenceFrameRate","fixed","fps_num","fps_den","_flvSoundRateTable","_mpegSamplingRates","_mpegAudioV10SampleRateTable","_mpegAudioV20SampleRateTable","_mpegAudioV25SampleRateTable","_mpegAudioL1BitRateTable","_mpegAudioL2BitRateTable","_mpegAudioL3BitRateTable","_videoTrack","sequenceNumber","samples","_audioTrack","_littleEndian","loader","chunk","_v","tagType","ts2","ts1","ts0","ts3","_parseAudioData","_parseVideoData","_parseScriptData","prevTagSize","_isInitialMetadataDispatched","scriptData","_amfParser2","parseScriptData","onMetaData","_typeof","audiodatarate","videodatarate","framerate","keyframes","_parseKeyframesIndex","isComplete","time","tagTimestamp","soundSpec","soundFormat","soundRate","soundRateIndex","soundType","meta","track","timescale","channelCount","aacData","_parseAACAudioData","packetType","misc","samplingRate","originalCodec","refSampleDuration","mi","aacSample","unit","_misc","_parseMP3AudioData","_mi","bitRate","_dts","mp3Sample","_parseAACAudioSpecificConfig","audioObjectType","originalAudioObjectType","samplingIndex","extensionSamplingIndex","samplingFrequence","channelConfig","userAgent","navigator","toLowerCase","indexOf","requestHeader","ver","layer","bitrate_index","sampling_freq_index","channel_mode","channel_count","sample_rate","bit_rate","tagPosition","spec","frameType","codecId","_parseAVCVideoPacket","cts","_parseAVCDecoderConfigurationRecord","_parseAVCVideoData","avcc","avcProfile","spsCount","sps","_spsParser2","parseSPS","codecWidth","codec_size","codecHeight","presentWidth","present_size","presentHeight","profile_string","level_string","bitDepth","bit_depth","chroma_format","sarRatio","sar_ratio","frameRate","frame_rate","codecArray","codecString","j","h","chroma_format_string","ppsCount","_i","_len","units","lengthSize","naluSize","unitType","avcSample","isKeyframe","base","mismatch","_expGolomb","SPSParser","src_length","dst","dst_idx","rbsp","_ebsp2rbsp","gb","_expGolomb2","readByte","profile_idc","level_idc","getProfileString","getLevelString","chroma_format_idc","chroma_format_table","readBool","scaling_list_count","_skipScalingList","pic_order_cnt_type","readSEG","num_ref_frames_in_pic_order_cnt_cycle","pic_width_in_mbs_minus1","pic_height_in_map_units_minus1","frame_mbs_only_flag","frame_crop_left_offset","frame_crop_right_offset","frame_crop_top_offset","frame_crop_bottom_offset","sar_width","sar_height","fps_fixed","aspect_ratio_idc","sar_w_table","sar_h_table","num_units_in_tick","time_scale","sarScale","crop_unit_x","crop_unit_y","sub_wc","sub_hc","codec_width","codec_height","present_width","ceil","getChromaFormatString","count","last_scale","next_scale","delta_scale","toFixed","chroma","createPlayer","optionalConfig","_flvPlayer2","_nativePlayer2","isSupported","_features2","getFeatureList","_features","_flvPlayer","_nativePlayer","_playerEvents","_playerErrors","Events","_playerEvents2","ErrorTypes","ErrorDetails","FlvPlayer","NativePlayer","LoggingControl","defineProperty","enumerable","get","_loader","FetchStreamLoader","seekHandler","_possibleConstructorReturn","__proto__","getPrototypeOf","_seekHandler","_needStash","_requestAbort","_contentLength","_receivedLength","isWorkWellEdge","msedge","minor","browserNotBlacklisted","fetch","ReadableStream","_get","_dataSource","_range","sourceURL","seekConfig","headers","Headers","configHeaders","append","params","method","mode","credentials","_status","LoaderStatus","kConnecting","res","kIdle","ok","status","_onURLRedirect","removeURLParameters","lengthHeader","parseInt","_onContentLengthKnown","_pump","body","getReader","kError","RuntimeException","statusText","LoaderErrors","HTTP_STATUS_CODE_INVALID","EXCEPTION","reader","read","done","kComplete","_onComplete","from","cancel","kBuffering","_onDataArrival","EARLY_EOF","_speedSampler","_fetchStreamLoader","_xhrMozChunkedLoader","_xhrMsstreamLoader","_xhrRangeLoader","_websocketLoader","_rangeSeekHandler","_paramSeekHandler","IOController","_extraData","_stashInitialSize","_stashUsed","_stashSize","_bufferSize","_stashBuffer","_stashByteStart","_enableStash","_loaderClass","_isWebSocketURL","test","_refTotalLength","_totalLength","_fullRequestFlag","_currentRange","_redirectedURL","_speedNormalized","_speedSampler2","_speedNormalizeList","_isEarlyEofReconnecting","_paused","_resumeFrom","_onSeeked","_onRedirect","_selectSeekHandler","_selectLoader","_createLoader","_rangeSeekHandler2","paramStart","paramEnd","_paramSeekHandler2","_websocketLoader2","_fetchStreamLoader2","_xhrMozChunkedLoader2","_xhrRangeLoader2","needStashBuffer","onContentLengthKnown","onURLRedirect","_onLoaderChunkArrival","_onLoaderComplete","_onLoaderError","to","reset","bytes","_internalSeek","dropUnconsumed","_flushStashBuffer","requestRange","expectedBytes","bufferNewSize","newBuffer","stashOldArray","normalized","stashSizeKB","bufferSize","_expandBuffer","chunks","contentLength","receivedLength","addBytes","KBps","lastSecondKBps","_normalizeSpeed","_adjustStashSize","_stashArray2","_stashArray3","_consumed2","_dispatchChunks","_remainArray","_consumed3","_remain","remain","stashArray","_stashArray","_consumed","remainArray","UNRECOVERABLE_EARLY_EOF","nextFrom","CONNECTING_TIMEOUT","BaseLoader","typeName","NotImplementedException","ParamSeekHandler","_startName","_endName","baseUrl","needAnd","seekedURL","baseURL","split","queryIndex","resultParams","pairs","pair","requireAnd","RangeSeekHandler","zeroStart","_zeroStart","SpeedSampler","_firstCheckpoint","_lastCheckpoint","_intervalBytes","_totalBytes","_lastSecondBytes","performance","now","_now","durationSeconds","currentKBps","WebSocketLoader","_ws","WebSocket","ws","binaryType","onopen","_onWebSocketOpen","onclose","_onWebSocketClose","_onWebSocketMessage","onerror","_onWebSocketError","close","_dispatchArrayBuffer","FileReader","onload","readAsArrayBuffer","arraybuffer","MozChunkedLoader","_xhr","xhr","XMLHttpRequest","responseType","onreadystatechange","onprogress","onloadend","_requestURL","_onReadyStateChange","_onProgress","_onLoadEnd","_onXhrError","setRequestHeader","send","responseURL","total","response","loaded","MSStreamLoader","_reader","_totalRange","_currentRequestURL","_currentRedirectedURL","_bufferLimit","_lastTimeBufferSize","_isReconnecting","MSStream","MSStreamReader","_internalOpen","isSubrange","_msrOnProgress","_msrOnLoad","_msrOnError","_xhrOnReadyStateChange","_xhrOnError","getResponseHeader","msstream","bigbuffer","_doReconnectIfNeeded","RangeLoader","_chunkSizeKBList","_currentChunkSizeKB","_currentSpeedNormalized","_zeroSpeedChunkCount","_waitForTotalLength","_totalLengthReceived","_currentRequestRange","_lastTimeLoaded","useRefTotalLength","_openSubRange","chunkSize","_onLoad","openNextRange","reportComplete","_transmuxer","_mseController","onvLoadedMetadata","_onvLoadedMetadata","onvSeeking","_onvSeeking","onvCanPlay","_onvCanPlay","onvStalled","_onvStalled","onvProgress","_onvProgress","_requestSetTime","_seekpointRecord","_progressChecker","_msectl","_mseSourceOpened","_hasPendingLoad","_receivedCanPlay","_statisticsInfo","chromeNeedIDRFix","chrome","major","build","_alwaysSeekKeyframe","msie","unload","_mseController2","_onmseUpdateEnd","_onmseBufferFull","load","MEDIA_ERROR","MEDIA_MSE_ERROR","attachMediaElement","_transmuxer2","appendMediaSegment","_suspendTransmuxer","NETWORK_ERROR","_fillStatisticsInfo","play","playerType","HTMLVideoElement","hasQualityInfo","decoded","dropped","getVideoPlaybackQuality","quality","totalVideoFrames","droppedVideoFrames","webkitDecodedFrameCount","webkitDroppedFrameCount","decodedFrames","droppedFrames","currentRangeEnd","_checkProgressAndResume","needResume","directSeek","_isTimepointBuffered","directSeekBegin","directSeekBeginTime","videoBeginTime","idr","recordTime","_checkAndApplyUnbufferedSeekpoint","stalled","media","seekPoint","_checkAndResumeStuckPlayback","volume","muted","preload","mediaPrefix","HTMLAudioElement","videoWidth","videoHeight","OTHER_ERROR","NETWORK_EXCEPTION","NETWORK_STATUS_CODE_INVALID","NETWORK_TIMEOUT","NETWORK_UNRECOVERABLE_EARLY_EOF","MEDIA_FORMAT_ERROR","MEDIA_FORMAT_UNSUPPORTED","MEDIA_CODEC_UNSUPPORTED","PlayerEvents","AAC","MP4","types","avc1","avcC","btrt","dinf","dref","esds","ftyp","hdlr","mdat","mdhd","mdia","mfhd","minf","moof","moov","mp4a","mvex","mvhd","sdtp","stbl","stco","stsc","stsd","stsz","stts","tfdt","tfhd","traf","trak","trun","trex","tkhd","vmhd","smhd",".mp3","charCodeAt","constants","FTYP","STSD_PREFIX","STTS","STSC","STCO","STSZ","HDLR_VIDEO","HDLR_AUDIO","DREF","SMHD","VMHD","datas","arrayCount","box","trackId","xmhd","mp3","sampleRate","configSize","baseMediaDecodeTime","sampleCount","flags","isLeading","dependsOn","isDependedOn","hasRedundancy","isNonSync","init","_mp4Generator","_aacSilent","MP4Remuxer","_isLive","_dtsBase","_dtsBaseInited","_audioDtsBase","Infinity","_videoDtsBase","_audioNextDts","_videoNextDts","_audioMeta","_videoMeta","_audioSegmentInfoList","_videoSegmentInfoList","_forceFirstIDR","_fillSilentAfterSeek","_mp3UseMpegAudio","firefox","_fillAudioTimestampGap","producer","onDataAvailable","remux","onTrackMetadata","_onTrackMetadataReceived","audioTrack","videoTrack","_calculateDtsBase","_remuxVideo","_remuxAudio","metabox","_mp4Generator2","generateInitSegment","dtsCorrection","firstDts","lastDts","mpegRawTrack","firstSegmentAfterSeek","insertPrefixSilentFrame","mdatbox","mdatBytes","firstSampleOriginalDts","isEmpty","getLastSampleBefore","distance","expectedDts","firstSampleDts","videoSegment","silentUnit","_aacSilent2","getSilentFrame","silentFrameDuration","mp4Samples","sample","sampleDuration","needFillSilentFrames","silentFrames","frameCount","currentDts","round","_silentUnit","intDts","previousFrame","frame","lastFrame","_unit","latest","moofbox","_mergeBoxes","firstPts","lastPts","syncPoint","appendSyncPoint","_i2","Browser","ua","exec","platform_match","matched","majorVersion","platform","versionArray","string","opr","webkit","rv","iemobile","edge","android","_message","Log","tag","FORCE_GLOBAL_TAG","GLOBAL_TAG","ENABLE_CALLBACK","ENABLE_ERROR","warn","log","ENABLE_INFO","ENABLE_WARN","ENABLE_DEBUG","debug","ENABLE_VERBOSE","globalTag","forceGlobalTag","enableVerbose","enableDebug","enableInfo","enableWarn","enableError","_notifyChange","enable","Polyfill","proto","output","source","checkContinuation","checkLength","decodeUTF8","out","String","fromCharCode","ucs4","_ucs","_ucs2"],"mappings":"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","file":"flv.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o postsJSON\n values[1] // => commentsJSON\n\n return values;\n });\n ```\n\n @class Promise\n @param {function} resolver\n Useful for tooling.\n @constructor\n*/\nfunction Promise(resolver) {\n this[PROMISE_ID] = nextId();\n this._result = this._state = undefined;\n this._subscribers = [];\n\n if (noop !== resolver) {\n typeof resolver !== 'function' && needsResolver();\n this instanceof Promise ? initializePromise(this, resolver) : needsNew();\n }\n}\n\nPromise.all = all;\nPromise.race = race;\nPromise.resolve = resolve;\nPromise.reject = reject;\nPromise._setScheduler = setScheduler;\nPromise._setAsap = setAsap;\nPromise._asap = asap;\n\nPromise.prototype = {\n constructor: Promise,\n\n /**\n The primary way of interacting with a promise is through its `then` method,\n which registers callbacks to receive either a promise's eventual value or the\n reason why the promise cannot be fulfilled.\n \n ```js\n findUser().then(function(user){\n // user is available\n }, function(reason){\n // user is unavailable, and you are given the reason why\n });\n ```\n \n Chaining\n --------\n \n The return value of `then` is itself a promise. This second, 'downstream'\n promise is resolved with the return value of the first promise's fulfillment\n or rejection handler, or rejected if the handler throws an exception.\n \n ```js\n findUser().then(function (user) {\n return user.name;\n }, function (reason) {\n return 'default name';\n }).then(function (userName) {\n // If `findUser` fulfilled, `userName` will be the user's name, otherwise it\n // will be `'default name'`\n });\n \n findUser().then(function (user) {\n throw new Error('Found user, but still unhappy');\n }, function (reason) {\n throw new Error('`findUser` rejected and we're unhappy');\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.\n // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.\n });\n ```\n If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.\n \n ```js\n findUser().then(function (user) {\n throw new PedagogicalException('Upstream error');\n }).then(function (value) {\n // never reached\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // The `PedgagocialException` is propagated all the way down to here\n });\n ```\n \n Assimilation\n ------------\n \n Sometimes the value you want to propagate to a downstream promise can only be\n retrieved asynchronously. This can be achieved by returning a promise in the\n fulfillment or rejection handler. The downstream promise will then be pending\n until the returned promise is settled. This is called *assimilation*.\n \n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // The user's comments are now available\n });\n ```\n \n If the assimliated promise rejects, then the downstream promise will also reject.\n \n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // If `findCommentsByAuthor` fulfills, we'll have the value here\n }, function (reason) {\n // If `findCommentsByAuthor` rejects, we'll have the reason here\n });\n ```\n \n Simple Example\n --------------\n \n Synchronous Example\n \n ```javascript\n let result;\n \n try {\n result = findResult();\n // success\n } catch(reason) {\n // failure\n }\n ```\n \n Errback Example\n \n ```js\n findResult(function(result, err){\n if (err) {\n // failure\n } else {\n // success\n }\n });\n ```\n \n Promise Example;\n \n ```javascript\n findResult().then(function(result){\n // success\n }, function(reason){\n // failure\n });\n ```\n \n Advanced Example\n --------------\n \n Synchronous Example\n \n ```javascript\n let author, books;\n \n try {\n author = findAuthor();\n books = findBooksByAuthor(author);\n // success\n } catch(reason) {\n // failure\n }\n ```\n \n Errback Example\n \n ```js\n \n function foundBooks(books) {\n \n }\n \n function failure(reason) {\n \n }\n \n findAuthor(function(author, err){\n if (err) {\n failure(err);\n // failure\n } else {\n try {\n findBoooksByAuthor(author, function(books, err) {\n if (err) {\n failure(err);\n } else {\n try {\n foundBooks(books);\n } catch(reason) {\n failure(reason);\n }\n }\n });\n } catch(error) {\n failure(err);\n }\n // success\n }\n });\n ```\n \n Promise Example;\n \n ```javascript\n findAuthor().\n then(findBooksByAuthor).\n then(function(books){\n // found books\n }).catch(function(reason){\n // something went wrong\n });\n ```\n \n @method then\n @param {Function} onFulfilled\n @param {Function} onRejected\n Useful for tooling.\n @return {Promise}\n */\n then: then,\n\n /**\n `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same\n as the catch block of a try/catch statement.\n \n ```js\n function findAuthor(){\n throw new Error('couldn't find that author');\n }\n \n // synchronous\n try {\n findAuthor();\n } catch(reason) {\n // something went wrong\n }\n \n // async with promises\n findAuthor().catch(function(reason){\n // something went wrong\n });\n ```\n \n @method catch\n @param {Function} onRejection\n Useful for tooling.\n @return {Promise}\n */\n 'catch': function _catch(onRejection) {\n return this.then(null, onRejection);\n }\n};\n\nfunction polyfill() {\n var local = undefined;\n\n if (typeof global !== 'undefined') {\n local = global;\n } else if (typeof self !== 'undefined') {\n local = self;\n } else {\n try {\n local = Function('return this')();\n } catch (e) {\n throw new Error('polyfill failed because global object is unavailable in this environment');\n }\n }\n\n var P = local.Promise;\n\n if (P) {\n var promiseToString = null;\n try {\n promiseToString = Object.prototype.toString.call(P.resolve());\n } catch (e) {\n // silently ignored\n }\n\n if (promiseToString === '[object Promise]' && !P.cast) {\n return;\n }\n }\n\n local.Promise = Promise;\n}\n\n// Strange compat..\nPromise.polyfill = polyfill;\nPromise.Promise = Promise;\n\nreturn Promise;\n\n})));\n//# sourceMappingURL=es6-promise.map\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n args = Array.prototype.slice.call(arguments, 1);\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n args = Array.prototype.slice.call(arguments, 1);\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","var bundleFn = arguments[3];\nvar sources = arguments[4];\nvar cache = arguments[5];\n\nvar stringify = JSON.stringify;\n\nmodule.exports = function (fn, options) {\n var wkey;\n var cacheKeys = Object.keys(cache);\n\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n var exp = cache[key].exports;\n // Using babel as a transpiler to use esmodule, the export will always\n // be an object with the default export as a property of it. To ensure\n // the existing api and babel esmodule exports are both supported we\n // check for both\n if (exp === fn || exp && exp.default === fn) {\n wkey = key;\n break;\n }\n }\n\n if (!wkey) {\n wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n var wcache = {};\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n wcache[key] = key;\n }\n sources[wkey] = [\n Function(['require','module','exports'], '(' + fn + ')(self)'),\n wcache\n ];\n }\n var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n\n var scache = {}; scache[wkey] = wkey;\n sources[skey] = [\n Function(['require'], (\n // try to call default if defined to also support babel esmodule\n // exports\n 'var f = require(' + stringify(wkey) + ');' +\n '(f.default ? f.default : f)(self);'\n )),\n scache\n ];\n\n var workerSources = {};\n resolveSources(skey);\n\n function resolveSources(key) {\n workerSources[key] = true;\n\n for (var depPath in sources[key][1]) {\n var depKey = sources[key][1][depPath];\n if (!workerSources[depKey]) {\n resolveSources(depKey);\n }\n }\n }\n\n var src = '(' + bundleFn + ')({'\n + Object.keys(workerSources).map(function (key) {\n return stringify(key) + ':['\n + sources[key][0]\n + ',' + stringify(sources[key][1]) + ']'\n ;\n }).join(',')\n + '},{},[' + stringify(skey) + '])'\n ;\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n var blob = new Blob([src], { type: 'text/javascript' });\n if (options && options.bare) { return blob; }\n var workerUrl = URL.createObjectURL(blob);\n var worker = new Worker(workerUrl);\n worker.objectURL = workerUrl;\n return worker;\n};\n","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const defaultConfig = {\n enableWorker: false,\n enableStashBuffer: true,\n stashInitialSize: undefined,\n\n isLive: false,\n\n lazyLoad: true,\n lazyLoadMaxDuration: 3 * 60,\n lazyLoadRecoverDuration: 30,\n deferLoadAfterSourceOpen: true,\n\n // autoCleanupSourceBuffer: default as false, leave unspecified\n autoCleanupMaxBackwardDuration: 3 * 60,\n autoCleanupMinBackwardDuration: 2 * 60,\n\n statisticsInfoReportInterval: 600,\n\n fixAudioTimestampGap: true,\n\n accurateSeek: false,\n seekType: 'range', // [range, param, custom]\n seekParamStart: 'bstart',\n seekParamEnd: 'bend',\n rangeLoadZeroStart: false,\n customSeekHandler: undefined,\n reuseRedirectedURL: false\n // referrerPolicy: leave as unspecified\n};\n\nexport function createDefaultConfig() {\n return Object.assign({}, defaultConfig);\n}","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport IOController from '../io/io-controller.js';\nimport {createDefaultConfig} from '../config.js';\n\nclass Features {\n\n static supportMSEH264Playback() {\n return window.MediaSource &&\n window.MediaSource.isTypeSupported('video/mp4; codecs=\"avc1.42E01E,mp4a.40.2\"');\n }\n\n static supportNetworkStreamIO() {\n let ioctl = new IOController({}, createDefaultConfig());\n let loaderType = ioctl.loaderType;\n ioctl.destroy();\n return loaderType == 'fetch-stream-loader' || loaderType == 'xhr-moz-chunked-loader';\n }\n\n static getNetworkLoaderTypeName() {\n let ioctl = new IOController({}, createDefaultConfig());\n let loaderType = ioctl.loaderType;\n ioctl.destroy();\n return loaderType;\n }\n\n static supportNativeMediaPlayback(mimeType) {\n if (Features.videoElement == undefined) {\n Features.videoElement = window.document.createElement('video');\n }\n let canPlay = Features.videoElement.canPlayType(mimeType);\n return canPlay === 'probably' || canPlay == 'maybe';\n }\n\n static getFeatureList() {\n let features = {\n mseFlvPlayback: false,\n mseLiveFlvPlayback: false,\n networkStreamIO: false,\n networkLoaderName: '',\n nativeMP4H264Playback: false,\n nativeWebmVP8Playback: false,\n nativeWebmVP9Playback: false\n };\n\n features.mseFlvPlayback = Features.supportMSEH264Playback();\n features.networkStreamIO = Features.supportNetworkStreamIO();\n features.networkLoaderName = Features.getNetworkLoaderTypeName();\n features.mseLiveFlvPlayback = features.mseFlvPlayback && features.networkStreamIO;\n features.nativeMP4H264Playback = Features.supportNativeMediaPlayback('video/mp4; codecs=\"avc1.42001E, mp4a.40.2\"');\n features.nativeWebmVP8Playback = Features.supportNativeMediaPlayback('video/webm; codecs=\"vp8.0, vorbis\"');\n features.nativeWebmVP9Playback = Features.supportNativeMediaPlayback('video/webm; codecs=\"vp9\"');\n\n return features;\n }\n\n}\n\nexport default Features;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass MediaInfo {\n\n constructor() {\n this.mimeType = null;\n this.duration = null;\n\n this.hasAudio = null;\n this.hasVideo = null;\n this.audioCodec = null;\n this.videoCodec = null;\n this.audioDataRate = null;\n this.videoDataRate = null;\n\n this.audioSampleRate = null;\n this.audioChannelCount = null;\n\n this.width = null;\n this.height = null;\n this.fps = null;\n this.profile = null;\n this.level = null;\n this.chromaFormat = null;\n this.sarNum = null;\n this.sarDen = null;\n\n this.metadata = null;\n this.segments = null; // MediaInfo[]\n this.segmentCount = null;\n this.hasKeyframesIndex = null;\n this.keyframesIndex = null;\n }\n\n isComplete() {\n let audioInfoComplete = (this.hasAudio === false) ||\n (this.hasAudio === true &&\n this.audioCodec != null &&\n this.audioSampleRate != null &&\n this.audioChannelCount != null);\n\n let videoInfoComplete = (this.hasVideo === false) ||\n (this.hasVideo === true &&\n this.videoCodec != null &&\n this.width != null &&\n this.height != null &&\n this.fps != null &&\n this.profile != null &&\n this.level != null &&\n this.chromaFormat != null &&\n this.sarNum != null &&\n this.sarDen != null);\n\n // keyframesIndex may not be present\n return this.mimeType != null &&\n this.duration != null &&\n this.metadata != null &&\n this.hasKeyframesIndex != null &&\n audioInfoComplete &&\n videoInfoComplete;\n }\n\n isSeekable() {\n return this.hasKeyframesIndex === true;\n }\n\n getNearestKeyframe(milliseconds) {\n if (this.keyframesIndex == null) {\n return null;\n }\n\n let table = this.keyframesIndex;\n let keyframeIdx = this._search(table.times, milliseconds);\n\n return {\n index: keyframeIdx,\n milliseconds: table.times[keyframeIdx],\n fileposition: table.filepositions[keyframeIdx]\n };\n }\n\n _search(list, value) {\n let idx = 0;\n\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (value < list[0]) {\n idx = 0;\n lbound = ubound + 1; // skip search\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (value >= list[mid] && value < list[mid + 1])) {\n idx = mid;\n break;\n } else if (list[mid] < value) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n\n return idx;\n }\n\n}\n\nexport default MediaInfo;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Represents an media sample (audio / video)\nexport class SampleInfo {\n\n constructor(dts, pts, duration, originalDts, isSync) {\n this.dts = dts;\n this.pts = pts;\n this.duration = duration;\n this.originalDts = originalDts;\n this.isSyncPoint = isSync;\n this.fileposition = null;\n }\n\n}\n\n// Media Segment concept is defined in Media Source Extensions spec.\n// Particularly in ISO BMFF format, an Media Segment contains a moof box followed by a mdat box.\nexport class MediaSegmentInfo {\n\n constructor() {\n this.beginDts = 0;\n this.endDts = 0;\n this.beginPts = 0;\n this.endPts = 0;\n this.originalBeginDts = 0;\n this.originalEndDts = 0;\n this.syncPoints = []; // SampleInfo[n], for video IDR frames only\n this.firstSample = null; // SampleInfo\n this.lastSample = null; // SampleInfo\n }\n\n appendSyncPoint(sampleInfo) { // also called Random Access Point\n sampleInfo.isSyncPoint = true;\n this.syncPoints.push(sampleInfo);\n }\n\n}\n\n// Ordered list for recording video IDR frames, sorted by originalDts\nexport class IDRSampleList {\n\n constructor() {\n this._list = [];\n }\n\n clear() {\n this._list = [];\n }\n\n appendArray(syncPoints) {\n let list = this._list;\n\n if (syncPoints.length === 0) {\n return;\n }\n\n if (list.length > 0 && syncPoints[0].originalDts < list[list.length - 1].originalDts) {\n this.clear();\n }\n\n Array.prototype.push.apply(list, syncPoints);\n }\n\n getLastSyncPointBeforeDts(dts) {\n if (this._list.length == 0) {\n return null;\n }\n\n let list = this._list;\n let idx = 0;\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (dts < list[0].dts) {\n idx = 0;\n lbound = ubound + 1;\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (dts >= list[mid].dts && dts < list[mid + 1].dts)) {\n idx = mid;\n break;\n } else if (list[mid].dts < dts) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n return this._list[idx];\n }\n\n}\n\n// Data structure for recording information of media segments in single track.\nexport class MediaSegmentInfoList {\n\n constructor(type) {\n this._type = type;\n this._list = [];\n this._lastAppendLocation = -1; // cached last insert location\n }\n\n get type() {\n return this._type;\n }\n\n get length() {\n return this._list.length;\n }\n\n isEmpty() {\n return this._list.length === 0;\n }\n\n clear() {\n this._list = [];\n this._lastAppendLocation = -1;\n }\n\n _searchNearestSegmentBefore(originalBeginDts) {\n let list = this._list;\n if (list.length === 0) {\n return -2;\n }\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n let idx = 0;\n\n if (originalBeginDts < list[0].originalBeginDts) {\n idx = -1;\n return idx;\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (originalBeginDts > list[mid].lastSample.originalDts &&\n (originalBeginDts < list[mid + 1].originalBeginDts))) {\n idx = mid;\n break;\n } else if (list[mid].originalBeginDts < originalBeginDts) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n return idx;\n }\n\n _searchNearestSegmentAfter(originalBeginDts) {\n return this._searchNearestSegmentBefore(originalBeginDts) + 1;\n }\n\n append(mediaSegmentInfo) {\n let list = this._list;\n let msi = mediaSegmentInfo;\n let lastAppendIdx = this._lastAppendLocation;\n let insertIdx = 0;\n\n if (lastAppendIdx !== -1 && lastAppendIdx < list.length &&\n msi.originalBeginDts >= list[lastAppendIdx].lastSample.originalDts &&\n ((lastAppendIdx === list.length - 1) ||\n (lastAppendIdx < list.length - 1 &&\n msi.originalBeginDts < list[lastAppendIdx + 1].originalBeginDts))) {\n insertIdx = lastAppendIdx + 1; // use cached location idx\n } else {\n if (list.length > 0) {\n insertIdx = this._searchNearestSegmentBefore(msi.originalBeginDts) + 1;\n }\n }\n\n this._lastAppendLocation = insertIdx;\n this._list.splice(insertIdx, 0, msi);\n }\n\n getLastSegmentBefore(originalBeginDts) {\n let idx = this._searchNearestSegmentBefore(originalBeginDts);\n if (idx >= 0) {\n return this._list[idx];\n } else { // -1\n return null;\n }\n }\n\n getLastSampleBefore(originalBeginDts) {\n let segment = this.getLastSegmentBefore(originalBeginDts);\n if (segment != null) {\n return segment.lastSample;\n } else {\n return null;\n }\n }\n\n getLastSyncPointBefore(originalBeginDts) {\n let segmentIdx = this._searchNearestSegmentBefore(originalBeginDts);\n let syncPoints = this._list[segmentIdx].syncPoints;\n while (syncPoints.length === 0 && segmentIdx > 0) {\n segmentIdx--;\n syncPoints = this._list[segmentIdx].syncPoints;\n }\n if (syncPoints.length > 0) {\n return syncPoints[syncPoints.length - 1];\n } else {\n return null;\n }\n }\n\n}","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport MSEEvents from './mse-events.js';\nimport {SampleInfo, IDRSampleList} from './media-segment-info.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\n// Media Source Extensions controller\nclass MSEController {\n\n constructor(config) {\n this.TAG = 'MSEController';\n\n this._config = config;\n this._emitter = new EventEmitter();\n\n if (this._config.isLive && this._config.autoCleanupSourceBuffer == undefined) {\n // For live stream, do auto cleanup by default\n this._config.autoCleanupSourceBuffer = true;\n }\n\n this.e = {\n onSourceOpen: this._onSourceOpen.bind(this),\n onSourceEnded: this._onSourceEnded.bind(this),\n onSourceClose: this._onSourceClose.bind(this),\n onSourceBufferError: this._onSourceBufferError.bind(this),\n onSourceBufferUpdateEnd: this._onSourceBufferUpdateEnd.bind(this)\n };\n\n this._mediaSource = null;\n this._mediaSourceObjectURL = null;\n this._mediaElement = null;\n\n this._isBufferFull = false;\n this._hasPendingEos = false;\n\n this._requireSetMediaDuration = false;\n this._pendingMediaDuration = 0;\n\n this._pendingSourceBufferInit = [];\n this._mimeTypes = {\n video: null,\n audio: null\n };\n this._sourceBuffers = {\n video: null,\n audio: null\n };\n this._lastInitSegments = {\n video: null,\n audio: null\n };\n this._pendingSegments = {\n video: [],\n audio: []\n };\n this._pendingRemoveRanges = {\n video: [],\n audio: []\n };\n this._idrList = new IDRSampleList();\n }\n\n destroy() {\n if (this._mediaElement || this._mediaSource) {\n this.detachMediaElement();\n }\n this.e = null;\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n attachMediaElement(mediaElement) {\n if (this._mediaSource) {\n throw new IllegalStateException('MediaSource has been attached to an HTMLMediaElement!');\n }\n let ms = this._mediaSource = new window.MediaSource();\n ms.addEventListener('sourceopen', this.e.onSourceOpen);\n ms.addEventListener('sourceended', this.e.onSourceEnded);\n ms.addEventListener('sourceclose', this.e.onSourceClose);\n\n this._mediaElement = mediaElement;\n this._mediaSourceObjectURL = window.URL.createObjectURL(this._mediaSource);\n mediaElement.src = this._mediaSourceObjectURL;\n }\n\n detachMediaElement() {\n if (this._mediaSource) {\n let ms = this._mediaSource;\n for (let type in this._sourceBuffers) {\n // pending segments should be discard\n let ps = this._pendingSegments[type];\n ps.splice(0, ps.length);\n this._pendingSegments[type] = null;\n this._pendingRemoveRanges[type] = null;\n this._lastInitSegments[type] = null;\n\n // remove all sourcebuffers\n let sb = this._sourceBuffers[type];\n if (sb) {\n if (ms.readyState !== 'closed') {\n ms.removeSourceBuffer(sb);\n sb.removeEventListener('error', this.e.onSourceBufferError);\n sb.removeEventListener('updateend', this.e.onSourceBufferUpdateEnd);\n }\n this._mimeTypes[type] = null;\n this._sourceBuffers[type] = null;\n }\n }\n if (ms.readyState === 'open') {\n try {\n ms.endOfStream();\n } catch (error) {\n Log.e(this.TAG, error.message);\n }\n }\n ms.removeEventListener('sourceopen', this.e.onSourceOpen);\n ms.removeEventListener('sourceended', this.e.onSourceEnded);\n ms.removeEventListener('sourceclose', this.e.onSourceClose);\n this._pendingSourceBufferInit = [];\n this._isBufferFull = false;\n this._idrList.clear();\n this._mediaSource = null;\n }\n\n if (this._mediaElement) {\n this._mediaElement.src = '';\n this._mediaElement.removeAttribute('src');\n this._mediaElement = null;\n }\n if (this._mediaSourceObjectURL) {\n window.URL.revokeObjectURL(this._mediaSourceObjectURL);\n this._mediaSourceObjectURL = null;\n }\n }\n\n appendInitSegment(initSegment, deferred) {\n if (!this._mediaSource || this._mediaSource.readyState !== 'open') {\n // sourcebuffer creation requires mediaSource.readyState === 'open'\n // so we defer the sourcebuffer creation, until sourceopen event triggered\n this._pendingSourceBufferInit.push(initSegment);\n // make sure that this InitSegment is in the front of pending segments queue\n this._pendingSegments[initSegment.type].push(initSegment);\n return;\n }\n\n let is = initSegment;\n let mimeType = `${is.container}`;\n if (is.codec && is.codec.length > 0) {\n mimeType += `;codecs=${is.codec}`;\n }\n\n let firstInitSegment = false;\n\n Log.v(this.TAG, 'Received Initialization Segment, mimeType: ' + mimeType);\n this._lastInitSegments[is.type] = is;\n\n if (mimeType !== this._mimeTypes[is.type]) {\n if (!this._mimeTypes[is.type]) { // empty, first chance create sourcebuffer\n firstInitSegment = true;\n try {\n let sb = this._sourceBuffers[is.type] = this._mediaSource.addSourceBuffer(mimeType);\n sb.addEventListener('error', this.e.onSourceBufferError);\n sb.addEventListener('updateend', this.e.onSourceBufferUpdateEnd);\n } catch (error) {\n Log.e(this.TAG, error.message);\n this._emitter.emit(MSEEvents.ERROR, {code: error.code, msg: error.message});\n return;\n }\n } else {\n Log.v(this.TAG, `Notice: ${is.type} mimeType changed, origin: ${this._mimeTypes[is.type]}, target: ${mimeType}`);\n }\n this._mimeTypes[is.type] = mimeType;\n }\n\n if (!deferred) {\n // deferred means this InitSegment has been pushed to pendingSegments queue\n this._pendingSegments[is.type].push(is);\n }\n if (!firstInitSegment) { // append immediately only if init segment in subsequence\n if (this._sourceBuffers[is.type] && !this._sourceBuffers[is.type].updating) {\n this._doAppendSegments();\n }\n }\n if (Browser.safari && is.container === 'audio/mpeg' && is.mediaDuration > 0) {\n // 'audio/mpeg' track under Safari may cause MediaElement's duration to be NaN\n // Manually correct MediaSource.duration to make progress bar seekable, and report right duration\n this._requireSetMediaDuration = true;\n this._pendingMediaDuration = is.mediaDuration / 1000; // in seconds\n this._updateMediaSourceDuration();\n }\n }\n\n appendMediaSegment(mediaSegment) {\n let ms = mediaSegment;\n this._pendingSegments[ms.type].push(ms);\n\n if (this._config.autoCleanupSourceBuffer && this._needCleanupSourceBuffer()) {\n this._doCleanupSourceBuffer();\n }\n\n let sb = this._sourceBuffers[ms.type];\n if (sb && !sb.updating && !this._hasPendingRemoveRanges()) {\n this._doAppendSegments();\n }\n }\n\n seek(seconds) {\n // remove all appended buffers\n for (let type in this._sourceBuffers) {\n if (!this._sourceBuffers[type]) {\n continue;\n }\n\n // abort current buffer append algorithm\n let sb = this._sourceBuffers[type];\n if (this._mediaSource.readyState === 'open') {\n try {\n // If range removal algorithm is running, InvalidStateError will be throwed\n // Ignore it.\n sb.abort();\n } catch (error) {\n Log.e(this.TAG, error.message);\n }\n }\n\n // IDRList should be clear\n this._idrList.clear();\n\n // pending segments should be discard\n let ps = this._pendingSegments[type];\n ps.splice(0, ps.length);\n\n if (this._mediaSource.readyState === 'closed') {\n // Parent MediaSource object has been detached from HTMLMediaElement\n continue;\n }\n\n // record ranges to be remove from SourceBuffer\n for (let i = 0; i < sb.buffered.length; i++) {\n let start = sb.buffered.start(i);\n let end = sb.buffered.end(i);\n this._pendingRemoveRanges[type].push({start, end});\n }\n\n // if sb is not updating, let's remove ranges now!\n if (!sb.updating) {\n this._doRemoveRanges();\n }\n\n // Safari 10 may get InvalidStateError in the later appendBuffer() after SourceBuffer.remove() call\n // Internal parser's state may be invalid at this time. Re-append last InitSegment to workaround.\n // Related issue: https://bugs.webkit.org/show_bug.cgi?id=159230\n if (Browser.safari) {\n let lastInitSegment = this._lastInitSegments[type];\n if (lastInitSegment) {\n this._pendingSegments[type].push(lastInitSegment);\n if (!sb.updating) {\n this._doAppendSegments();\n }\n }\n }\n }\n }\n\n endOfStream() {\n let ms = this._mediaSource;\n let sb = this._sourceBuffers;\n if (!ms || ms.readyState !== 'open') {\n if (ms && ms.readyState === 'closed' && this._hasPendingSegments()) {\n // If MediaSource hasn't turned into open state, and there're pending segments\n // Mark pending endOfStream, defer call until all pending segments appended complete\n this._hasPendingEos = true;\n }\n return;\n }\n if (sb.video && sb.video.updating || sb.audio && sb.audio.updating) {\n // If any sourcebuffer is updating, defer endOfStream operation\n // See _onSourceBufferUpdateEnd()\n this._hasPendingEos = true;\n } else {\n this._hasPendingEos = false;\n // Notify media data loading complete\n // This is helpful for correcting total duration to match last media segment\n // Otherwise MediaElement's ended event may not be triggered\n ms.endOfStream();\n }\n }\n\n getNearestKeyframe(dts) {\n return this._idrList.getLastSyncPointBeforeDts(dts);\n }\n\n _needCleanupSourceBuffer() {\n if (!this._config.autoCleanupSourceBuffer) {\n return false;\n }\n\n let currentTime = this._mediaElement.currentTime;\n\n for (let type in this._sourceBuffers) {\n let sb = this._sourceBuffers[type];\n if (sb) {\n let buffered = sb.buffered;\n if (buffered.length >= 1) {\n if (currentTime - buffered.start(0) >= this._config.autoCleanupMaxBackwardDuration) {\n return true;\n }\n }\n }\n }\n\n return false;\n }\n\n _doCleanupSourceBuffer() {\n let currentTime = this._mediaElement.currentTime;\n\n for (let type in this._sourceBuffers) {\n let sb = this._sourceBuffers[type];\n if (sb) {\n let buffered = sb.buffered;\n let doRemove = false;\n\n for (let i = 0; i < buffered.length; i++) {\n let start = buffered.start(i);\n let end = buffered.end(i);\n\n if (start <= currentTime && currentTime < end + 3) { // padding 3 seconds\n if (currentTime - start >= this._config.autoCleanupMaxBackwardDuration) {\n doRemove = true;\n let removeEnd = currentTime - this._config.autoCleanupMinBackwardDuration;\n this._pendingRemoveRanges[type].push({start: start, end: removeEnd});\n }\n } else if (end < currentTime) {\n doRemove = true;\n this._pendingRemoveRanges[type].push({start: start, end: end});\n }\n }\n\n if (doRemove && !sb.updating) {\n this._doRemoveRanges();\n }\n }\n }\n }\n\n _updateMediaSourceDuration() {\n let sb = this._sourceBuffers;\n if (this._mediaElement.readyState === 0 || this._mediaSource.readyState !== 'open') {\n return;\n }\n if ((sb.video && sb.video.updating) || (sb.audio && sb.audio.updating)) {\n return;\n }\n\n let current = this._mediaSource.duration;\n let target = this._pendingMediaDuration;\n\n if (target > 0 && (isNaN(current) || target > current)) {\n Log.v(this.TAG, `Update MediaSource duration from ${current} to ${target}`);\n this._mediaSource.duration = target;\n }\n\n this._requireSetMediaDuration = false;\n this._pendingMediaDuration = 0;\n }\n\n _doRemoveRanges() {\n for (let type in this._pendingRemoveRanges) {\n if (!this._sourceBuffers[type] || this._sourceBuffers[type].updating) {\n continue;\n }\n let sb = this._sourceBuffers[type];\n let ranges = this._pendingRemoveRanges[type];\n while (ranges.length && !sb.updating) {\n let range = ranges.shift();\n sb.remove(range.start, range.end);\n }\n }\n }\n\n _doAppendSegments() {\n let pendingSegments = this._pendingSegments;\n\n for (let type in pendingSegments) {\n if (!this._sourceBuffers[type] || this._sourceBuffers[type].updating) {\n continue;\n }\n\n if (pendingSegments[type].length > 0) {\n let segment = pendingSegments[type].shift();\n\n if (segment.timestampOffset) {\n // For MPEG audio stream in MSE, if unbuffered-seeking occurred\n // We need explicitly set timestampOffset to the desired point in timeline for mpeg SourceBuffer.\n let currentOffset = this._sourceBuffers[type].timestampOffset;\n let targetOffset = segment.timestampOffset / 1000; // in seconds\n\n let delta = Math.abs(currentOffset - targetOffset);\n if (delta > 0.1) { // If time delta > 100ms\n Log.v(this.TAG, `Update MPEG audio timestampOffset from ${currentOffset} to ${targetOffset}`);\n this._sourceBuffers[type].timestampOffset = targetOffset;\n }\n delete segment.timestampOffset;\n }\n\n if (!segment.data || segment.data.byteLength === 0) {\n // Ignore empty buffer\n continue;\n }\n\n try {\n this._sourceBuffers[type].appendBuffer(segment.data);\n this._isBufferFull = false;\n if (type === 'video' && segment.hasOwnProperty('info')) {\n this._idrList.appendArray(segment.info.syncPoints);\n }\n } catch (error) {\n this._pendingSegments[type].unshift(segment);\n if (error.code === 22) { // QuotaExceededError\n /* Notice that FireFox may not throw QuotaExceededError if SourceBuffer is full\n * Currently we can only do lazy-load to avoid SourceBuffer become scattered.\n * SourceBuffer eviction policy may be changed in future version of FireFox.\n *\n * Related issues:\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1279885\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1280023\n */\n\n // report buffer full, abort network IO\n if (!this._isBufferFull) {\n this._emitter.emit(MSEEvents.BUFFER_FULL);\n }\n this._isBufferFull = true;\n } else {\n Log.e(this.TAG, error.message);\n this._emitter.emit(MSEEvents.ERROR, {code: error.code, msg: error.message});\n }\n }\n }\n }\n }\n\n _onSourceOpen() {\n Log.v(this.TAG, 'MediaSource onSourceOpen');\n this._mediaSource.removeEventListener('sourceopen', this.e.onSourceOpen);\n // deferred sourcebuffer creation / initialization\n if (this._pendingSourceBufferInit.length > 0) {\n let pendings = this._pendingSourceBufferInit;\n while (pendings.length) {\n let segment = pendings.shift();\n this.appendInitSegment(segment, true);\n }\n }\n // there may be some pending media segments, append them\n if (this._hasPendingSegments()) {\n this._doAppendSegments();\n }\n this._emitter.emit(MSEEvents.SOURCE_OPEN);\n }\n\n _onSourceEnded() {\n // fired on endOfStream\n Log.v(this.TAG, 'MediaSource onSourceEnded');\n }\n\n _onSourceClose() {\n // fired on detaching from media element\n Log.v(this.TAG, 'MediaSource onSourceClose');\n if (this._mediaSource && this.e != null) {\n this._mediaSource.removeEventListener('sourceopen', this.e.onSourceOpen);\n this._mediaSource.removeEventListener('sourceended', this.e.onSourceEnded);\n this._mediaSource.removeEventListener('sourceclose', this.e.onSourceClose);\n }\n }\n\n _hasPendingSegments() {\n let ps = this._pendingSegments;\n return ps.video.length > 0 || ps.audio.length > 0;\n }\n\n _hasPendingRemoveRanges() {\n let prr = this._pendingRemoveRanges;\n return prr.video.length > 0 || prr.audio.length > 0;\n }\n\n _onSourceBufferUpdateEnd() {\n if (this._requireSetMediaDuration) {\n this._updateMediaSourceDuration();\n } else if (this._hasPendingRemoveRanges()) {\n this._doRemoveRanges();\n } else if (this._hasPendingSegments()) {\n this._doAppendSegments();\n } else if (this._hasPendingEos) {\n this.endOfStream();\n }\n this._emitter.emit(MSEEvents.UPDATE_END);\n }\n\n _onSourceBufferError(e) {\n Log.e(this.TAG, `SourceBuffer Error: ${e}`);\n // this error might not always be fatal, just ignore it\n }\n\n}\n\nexport default MSEController;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst MSEEvents = {\n ERROR: 'error',\n SOURCE_OPEN: 'source_open',\n UPDATE_END: 'update_end',\n BUFFER_FULL: 'buffer_full'\n};\n\nexport default MSEEvents;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport LoggingControl from '../utils/logging-control.js';\nimport TransmuxingController from './transmuxing-controller.js';\nimport TransmuxingEvents from './transmuxing-events.js';\nimport TransmuxingWorker from './transmuxing-worker.js';\nimport MediaInfo from './media-info.js';\n\nclass Transmuxer {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'Transmuxer';\n this._emitter = new EventEmitter();\n\n if (config.enableWorker && typeof (Worker) !== 'undefined') {\n try {\n let work = require('webworkify');\n this._worker = work(TransmuxingWorker);\n this._workerDestroying = false;\n this._worker.addEventListener('message', this._onWorkerMessage.bind(this));\n this._worker.postMessage({cmd: 'init', param: [mediaDataSource, config]});\n this.e = {\n onLoggingConfigChanged: this._onLoggingConfigChanged.bind(this)\n };\n LoggingControl.registerListener(this.e.onLoggingConfigChanged);\n this._worker.postMessage({cmd: 'logging_config', param: LoggingControl.getConfig()});\n } catch (error) {\n Log.e(this.TAG, 'Error while initialize transmuxing worker, fallback to inline transmuxing');\n this._worker = null;\n this._controller = new TransmuxingController(mediaDataSource, config);\n }\n } else {\n this._controller = new TransmuxingController(mediaDataSource, config);\n }\n\n if (this._controller) {\n let ctl = this._controller;\n ctl.on(TransmuxingEvents.IO_ERROR, this._onIOError.bind(this));\n ctl.on(TransmuxingEvents.DEMUX_ERROR, this._onDemuxError.bind(this));\n ctl.on(TransmuxingEvents.INIT_SEGMENT, this._onInitSegment.bind(this));\n ctl.on(TransmuxingEvents.MEDIA_SEGMENT, this._onMediaSegment.bind(this));\n ctl.on(TransmuxingEvents.LOADING_COMPLETE, this._onLoadingComplete.bind(this));\n ctl.on(TransmuxingEvents.RECOVERED_EARLY_EOF, this._onRecoveredEarlyEof.bind(this));\n ctl.on(TransmuxingEvents.MEDIA_INFO, this._onMediaInfo.bind(this));\n ctl.on(TransmuxingEvents.STATISTICS_INFO, this._onStatisticsInfo.bind(this));\n ctl.on(TransmuxingEvents.RECOMMEND_SEEKPOINT, this._onRecommendSeekpoint.bind(this));\n }\n }\n\n destroy() {\n if (this._worker) {\n if (!this._workerDestroying) {\n this._workerDestroying = true;\n this._worker.postMessage({cmd: 'destroy'});\n LoggingControl.removeListener(this.e.onLoggingConfigChanged);\n this.e = null;\n }\n } else {\n this._controller.destroy();\n this._controller = null;\n }\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n hasWorker() {\n return this._worker != null;\n }\n\n open() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'start'});\n } else {\n this._controller.start();\n }\n }\n\n close() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'stop'});\n } else {\n this._controller.stop();\n }\n }\n\n seek(milliseconds) {\n if (this._worker) {\n this._worker.postMessage({cmd: 'seek', param: milliseconds});\n } else {\n this._controller.seek(milliseconds);\n }\n }\n\n pause() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'pause'});\n } else {\n this._controller.pause();\n }\n }\n\n resume() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'resume'});\n } else {\n this._controller.resume();\n }\n }\n\n _onInitSegment(type, initSegment) {\n // do async invoke\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.INIT_SEGMENT, type, initSegment);\n });\n }\n\n _onMediaSegment(type, mediaSegment) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.MEDIA_SEGMENT, type, mediaSegment);\n });\n }\n\n _onLoadingComplete() {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.LOADING_COMPLETE);\n });\n }\n\n _onRecoveredEarlyEof() {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.RECOVERED_EARLY_EOF);\n });\n }\n\n _onMediaInfo(mediaInfo) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.MEDIA_INFO, mediaInfo);\n });\n }\n\n _onStatisticsInfo(statisticsInfo) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.STATISTICS_INFO, statisticsInfo);\n });\n }\n\n _onIOError(type, info) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.IO_ERROR, type, info);\n });\n }\n\n _onDemuxError(type, info) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.DEMUX_ERROR, type, info);\n });\n }\n\n _onRecommendSeekpoint(milliseconds) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.RECOMMEND_SEEKPOINT, milliseconds);\n });\n }\n\n _onLoggingConfigChanged(config) {\n if (this._worker) {\n this._worker.postMessage({cmd: 'logging_config', param: config});\n }\n }\n\n _onWorkerMessage(e) {\n let message = e.data;\n let data = message.data;\n\n if (message.msg === 'destroyed' || this._workerDestroying) {\n this._workerDestroying = false;\n this._worker.terminate();\n this._worker = null;\n return;\n }\n\n switch (message.msg) {\n case TransmuxingEvents.INIT_SEGMENT:\n case TransmuxingEvents.MEDIA_SEGMENT:\n this._emitter.emit(message.msg, data.type, data.data);\n break;\n case TransmuxingEvents.LOADING_COMPLETE:\n case TransmuxingEvents.RECOVERED_EARLY_EOF:\n this._emitter.emit(message.msg);\n break;\n case TransmuxingEvents.MEDIA_INFO:\n Object.setPrototypeOf(data, MediaInfo.prototype);\n this._emitter.emit(message.msg, data);\n break;\n case TransmuxingEvents.STATISTICS_INFO:\n this._emitter.emit(message.msg, data);\n break;\n case TransmuxingEvents.IO_ERROR:\n case TransmuxingEvents.DEMUX_ERROR:\n this._emitter.emit(message.msg, data.type, data.info);\n break;\n case TransmuxingEvents.RECOMMEND_SEEKPOINT:\n this._emitter.emit(message.msg, data);\n break;\n case 'logcat_callback':\n Log.emitter.emit('log', data.type, data.logcat);\n break;\n default:\n break;\n }\n }\n\n}\n\nexport default Transmuxer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport MediaInfo from './media-info.js';\nimport FLVDemuxer from '../demux/flv-demuxer.js';\nimport MP4Remuxer from '../remux/mp4-remuxer.js';\nimport DemuxErrors from '../demux/demux-errors.js';\nimport IOController from '../io/io-controller.js';\nimport TransmuxingEvents from './transmuxing-events.js';\nimport {LoaderStatus, LoaderErrors} from '../io/loader.js';\n\n// Transmuxing (IO, Demuxing, Remuxing) controller, with multipart support\nclass TransmuxingController {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'TransmuxingController';\n this._emitter = new EventEmitter();\n\n this._config = config;\n\n // treat single part media as multipart media, which has only one segment\n if (!mediaDataSource.segments) {\n mediaDataSource.segments = [{\n duration: mediaDataSource.duration,\n filesize: mediaDataSource.filesize,\n url: mediaDataSource.url\n }];\n }\n\n // fill in default IO params if not exists\n if (typeof mediaDataSource.cors !== 'boolean') {\n mediaDataSource.cors = true;\n }\n if (typeof mediaDataSource.withCredentials !== 'boolean') {\n mediaDataSource.withCredentials = false;\n }\n\n this._mediaDataSource = mediaDataSource;\n this._currentSegmentIndex = 0;\n let totalDuration = 0;\n\n this._mediaDataSource.segments.forEach((segment) => {\n // timestampBase for each segment, and calculate total duration\n segment.timestampBase = totalDuration;\n totalDuration += segment.duration;\n // params needed by IOController\n segment.cors = mediaDataSource.cors;\n segment.withCredentials = mediaDataSource.withCredentials;\n // referrer policy control, if exist\n if (config.referrerPolicy) {\n segment.referrerPolicy = config.referrerPolicy;\n }\n });\n\n if (!isNaN(totalDuration) && this._mediaDataSource.duration !== totalDuration) {\n this._mediaDataSource.duration = totalDuration;\n }\n\n this._mediaInfo = null;\n this._demuxer = null;\n this._remuxer = null;\n this._ioctl = null;\n\n this._pendingSeekTime = null;\n this._pendingResolveSeekPoint = null;\n\n this._statisticsReporter = null;\n }\n\n destroy() {\n this._mediaInfo = null;\n this._mediaDataSource = null;\n\n if (this._statisticsReporter) {\n this._disableStatisticsReporter();\n }\n if (this._ioctl) {\n this._ioctl.destroy();\n this._ioctl = null;\n }\n if (this._demuxer) {\n this._demuxer.destroy();\n this._demuxer = null;\n }\n if (this._remuxer) {\n this._remuxer.destroy();\n this._remuxer = null;\n }\n\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n start() {\n this._loadSegment(0);\n this._enableStatisticsReporter();\n }\n\n _loadSegment(segmentIndex, optionalFrom) {\n this._currentSegmentIndex = segmentIndex;\n let dataSource = this._mediaDataSource.segments[segmentIndex];\n\n let ioctl = this._ioctl = new IOController(dataSource, this._config, segmentIndex);\n ioctl.onError = this._onIOException.bind(this);\n ioctl.onSeeked = this._onIOSeeked.bind(this);\n ioctl.onComplete = this._onIOComplete.bind(this);\n ioctl.onRedirect = this._onIORedirect.bind(this);\n ioctl.onRecoveredEarlyEof = this._onIORecoveredEarlyEof.bind(this);\n\n if (optionalFrom) {\n this._demuxer.bindDataSource(this._ioctl);\n } else {\n ioctl.onDataArrival = this._onInitChunkArrival.bind(this);\n }\n\n ioctl.open(optionalFrom);\n }\n\n stop() {\n this._internalAbort();\n this._disableStatisticsReporter();\n }\n\n _internalAbort() {\n if (this._ioctl) {\n this._ioctl.destroy();\n this._ioctl = null;\n }\n }\n\n pause() { // take a rest\n if (this._ioctl && this._ioctl.isWorking()) {\n this._ioctl.pause();\n this._disableStatisticsReporter();\n }\n }\n\n resume() {\n if (this._ioctl && this._ioctl.isPaused()) {\n this._ioctl.resume();\n this._enableStatisticsReporter();\n }\n }\n\n seek(milliseconds) {\n if (this._mediaInfo == null || !this._mediaInfo.isSeekable()) {\n return;\n }\n\n let targetSegmentIndex = this._searchSegmentIndexContains(milliseconds);\n\n if (targetSegmentIndex === this._currentSegmentIndex) {\n // intra-segment seeking\n let segmentInfo = this._mediaInfo.segments[targetSegmentIndex];\n\n if (segmentInfo == undefined) {\n // current segment loading started, but mediainfo hasn't received yet\n // wait for the metadata loaded, then seek to expected position\n this._pendingSeekTime = milliseconds;\n } else {\n let keyframe = segmentInfo.getNearestKeyframe(milliseconds);\n this._remuxer.seek(keyframe.milliseconds);\n this._ioctl.seek(keyframe.fileposition);\n // Will be resolved in _onRemuxerMediaSegmentArrival()\n this._pendingResolveSeekPoint = keyframe.milliseconds;\n }\n } else {\n // cross-segment seeking\n let targetSegmentInfo = this._mediaInfo.segments[targetSegmentIndex];\n\n if (targetSegmentInfo == undefined) {\n // target segment hasn't been loaded. We need metadata then seek to expected time\n this._pendingSeekTime = milliseconds;\n this._internalAbort();\n this._remuxer.seek();\n this._remuxer.insertDiscontinuity();\n this._loadSegment(targetSegmentIndex);\n // Here we wait for the metadata loaded, then seek to expected position\n } else {\n // We have target segment's metadata, direct seek to target position\n let keyframe = targetSegmentInfo.getNearestKeyframe(milliseconds);\n this._internalAbort();\n this._remuxer.seek(milliseconds);\n this._remuxer.insertDiscontinuity();\n this._demuxer.resetMediaInfo();\n this._demuxer.timestampBase = this._mediaDataSource.segments[targetSegmentIndex].timestampBase;\n this._loadSegment(targetSegmentIndex, keyframe.fileposition);\n this._pendingResolveSeekPoint = keyframe.milliseconds;\n this._reportSegmentMediaInfo(targetSegmentIndex);\n }\n }\n\n this._enableStatisticsReporter();\n }\n\n _searchSegmentIndexContains(milliseconds) {\n let segments = this._mediaDataSource.segments;\n let idx = segments.length - 1;\n\n for (let i = 0; i < segments.length; i++) {\n if (milliseconds < segments[i].timestampBase) {\n idx = i - 1;\n break;\n }\n }\n return idx;\n }\n\n _onInitChunkArrival(data, byteStart) {\n let probeData = null;\n let consumed = 0;\n\n if (byteStart > 0) {\n // IOController seeked immediately after opened, byteStart > 0 callback may received\n this._demuxer.bindDataSource(this._ioctl);\n this._demuxer.timestampBase = this._mediaDataSource.segments[this._currentSegmentIndex].timestampBase;\n\n consumed = this._demuxer.parseChunks(data, byteStart);\n } else if ((probeData = FLVDemuxer.probe(data)).match) {\n // Always create new FLVDemuxer\n this._demuxer = new FLVDemuxer(probeData, this._config);\n\n if (!this._remuxer) {\n this._remuxer = new MP4Remuxer(this._config);\n }\n\n let mds = this._mediaDataSource;\n if (mds.duration != undefined && !isNaN(mds.duration)) {\n this._demuxer.overridedDuration = mds.duration;\n }\n if (typeof mds.hasAudio === 'boolean') {\n this._demuxer.overridedHasAudio = mds.hasAudio;\n }\n if (typeof mds.hasVideo === 'boolean') {\n this._demuxer.overridedHasVideo = mds.hasVideo;\n }\n\n this._demuxer.timestampBase = mds.segments[this._currentSegmentIndex].timestampBase;\n\n this._demuxer.onError = this._onDemuxException.bind(this);\n this._demuxer.onMediaInfo = this._onMediaInfo.bind(this);\n\n this._remuxer.bindDataSource(this._demuxer\n .bindDataSource(this._ioctl\n ));\n\n this._remuxer.onInitSegment = this._onRemuxerInitSegmentArrival.bind(this);\n this._remuxer.onMediaSegment = this._onRemuxerMediaSegmentArrival.bind(this);\n\n consumed = this._demuxer.parseChunks(data, byteStart);\n } else {\n probeData = null;\n Log.e(this.TAG, 'Non-FLV, Unsupported media type!');\n Promise.resolve().then(() => {\n this._internalAbort();\n });\n this._emitter.emit(TransmuxingEvents.DEMUX_ERROR, DemuxErrors.FORMAT_UNSUPPORTED, 'Non-FLV, Unsupported media type');\n\n consumed = 0;\n }\n\n return consumed;\n }\n\n _onMediaInfo(mediaInfo) {\n if (this._mediaInfo == null) {\n // Store first segment's mediainfo as global mediaInfo\n this._mediaInfo = Object.assign({}, mediaInfo);\n this._mediaInfo.keyframesIndex = null;\n this._mediaInfo.segments = [];\n this._mediaInfo.segmentCount = this._mediaDataSource.segments.length;\n Object.setPrototypeOf(this._mediaInfo, MediaInfo.prototype);\n }\n\n let segmentInfo = Object.assign({}, mediaInfo);\n Object.setPrototypeOf(segmentInfo, MediaInfo.prototype);\n this._mediaInfo.segments[this._currentSegmentIndex] = segmentInfo;\n\n // notify mediaInfo update\n this._reportSegmentMediaInfo(this._currentSegmentIndex);\n\n if (this._pendingSeekTime != null) {\n Promise.resolve().then(() => {\n let target = this._pendingSeekTime;\n this._pendingSeekTime = null;\n this.seek(target);\n });\n }\n }\n\n _onIOSeeked() {\n this._remuxer.insertDiscontinuity();\n }\n\n _onIOComplete(extraData) {\n let segmentIndex = extraData;\n let nextSegmentIndex = segmentIndex + 1;\n\n if (nextSegmentIndex < this._mediaDataSource.segments.length) {\n this._internalAbort();\n this._loadSegment(nextSegmentIndex);\n } else {\n this._emitter.emit(TransmuxingEvents.LOADING_COMPLETE);\n this._disableStatisticsReporter();\n }\n }\n\n _onIORedirect(redirectedURL) {\n let segmentIndex = this._ioctl.extraData;\n this._mediaDataSource.segments[segmentIndex].redirectedURL = redirectedURL;\n }\n\n _onIORecoveredEarlyEof() {\n this._emitter.emit(TransmuxingEvents.RECOVERED_EARLY_EOF);\n }\n\n _onIOException(type, info) {\n Log.e(this.TAG, `IOException: type = ${type}, code = ${info.code}, msg = ${info.msg}`);\n this._emitter.emit(TransmuxingEvents.IO_ERROR, type, info);\n this._disableStatisticsReporter();\n }\n\n _onDemuxException(type, info) {\n Log.e(this.TAG, `DemuxException: type = ${type}, info = ${info}`);\n this._emitter.emit(TransmuxingEvents.DEMUX_ERROR, type, info);\n }\n\n _onRemuxerInitSegmentArrival(type, initSegment) {\n this._emitter.emit(TransmuxingEvents.INIT_SEGMENT, type, initSegment);\n }\n\n _onRemuxerMediaSegmentArrival(type, mediaSegment) {\n if (this._pendingSeekTime != null) {\n // Media segments after new-segment cross-seeking should be dropped.\n return;\n }\n this._emitter.emit(TransmuxingEvents.MEDIA_SEGMENT, type, mediaSegment);\n\n // Resolve pending seekPoint\n if (this._pendingResolveSeekPoint != null && type === 'video') {\n let syncPoints = mediaSegment.info.syncPoints;\n let seekpoint = this._pendingResolveSeekPoint;\n this._pendingResolveSeekPoint = null;\n\n // Safari: Pass PTS for recommend_seekpoint\n if (Browser.safari && syncPoints.length > 0 && syncPoints[0].originalDts === seekpoint) {\n seekpoint = syncPoints[0].pts;\n }\n // else: use original DTS (keyframe.milliseconds)\n\n this._emitter.emit(TransmuxingEvents.RECOMMEND_SEEKPOINT, seekpoint);\n }\n }\n\n _enableStatisticsReporter() {\n if (this._statisticsReporter == null) {\n this._statisticsReporter = self.setInterval(\n this._reportStatisticsInfo.bind(this),\n this._config.statisticsInfoReportInterval);\n }\n }\n\n _disableStatisticsReporter() {\n if (this._statisticsReporter) {\n self.clearInterval(this._statisticsReporter);\n this._statisticsReporter = null;\n }\n }\n\n _reportSegmentMediaInfo(segmentIndex) {\n let segmentInfo = this._mediaInfo.segments[segmentIndex];\n let exportInfo = Object.assign({}, segmentInfo);\n\n exportInfo.duration = this._mediaInfo.duration;\n exportInfo.segmentCount = this._mediaInfo.segmentCount;\n delete exportInfo.segments;\n delete exportInfo.keyframesIndex;\n\n this._emitter.emit(TransmuxingEvents.MEDIA_INFO, exportInfo);\n }\n\n _reportStatisticsInfo() {\n let info = {};\n\n info.url = this._ioctl.currentURL;\n info.hasRedirect = this._ioctl.hasRedirect;\n if (info.hasRedirect) {\n info.redirectedURL = this._ioctl.currentRedirectedURL;\n }\n\n info.speed = this._ioctl.currentSpeed;\n info.loaderType = this._ioctl.loaderType;\n info.currentSegmentIndex = this._currentSegmentIndex;\n info.totalSegmentCount = this._mediaDataSource.segments.length;\n\n this._emitter.emit(TransmuxingEvents.STATISTICS_INFO, info);\n }\n\n}\n\nexport default TransmuxingController;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst TransmuxingEvents = {\n IO_ERROR: 'io_error',\n DEMUX_ERROR: 'demux_error',\n INIT_SEGMENT: 'init_segment',\n MEDIA_SEGMENT: 'media_segment',\n LOADING_COMPLETE: 'loading_complete',\n RECOVERED_EARLY_EOF: 'recovered_early_eof',\n MEDIA_INFO: 'media_info',\n STATISTICS_INFO: 'statistics_info',\n RECOMMEND_SEEKPOINT: 'recommend_seekpoint'\n};\n\nexport default TransmuxingEvents;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport LoggingControl from '../utils/logging-control.js';\nimport Polyfill from '../utils/polyfill.js';\nimport TransmuxingController from './transmuxing-controller.js';\nimport TransmuxingEvents from './transmuxing-events.js';\n\n/* post message to worker:\n data: {\n cmd: string\n param: any\n }\n\n receive message from worker:\n data: {\n msg: string,\n data: any\n }\n */\n\nlet TransmuxingWorker = function (self) {\n\n let TAG = 'TransmuxingWorker';\n let controller = null;\n let logcatListener = onLogcatCallback.bind(this);\n\n Polyfill.install();\n\n self.addEventListener('message', function (e) {\n switch (e.data.cmd) {\n case 'init':\n controller = new TransmuxingController(e.data.param[0], e.data.param[1]);\n controller.on(TransmuxingEvents.IO_ERROR, onIOError.bind(this));\n controller.on(TransmuxingEvents.DEMUX_ERROR, onDemuxError.bind(this));\n controller.on(TransmuxingEvents.INIT_SEGMENT, onInitSegment.bind(this));\n controller.on(TransmuxingEvents.MEDIA_SEGMENT, onMediaSegment.bind(this));\n controller.on(TransmuxingEvents.LOADING_COMPLETE, onLoadingComplete.bind(this));\n controller.on(TransmuxingEvents.RECOVERED_EARLY_EOF, onRecoveredEarlyEof.bind(this));\n controller.on(TransmuxingEvents.MEDIA_INFO, onMediaInfo.bind(this));\n controller.on(TransmuxingEvents.STATISTICS_INFO, onStatisticsInfo.bind(this));\n controller.on(TransmuxingEvents.RECOMMEND_SEEKPOINT, onRecommendSeekpoint.bind(this));\n break;\n case 'destroy':\n if (controller) {\n controller.destroy();\n controller = null;\n }\n self.postMessage({msg: 'destroyed'});\n break;\n case 'start':\n controller.start();\n break;\n case 'stop':\n controller.stop();\n break;\n case 'seek':\n controller.seek(e.data.param);\n break;\n case 'pause':\n controller.pause();\n break;\n case 'resume':\n controller.resume();\n break;\n case 'logging_config': {\n let config = e.data.param;\n LoggingControl.applyConfig(config);\n\n if (config.enableCallback === true) {\n LoggingControl.addLogListener(logcatListener);\n } else {\n LoggingControl.removeLogListener(logcatListener);\n }\n break;\n }\n }\n });\n\n function onInitSegment(type, initSegment) {\n let obj = {\n msg: TransmuxingEvents.INIT_SEGMENT,\n data: {\n type: type,\n data: initSegment\n }\n };\n self.postMessage(obj, [initSegment.data]); // data: ArrayBuffer\n }\n\n function onMediaSegment(type, mediaSegment) {\n let obj = {\n msg: TransmuxingEvents.MEDIA_SEGMENT,\n data: {\n type: type,\n data: mediaSegment\n }\n };\n self.postMessage(obj, [mediaSegment.data]); // data: ArrayBuffer\n }\n\n function onLoadingComplete() {\n let obj = {\n msg: TransmuxingEvents.LOADING_COMPLETE\n };\n self.postMessage(obj);\n }\n\n function onRecoveredEarlyEof() {\n let obj = {\n msg: TransmuxingEvents.RECOVERED_EARLY_EOF\n };\n self.postMessage(obj);\n }\n\n function onMediaInfo(mediaInfo) {\n let obj = {\n msg: TransmuxingEvents.MEDIA_INFO,\n data: mediaInfo\n };\n self.postMessage(obj);\n }\n\n function onStatisticsInfo(statInfo) {\n let obj = {\n msg: TransmuxingEvents.STATISTICS_INFO,\n data: statInfo\n };\n self.postMessage(obj);\n }\n\n function onIOError(type, info) {\n self.postMessage({\n msg: TransmuxingEvents.IO_ERROR,\n data: {\n type: type,\n info: info\n }\n });\n }\n\n function onDemuxError(type, info) {\n self.postMessage({\n msg: TransmuxingEvents.DEMUX_ERROR,\n data: {\n type: type,\n info: info\n }\n });\n }\n\n function onRecommendSeekpoint(milliseconds) {\n self.postMessage({\n msg: TransmuxingEvents.RECOMMEND_SEEKPOINT,\n data: milliseconds\n });\n }\n\n function onLogcatCallback(type, str) {\n self.postMessage({\n msg: 'logcat_callback',\n data: {\n type: type,\n logcat: str\n }\n });\n }\n\n};\n\nexport default TransmuxingWorker;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport decodeUTF8 from '../utils/utf8-conv.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\nlet le = (function () {\n let buf = new ArrayBuffer(2);\n (new DataView(buf)).setInt16(0, 256, true); // little-endian write\n return (new Int16Array(buf))[0] === 256; // platform-spec read, if equal then LE\n})();\n\nclass AMF {\n\n static parseScriptData(arrayBuffer, dataOffset, dataSize) {\n let data = {};\n\n try {\n let name = AMF.parseValue(arrayBuffer, dataOffset, dataSize);\n let value = AMF.parseValue(arrayBuffer, dataOffset + name.size, dataSize - name.size);\n\n data[name.data] = value.data;\n } catch (e) {\n Log.e('AMF', e.toString());\n }\n\n return data;\n }\n\n static parseObject(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 3) {\n throw new IllegalStateException('Data not enough when parse ScriptDataObject');\n }\n let name = AMF.parseString(arrayBuffer, dataOffset, dataSize);\n let value = AMF.parseValue(arrayBuffer, dataOffset + name.size, dataSize - name.size);\n let isObjectEnd = value.objectEnd;\n\n return {\n data: {\n name: name.data,\n value: value.data\n },\n size: name.size + value.size,\n objectEnd: isObjectEnd\n };\n }\n\n static parseVariable(arrayBuffer, dataOffset, dataSize) {\n return AMF.parseObject(arrayBuffer, dataOffset, dataSize);\n }\n\n static parseString(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 2) {\n throw new IllegalStateException('Data not enough when parse String');\n }\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n let length = v.getUint16(0, !le);\n\n let str;\n if (length > 0) {\n str = decodeUTF8(new Uint8Array(arrayBuffer, dataOffset + 2, length));\n } else {\n str = '';\n }\n\n return {\n data: str,\n size: 2 + length\n };\n }\n\n static parseLongString(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 4) {\n throw new IllegalStateException('Data not enough when parse LongString');\n }\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n let length = v.getUint32(0, !le);\n\n let str;\n if (length > 0) {\n str = decodeUTF8(new Uint8Array(arrayBuffer, dataOffset + 4, length));\n } else {\n str = '';\n }\n\n return {\n data: str,\n size: 4 + length\n };\n }\n\n static parseDate(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 10) {\n throw new IllegalStateException('Data size invalid when parse Date');\n }\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n let timestamp = v.getFloat64(0, !le);\n let localTimeOffset = v.getInt16(8, !le);\n timestamp += localTimeOffset * 60 * 1000; // get UTC time\n\n return {\n data: new Date(timestamp),\n size: 8 + 2\n };\n }\n\n static parseValue(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 1) {\n throw new IllegalStateException('Data not enough when parse Value');\n }\n\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let offset = 1;\n let type = v.getUint8(0);\n let value;\n let objectEnd = false;\n\n try {\n switch (type) {\n case 0: // Number(Double) type\n value = v.getFloat64(1, !le);\n offset += 8;\n break;\n case 1: { // Boolean type\n let b = v.getUint8(1);\n value = b ? true : false;\n offset += 1;\n break;\n }\n case 2: { // String type\n let amfstr = AMF.parseString(arrayBuffer, dataOffset + 1, dataSize - 1);\n value = amfstr.data;\n offset += amfstr.size;\n break;\n }\n case 3: { // Object(s) type\n value = {};\n let terminal = 0; // workaround for malformed Objects which has missing ScriptDataObjectEnd\n if ((v.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {\n terminal = 3;\n }\n while (offset < dataSize - 4) { // 4 === type(UI8) + ScriptDataObjectEnd(UI24)\n let amfobj = AMF.parseObject(arrayBuffer, dataOffset + offset, dataSize - offset - terminal);\n if (amfobj.objectEnd)\n break;\n value[amfobj.data.name] = amfobj.data.value;\n offset += amfobj.size;\n }\n if (offset <= dataSize - 3) {\n let marker = v.getUint32(offset - 1, !le) & 0x00FFFFFF;\n if (marker === 9) {\n offset += 3;\n }\n }\n break;\n }\n case 8: { // ECMA array type (Mixed array)\n value = {};\n offset += 4; // ECMAArrayLength(UI32)\n let terminal = 0; // workaround for malformed MixedArrays which has missing ScriptDataObjectEnd\n if ((v.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {\n terminal = 3;\n }\n while (offset < dataSize - 8) { // 8 === type(UI8) + ECMAArrayLength(UI32) + ScriptDataVariableEnd(UI24)\n let amfvar = AMF.parseVariable(arrayBuffer, dataOffset + offset, dataSize - offset - terminal);\n if (amfvar.objectEnd)\n break;\n value[amfvar.data.name] = amfvar.data.value;\n offset += amfvar.size;\n }\n if (offset <= dataSize - 3) {\n let marker = v.getUint32(offset - 1, !le) & 0x00FFFFFF;\n if (marker === 9) {\n offset += 3;\n }\n }\n break;\n }\n case 9: // ScriptDataObjectEnd\n value = undefined;\n offset = 1;\n objectEnd = true;\n break;\n case 10: { // Strict array type\n // ScriptDataValue[n]. NOTE: according to video_file_format_spec_v10_1.pdf\n value = [];\n let strictArrayLength = v.getUint32(1, !le);\n offset += 4;\n for (let i = 0; i < strictArrayLength; i++) {\n let val = AMF.parseValue(arrayBuffer, dataOffset + offset, dataSize - offset);\n value.push(val.data);\n offset += val.size;\n }\n break;\n }\n case 11: { // Date type\n let date = AMF.parseDate(arrayBuffer, dataOffset + 1, dataSize - 1);\n value = date.data;\n offset += date.size;\n break;\n }\n case 12: { // Long string type\n let amfLongStr = AMF.parseString(arrayBuffer, dataOffset + 1, dataSize - 1);\n value = amfLongStr.data;\n offset += amfLongStr.size;\n break;\n }\n default:\n // ignore and skip\n offset = dataSize;\n Log.w('AMF', 'Unsupported AMF value type ' + type);\n }\n } catch (e) {\n Log.e('AMF', e.toString());\n }\n\n return {\n data: value,\n size: offset,\n objectEnd: objectEnd\n };\n }\n\n}\n\nexport default AMF;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst DemuxErrors = {\n OK: 'OK',\n FORMAT_ERROR: 'FormatError',\n FORMAT_UNSUPPORTED: 'FormatUnsupported',\n CODEC_UNSUPPORTED: 'CodecUnsupported'\n};\n\nexport default DemuxErrors;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {IllegalStateException, InvalidArgumentException} from '../utils/exception.js';\n\n// Exponential-Golomb buffer decoder\nclass ExpGolomb {\n\n constructor(uint8array) {\n this.TAG = 'ExpGolomb';\n\n this._buffer = uint8array;\n this._buffer_index = 0;\n this._total_bytes = uint8array.byteLength;\n this._total_bits = uint8array.byteLength * 8;\n this._current_word = 0;\n this._current_word_bits_left = 0;\n }\n\n destroy() {\n this._buffer = null;\n }\n\n _fillCurrentWord() {\n let buffer_bytes_left = this._total_bytes - this._buffer_index;\n if (buffer_bytes_left <= 0)\n throw new IllegalStateException('ExpGolomb: _fillCurrentWord() but no bytes available');\n\n let bytes_read = Math.min(4, buffer_bytes_left);\n let word = new Uint8Array(4);\n word.set(this._buffer.subarray(this._buffer_index, this._buffer_index + bytes_read));\n this._current_word = new DataView(word.buffer).getUint32(0, false);\n\n this._buffer_index += bytes_read;\n this._current_word_bits_left = bytes_read * 8;\n }\n\n readBits(bits) {\n if (bits > 32)\n throw new InvalidArgumentException('ExpGolomb: readBits() bits exceeded max 32bits!');\n\n if (bits <= this._current_word_bits_left) {\n let result = this._current_word >>> (32 - bits);\n this._current_word <<= bits;\n this._current_word_bits_left -= bits;\n return result;\n }\n\n let result = this._current_word_bits_left ? this._current_word : 0;\n result = result >>> (32 - this._current_word_bits_left);\n let bits_need_left = bits - this._current_word_bits_left;\n\n this._fillCurrentWord();\n let bits_read_next = Math.min(bits_need_left, this._current_word_bits_left);\n\n let result2 = this._current_word >>> (32 - bits_read_next);\n this._current_word <<= bits_read_next;\n this._current_word_bits_left -= bits_read_next;\n\n result = (result << bits_read_next) | result2;\n return result;\n }\n\n readBool() {\n return this.readBits(1) === 1;\n }\n\n readByte() {\n return this.readBits(8);\n }\n\n _skipLeadingZero() {\n let zero_count;\n for (zero_count = 0; zero_count < this._current_word_bits_left; zero_count++) {\n if (0 !== (this._current_word & (0x80000000 >>> zero_count))) {\n this._current_word <<= zero_count;\n this._current_word_bits_left -= zero_count;\n return zero_count;\n }\n }\n this._fillCurrentWord();\n return zero_count + this._skipLeadingZero();\n }\n\n readUEG() { // unsigned exponential golomb\n let leading_zeros = this._skipLeadingZero();\n return this.readBits(leading_zeros + 1) - 1;\n }\n\n readSEG() { // signed exponential golomb\n let value = this.readUEG();\n if (value & 0x01) {\n return (value + 1) >>> 1;\n } else {\n return -1 * (value >>> 1);\n }\n }\n\n}\n\nexport default ExpGolomb;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport AMF from './amf-parser.js';\nimport SPSParser from './sps-parser.js';\nimport DemuxErrors from './demux-errors.js';\nimport MediaInfo from '../core/media-info.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\nfunction Swap16(src) {\n return (((src >>> 8) & 0xFF) |\n ((src & 0xFF) << 8));\n}\n\nfunction Swap32(src) {\n return (((src & 0xFF000000) >>> 24) |\n ((src & 0x00FF0000) >>> 8) |\n ((src & 0x0000FF00) << 8) |\n ((src & 0x000000FF) << 24));\n}\n\nfunction ReadBig32(array, index) {\n return ((array[index] << 24) |\n (array[index + 1] << 16) |\n (array[index + 2] << 8) |\n (array[index + 3]));\n}\n\n\nclass FLVDemuxer {\n\n constructor(probeData, config) {\n this.TAG = 'FLVDemuxer';\n\n this._config = config;\n\n this._onError = null;\n this._onMediaInfo = null;\n this._onTrackMetadata = null;\n this._onDataAvailable = null;\n\n this._dataOffset = probeData.dataOffset;\n this._firstParse = true;\n this._dispatch = false;\n\n this._hasAudio = probeData.hasAudioTrack;\n this._hasVideo = probeData.hasVideoTrack;\n\n this._hasAudioFlagOverrided = false;\n this._hasVideoFlagOverrided = false;\n\n this._audioInitialMetadataDispatched = false;\n this._videoInitialMetadataDispatched = false;\n\n this._mediaInfo = new MediaInfo();\n this._mediaInfo.hasAudio = this._hasAudio;\n this._mediaInfo.hasVideo = this._hasVideo;\n this._metadata = null;\n this._audioMetadata = null;\n this._videoMetadata = null;\n\n this._naluLengthSize = 4;\n this._timestampBase = 0; // int32, in milliseconds\n this._timescale = 1000;\n this._duration = 0; // int32, in milliseconds\n this._durationOverrided = false;\n this._referenceFrameRate = {\n fixed: true,\n fps: 23.976,\n fps_num: 23976,\n fps_den: 1000\n };\n\n this._flvSoundRateTable = [5500, 11025, 22050, 44100, 48000];\n\n this._mpegSamplingRates = [\n 96000, 88200, 64000, 48000, 44100, 32000,\n 24000, 22050, 16000, 12000, 11025, 8000, 7350\n ];\n\n this._mpegAudioV10SampleRateTable = [44100, 48000, 32000, 0];\n this._mpegAudioV20SampleRateTable = [22050, 24000, 16000, 0];\n this._mpegAudioV25SampleRateTable = [11025, 12000, 8000, 0];\n\n this._mpegAudioL1BitRateTable = [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1];\n this._mpegAudioL2BitRateTable = [0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1];\n this._mpegAudioL3BitRateTable = [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1];\n\n this._videoTrack = {type: 'video', id: 1, sequenceNumber: 0, samples: [], length: 0};\n this._audioTrack = {type: 'audio', id: 2, sequenceNumber: 0, samples: [], length: 0};\n\n this._littleEndian = (function () {\n let buf = new ArrayBuffer(2);\n (new DataView(buf)).setInt16(0, 256, true); // little-endian write\n return (new Int16Array(buf))[0] === 256; // platform-spec read, if equal then LE\n })();\n }\n\n destroy() {\n this._mediaInfo = null;\n this._metadata = null;\n this._audioMetadata = null;\n this._videoMetadata = null;\n this._videoTrack = null;\n this._audioTrack = null;\n\n this._onError = null;\n this._onMediaInfo = null;\n this._onTrackMetadata = null;\n this._onDataAvailable = null;\n }\n\n static probe(buffer) {\n let data = new Uint8Array(buffer);\n let mismatch = {match: false};\n\n if (data[0] !== 0x46 || data[1] !== 0x4C || data[2] !== 0x56 || data[3] !== 0x01) {\n return mismatch;\n }\n\n let hasAudio = ((data[4] & 4) >>> 2) !== 0;\n let hasVideo = (data[4] & 1) !== 0;\n\n let offset = ReadBig32(data, 5);\n\n if (offset < 9) {\n return mismatch;\n }\n\n return {\n match: true,\n consumed: offset,\n dataOffset: offset,\n hasAudioTrack: hasAudio,\n hasVideoTrack: hasVideo\n };\n }\n\n bindDataSource(loader) {\n loader.onDataArrival = this.parseChunks.bind(this);\n return this;\n }\n\n // prototype: function(type: string, metadata: any): void\n get onTrackMetadata() {\n return this._onTrackMetadata;\n }\n\n set onTrackMetadata(callback) {\n this._onTrackMetadata = callback;\n }\n\n // prototype: function(mediaInfo: MediaInfo): void\n get onMediaInfo() {\n return this._onMediaInfo;\n }\n\n set onMediaInfo(callback) {\n this._onMediaInfo = callback;\n }\n\n // prototype: function(type: number, info: string): void\n get onError() {\n return this._onError;\n }\n\n set onError(callback) {\n this._onError = callback;\n }\n\n // prototype: function(videoTrack: any, audioTrack: any): void\n get onDataAvailable() {\n return this._onDataAvailable;\n }\n\n set onDataAvailable(callback) {\n this._onDataAvailable = callback;\n }\n\n // timestamp base for output samples, must be in milliseconds\n get timestampBase() {\n return this._timestampBase;\n }\n\n set timestampBase(base) {\n this._timestampBase = base;\n }\n\n get overridedDuration() {\n return this._duration;\n }\n\n // Force-override media duration. Must be in milliseconds, int32\n set overridedDuration(duration) {\n this._durationOverrided = true;\n this._duration = duration;\n this._mediaInfo.duration = duration;\n }\n\n // Force-override audio track present flag, boolean\n set overridedHasAudio(hasAudio) {\n this._hasAudioFlagOverrided = true;\n this._hasAudio = hasAudio;\n this._mediaInfo.hasAudio = hasAudio;\n }\n\n // Force-override video track present flag, boolean\n set overridedHasVideo(hasVideo) {\n this._hasVideoFlagOverrided = true;\n this._hasVideo = hasVideo;\n this._mediaInfo.hasVideo = hasVideo;\n }\n\n resetMediaInfo() {\n this._mediaInfo = new MediaInfo();\n }\n\n _isInitialMetadataDispatched() {\n if (this._hasAudio && this._hasVideo) { // both audio & video\n return this._audioInitialMetadataDispatched && this._videoInitialMetadataDispatched;\n }\n if (this._hasAudio && !this._hasVideo) { // audio only\n return this._audioInitialMetadataDispatched;\n }\n if (!this._hasAudio && this._hasVideo) { // video only\n return this._videoInitialMetadataDispatched;\n }\n return false;\n }\n\n // function parseChunks(chunk: ArrayBuffer, byteStart: number): number;\n parseChunks(chunk, byteStart) {\n if (!this._onError || !this._onMediaInfo || !this._onTrackMetadata || !this._onDataAvailable) {\n throw new IllegalStateException('Flv: onError & onMediaInfo & onTrackMetadata & onDataAvailable callback must be specified');\n }\n\n let offset = 0;\n let le = this._littleEndian;\n\n if (byteStart === 0) { // buffer with FLV header\n if (chunk.byteLength > 13) {\n let probeData = FLVDemuxer.probe(chunk);\n offset = probeData.dataOffset;\n } else {\n return 0;\n }\n }\n\n if (this._firstParse) { // handle PreviousTagSize0 before Tag1\n this._firstParse = false;\n if (byteStart + offset !== this._dataOffset) {\n Log.w(this.TAG, 'First time parsing but chunk byteStart invalid!');\n }\n\n let v = new DataView(chunk, offset);\n let prevTagSize0 = v.getUint32(0, !le);\n if (prevTagSize0 !== 0) {\n Log.w(this.TAG, 'PrevTagSize0 !== 0 !!!');\n }\n offset += 4;\n }\n\n while (offset < chunk.byteLength) {\n this._dispatch = true;\n\n let v = new DataView(chunk, offset);\n\n if (offset + 11 + 4 > chunk.byteLength) {\n // data not enough for parsing an flv tag\n break;\n }\n\n let tagType = v.getUint8(0);\n let dataSize = v.getUint32(0, !le) & 0x00FFFFFF;\n\n if (offset + 11 + dataSize + 4 > chunk.byteLength) {\n // data not enough for parsing actual data body\n break;\n }\n\n if (tagType !== 8 && tagType !== 9 && tagType !== 18) {\n Log.w(this.TAG, `Unsupported tag type ${tagType}, skipped`);\n // consume the whole tag (skip it)\n offset += 11 + dataSize + 4;\n continue;\n }\n\n let ts2 = v.getUint8(4);\n let ts1 = v.getUint8(5);\n let ts0 = v.getUint8(6);\n let ts3 = v.getUint8(7);\n\n let timestamp = ts0 | (ts1 << 8) | (ts2 << 16) | (ts3 << 24);\n\n let streamId = v.getUint32(7, !le) & 0x00FFFFFF;\n if (streamId !== 0) {\n Log.w(this.TAG, 'Meet tag which has StreamID != 0!');\n }\n\n let dataOffset = offset + 11;\n\n switch (tagType) {\n case 8: // Audio\n this._parseAudioData(chunk, dataOffset, dataSize, timestamp);\n break;\n case 9: // Video\n this._parseVideoData(chunk, dataOffset, dataSize, timestamp, byteStart + offset);\n break;\n case 18: // ScriptDataObject\n this._parseScriptData(chunk, dataOffset, dataSize);\n break;\n }\n\n let prevTagSize = v.getUint32(11 + dataSize, !le);\n if (prevTagSize !== 11 + dataSize) {\n Log.w(this.TAG, `Invalid PrevTagSize ${prevTagSize}`);\n }\n\n offset += 11 + dataSize + 4; // tagBody + dataSize + prevTagSize\n }\n\n // dispatch parsed frames to consumer (typically, the remuxer)\n if (this._isInitialMetadataDispatched()) {\n if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {\n this._onDataAvailable(this._audioTrack, this._videoTrack);\n }\n }\n\n return offset; // consumed bytes, just equals latest offset index\n }\n\n _parseScriptData(arrayBuffer, dataOffset, dataSize) {\n let scriptData = AMF.parseScriptData(arrayBuffer, dataOffset, dataSize);\n\n if (scriptData.hasOwnProperty('onMetaData')) {\n if (scriptData.onMetaData == null || typeof scriptData.onMetaData !== 'object') {\n Log.w(this.TAG, 'Invalid onMetaData structure!');\n return;\n }\n if (this._metadata) {\n Log.w(this.TAG, 'Found another onMetaData tag!');\n }\n this._metadata = scriptData;\n let onMetaData = this._metadata.onMetaData;\n\n if (typeof onMetaData.hasAudio === 'boolean') { // hasAudio\n if (this._hasAudioFlagOverrided === false) {\n this._hasAudio = onMetaData.hasAudio;\n this._mediaInfo.hasAudio = this._hasAudio;\n }\n }\n if (typeof onMetaData.hasVideo === 'boolean') { // hasVideo\n if (this._hasVideoFlagOverrided === false) {\n this._hasVideo = onMetaData.hasVideo;\n this._mediaInfo.hasVideo = this._hasVideo;\n }\n }\n if (typeof onMetaData.audiodatarate === 'number') { // audiodatarate\n this._mediaInfo.audioDataRate = onMetaData.audiodatarate;\n }\n if (typeof onMetaData.videodatarate === 'number') { // videodatarate\n this._mediaInfo.videoDataRate = onMetaData.videodatarate;\n }\n if (typeof onMetaData.width === 'number') { // width\n this._mediaInfo.width = onMetaData.width;\n }\n if (typeof onMetaData.height === 'number') { // height\n this._mediaInfo.height = onMetaData.height;\n }\n if (typeof onMetaData.duration === 'number') { // duration\n if (!this._durationOverrided) {\n let duration = Math.floor(onMetaData.duration * this._timescale);\n this._duration = duration;\n this._mediaInfo.duration = duration;\n }\n } else {\n this._mediaInfo.duration = 0;\n }\n if (typeof onMetaData.framerate === 'number') { // framerate\n let fps_num = Math.floor(onMetaData.framerate * 1000);\n if (fps_num > 0) {\n let fps = fps_num / 1000;\n this._referenceFrameRate.fixed = true;\n this._referenceFrameRate.fps = fps;\n this._referenceFrameRate.fps_num = fps_num;\n this._referenceFrameRate.fps_den = 1000;\n this._mediaInfo.fps = fps;\n }\n }\n if (typeof onMetaData.keyframes === 'object') { // keyframes\n this._mediaInfo.hasKeyframesIndex = true;\n let keyframes = onMetaData.keyframes;\n this._mediaInfo.keyframesIndex = this._parseKeyframesIndex(keyframes);\n onMetaData.keyframes = null; // keyframes has been extracted, remove it\n } else {\n this._mediaInfo.hasKeyframesIndex = false;\n }\n this._dispatch = false;\n this._mediaInfo.metadata = onMetaData;\n Log.v(this.TAG, 'Parsed onMetaData');\n if (this._mediaInfo.isComplete()) {\n this._onMediaInfo(this._mediaInfo);\n }\n }\n }\n\n _parseKeyframesIndex(keyframes) {\n let times = [];\n let filepositions = [];\n\n // ignore first keyframe which is actually AVC Sequence Header (AVCDecoderConfigurationRecord)\n for (let i = 1; i < keyframes.times.length; i++) {\n let time = this._timestampBase + Math.floor(keyframes.times[i] * 1000);\n times.push(time);\n filepositions.push(keyframes.filepositions[i]);\n }\n\n return {\n times: times,\n filepositions: filepositions\n };\n }\n\n _parseAudioData(arrayBuffer, dataOffset, dataSize, tagTimestamp) {\n if (dataSize <= 1) {\n Log.w(this.TAG, 'Flv: Invalid audio packet, missing SoundData payload!');\n return;\n }\n\n if (this._hasAudioFlagOverrided === true && this._hasAudio === false) {\n // If hasAudio: false indicated explicitly in MediaDataSource,\n // Ignore all the audio packets\n return;\n }\n\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let soundSpec = v.getUint8(0);\n\n let soundFormat = soundSpec >>> 4;\n if (soundFormat !== 2 && soundFormat !== 10) { // MP3 or AAC\n this._onError(DemuxErrors.CODEC_UNSUPPORTED, 'Flv: Unsupported audio codec idx: ' + soundFormat);\n return;\n }\n\n let soundRate = 0;\n let soundRateIndex = (soundSpec & 12) >>> 2;\n if (soundRateIndex >= 0 && soundRateIndex <= 4) {\n soundRate = this._flvSoundRateTable[soundRateIndex];\n } else {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid audio sample rate idx: ' + soundRateIndex);\n return;\n }\n\n let soundSize = (soundSpec & 2) >>> 1; // unused\n let soundType = (soundSpec & 1);\n\n\n let meta = this._audioMetadata;\n let track = this._audioTrack;\n\n if (!meta) {\n if (this._hasAudio === false && this._hasAudioFlagOverrided === false) {\n this._hasAudio = true;\n this._mediaInfo.hasAudio = true;\n }\n\n // initial metadata\n meta = this._audioMetadata = {};\n meta.type = 'audio';\n meta.id = track.id;\n meta.timescale = this._timescale;\n meta.duration = this._duration;\n meta.audioSampleRate = soundRate;\n meta.channelCount = (soundType === 0 ? 1 : 2);\n }\n\n if (soundFormat === 10) { // AAC\n let aacData = this._parseAACAudioData(arrayBuffer, dataOffset + 1, dataSize - 1);\n if (aacData == undefined) {\n return;\n }\n\n if (aacData.packetType === 0) { // AAC sequence header (AudioSpecificConfig)\n if (meta.config) {\n Log.w(this.TAG, 'Found another AudioSpecificConfig!');\n }\n let misc = aacData.data;\n meta.audioSampleRate = misc.samplingRate;\n meta.channelCount = misc.channelCount;\n meta.codec = misc.codec;\n meta.originalCodec = misc.originalCodec;\n meta.config = misc.config;\n // The decode result of an aac sample is 1024 PCM samples\n meta.refSampleDuration = 1024 / meta.audioSampleRate * meta.timescale;\n Log.v(this.TAG, 'Parsed AudioSpecificConfig');\n\n if (this._isInitialMetadataDispatched()) {\n // Non-initial metadata, force dispatch (or flush) parsed frames to remuxer\n if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {\n this._onDataAvailable(this._audioTrack, this._videoTrack);\n }\n } else {\n this._audioInitialMetadataDispatched = true;\n }\n // then notify new metadata\n this._dispatch = false;\n this._onTrackMetadata('audio', meta);\n\n let mi = this._mediaInfo;\n mi.audioCodec = meta.originalCodec;\n mi.audioSampleRate = meta.audioSampleRate;\n mi.audioChannelCount = meta.channelCount;\n if (mi.hasVideo) {\n if (mi.videoCodec != null) {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + ',' + mi.audioCodec + '\"';\n }\n } else {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.audioCodec + '\"';\n }\n if (mi.isComplete()) {\n this._onMediaInfo(mi);\n }\n } else if (aacData.packetType === 1) { // AAC raw frame data\n let dts = this._timestampBase + tagTimestamp;\n let aacSample = {unit: aacData.data, dts: dts, pts: dts};\n track.samples.push(aacSample);\n track.length += aacData.data.length;\n } else {\n Log.e(this.TAG, `Flv: Unsupported AAC data type ${aacData.packetType}`);\n }\n } else if (soundFormat === 2) { // MP3\n if (!meta.codec) {\n // We need metadata for mp3 audio track, extract info from frame header\n let misc = this._parseMP3AudioData(arrayBuffer, dataOffset + 1, dataSize - 1, true);\n if (misc == undefined) {\n return;\n }\n meta.audioSampleRate = misc.samplingRate;\n meta.channelCount = misc.channelCount;\n meta.codec = misc.codec;\n meta.originalCodec = misc.originalCodec;\n // The decode result of an mp3 sample is 1152 PCM samples\n meta.refSampleDuration = 1152 / meta.audioSampleRate * meta.timescale;\n Log.v(this.TAG, 'Parsed MPEG Audio Frame Header');\n\n this._audioInitialMetadataDispatched = true;\n this._onTrackMetadata('audio', meta);\n\n let mi = this._mediaInfo;\n mi.audioCodec = meta.codec;\n mi.audioSampleRate = meta.audioSampleRate;\n mi.audioChannelCount = meta.channelCount;\n mi.audioDataRate = misc.bitRate;\n if (mi.hasVideo) {\n if (mi.videoCodec != null) {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + ',' + mi.audioCodec + '\"';\n }\n } else {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.audioCodec + '\"';\n }\n if (mi.isComplete()) {\n this._onMediaInfo(mi);\n }\n }\n\n // This packet is always a valid audio packet, extract it\n let data = this._parseMP3AudioData(arrayBuffer, dataOffset + 1, dataSize - 1, false);\n if (data == undefined) {\n return;\n }\n let dts = this._timestampBase + tagTimestamp;\n let mp3Sample = {unit: data, dts: dts, pts: dts};\n track.samples.push(mp3Sample);\n track.length += data.length;\n }\n }\n\n _parseAACAudioData(arrayBuffer, dataOffset, dataSize) {\n if (dataSize <= 1) {\n Log.w(this.TAG, 'Flv: Invalid AAC packet, missing AACPacketType or/and Data!');\n return;\n }\n\n let result = {};\n let array = new Uint8Array(arrayBuffer, dataOffset, dataSize);\n\n result.packetType = array[0];\n\n if (array[0] === 0) {\n result.data = this._parseAACAudioSpecificConfig(arrayBuffer, dataOffset + 1, dataSize - 1);\n } else {\n result.data = array.subarray(1);\n }\n\n return result;\n }\n\n _parseAACAudioSpecificConfig(arrayBuffer, dataOffset, dataSize) {\n let array = new Uint8Array(arrayBuffer, dataOffset, dataSize);\n let config = null;\n\n /* Audio Object Type:\n 0: Null\n 1: AAC Main\n 2: AAC LC\n 3: AAC SSR (Scalable Sample Rate)\n 4: AAC LTP (Long Term Prediction)\n 5: HE-AAC / SBR (Spectral Band Replication)\n 6: AAC Scalable\n */\n\n let audioObjectType = 0;\n let originalAudioObjectType = 0;\n let audioExtensionObjectType = null;\n let samplingIndex = 0;\n let extensionSamplingIndex = null;\n\n // 5 bits\n audioObjectType = originalAudioObjectType = array[0] >>> 3;\n // 4 bits\n samplingIndex = ((array[0] & 0x07) << 1) | (array[1] >>> 7);\n if (samplingIndex < 0 || samplingIndex >= this._mpegSamplingRates.length) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: AAC invalid sampling frequency index!');\n return;\n }\n\n let samplingFrequence = this._mpegSamplingRates[samplingIndex];\n\n // 4 bits\n let channelConfig = (array[1] & 0x78) >>> 3;\n if (channelConfig < 0 || channelConfig >= 8) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: AAC invalid channel configuration');\n return;\n }\n\n if (audioObjectType === 5) { // HE-AAC?\n // 4 bits\n extensionSamplingIndex = ((array[1] & 0x07) << 1) | (array[2] >>> 7);\n // 5 bits\n audioExtensionObjectType = (array[2] & 0x7C) >>> 2;\n }\n\n // workarounds for various browsers\n let userAgent = self.navigator.userAgent.toLowerCase();\n\n if (userAgent.indexOf('firefox') !== -1) {\n // firefox: use SBR (HE-AAC) if freq less than 24kHz\n if (samplingIndex >= 6) {\n audioObjectType = 5;\n config = new Array(4);\n extensionSamplingIndex = samplingIndex - 3;\n } else { // use LC-AAC\n audioObjectType = 2;\n config = new Array(2);\n extensionSamplingIndex = samplingIndex;\n }\n } else if (userAgent.indexOf('android') !== -1) {\n // android: always use LC-AAC\n audioObjectType = 2;\n config = new Array(2);\n extensionSamplingIndex = samplingIndex;\n } else {\n // for other browsers, e.g. chrome...\n // Always use HE-AAC to make it easier to switch aac codec profile\n audioObjectType = 5;\n extensionSamplingIndex = samplingIndex;\n config = new Array(4);\n\n if (samplingIndex >= 6) {\n extensionSamplingIndex = samplingIndex - 3;\n } else if (channelConfig === 1) { // Mono channel\n audioObjectType = 2;\n config = new Array(2);\n extensionSamplingIndex = samplingIndex;\n }\n }\n\n config[0] = audioObjectType << 3;\n config[0] |= (samplingIndex & 0x0F) >>> 1;\n config[1] = (samplingIndex & 0x0F) << 7;\n config[1] |= (channelConfig & 0x0F) << 3;\n if (audioObjectType === 5) {\n config[1] |= ((extensionSamplingIndex & 0x0F) >>> 1);\n config[2] = (extensionSamplingIndex & 0x01) << 7;\n // extended audio object type: force to 2 (LC-AAC)\n config[2] |= (2 << 2);\n config[3] = 0;\n }\n\n return {\n config: config,\n samplingRate: samplingFrequence,\n channelCount: channelConfig,\n codec: 'mp4a.40.' + audioObjectType,\n originalCodec: 'mp4a.40.' + originalAudioObjectType\n };\n }\n\n _parseMP3AudioData(arrayBuffer, dataOffset, dataSize, requestHeader) {\n if (dataSize < 4) {\n Log.w(this.TAG, 'Flv: Invalid MP3 packet, header missing!');\n return;\n }\n\n let le = this._littleEndian;\n let array = new Uint8Array(arrayBuffer, dataOffset, dataSize);\n let result = null;\n\n if (requestHeader) {\n if (array[0] !== 0xFF) {\n return;\n }\n let ver = (array[1] >>> 3) & 0x03;\n let layer = (array[1] & 0x06) >> 1;\n\n let bitrate_index = (array[2] & 0xF0) >>> 4;\n let sampling_freq_index = (array[2] & 0x0C) >>> 2;\n\n let channel_mode = (array[3] >>> 6) & 0x03;\n let channel_count = channel_mode !== 3 ? 2 : 1;\n\n let sample_rate = 0;\n let bit_rate = 0;\n let object_type = 34; // Layer-3, listed in MPEG-4 Audio Object Types\n\n let codec = 'mp3';\n\n switch (ver) {\n case 0: // MPEG 2.5\n sample_rate = this._mpegAudioV25SampleRateTable[sampling_freq_index];\n break;\n case 2: // MPEG 2\n sample_rate = this._mpegAudioV20SampleRateTable[sampling_freq_index];\n break;\n case 3: // MPEG 1\n sample_rate = this._mpegAudioV10SampleRateTable[sampling_freq_index];\n break;\n }\n\n switch (layer) {\n case 1: // Layer 3\n object_type = 34;\n if (bitrate_index < this._mpegAudioL3BitRateTable.length) {\n bit_rate = this._mpegAudioL3BitRateTable[bitrate_index];\n }\n break;\n case 2: // Layer 2\n object_type = 33;\n if (bitrate_index < this._mpegAudioL2BitRateTable.length) {\n bit_rate = this._mpegAudioL2BitRateTable[bitrate_index];\n }\n break;\n case 3: // Layer 1\n object_type = 32;\n if (bitrate_index < this._mpegAudioL1BitRateTable.length) {\n bit_rate = this._mpegAudioL1BitRateTable[bitrate_index];\n }\n break;\n }\n\n result = {\n bitRate: bit_rate,\n samplingRate: sample_rate,\n channelCount: channel_count,\n codec: codec,\n originalCodec: codec\n };\n } else {\n result = array;\n }\n\n return result;\n }\n\n _parseVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition) {\n if (dataSize <= 1) {\n Log.w(this.TAG, 'Flv: Invalid video packet, missing VideoData payload!');\n return;\n }\n\n if (this._hasVideoFlagOverrided === true && this._hasVideo === false) {\n // If hasVideo: false indicated explicitly in MediaDataSource,\n // Ignore all the video packets\n return;\n }\n\n let spec = (new Uint8Array(arrayBuffer, dataOffset, dataSize))[0];\n\n let frameType = (spec & 240) >>> 4;\n let codecId = spec & 15;\n\n if (codecId !== 7) {\n this._onError(DemuxErrors.CODEC_UNSUPPORTED, `Flv: Unsupported codec in video frame: ${codecId}`);\n return;\n }\n\n this._parseAVCVideoPacket(arrayBuffer, dataOffset + 1, dataSize - 1, tagTimestamp, tagPosition, frameType);\n }\n\n _parseAVCVideoPacket(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType) {\n if (dataSize < 4) {\n Log.w(this.TAG, 'Flv: Invalid AVC packet, missing AVCPacketType or/and CompositionTime');\n return;\n }\n\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let packetType = v.getUint8(0);\n let cts = v.getUint32(0, !le) & 0x00FFFFFF;\n\n if (packetType === 0) { // AVCDecoderConfigurationRecord\n this._parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset + 4, dataSize - 4);\n } else if (packetType === 1) { // One or more Nalus\n this._parseAVCVideoData(arrayBuffer, dataOffset + 4, dataSize - 4, tagTimestamp, tagPosition, frameType, cts);\n } else if (packetType === 2) {\n // empty, AVC end of sequence\n } else {\n this._onError(DemuxErrors.FORMAT_ERROR, `Flv: Invalid video packet type ${packetType}`);\n return;\n }\n }\n\n _parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 7) {\n Log.w(this.TAG, 'Flv: Invalid AVCDecoderConfigurationRecord, lack of data!');\n return;\n }\n\n let meta = this._videoMetadata;\n let track = this._videoTrack;\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n if (!meta) {\n if (this._hasVideo === false && this._hasVideoFlagOverrided === false) {\n this._hasVideo = true;\n this._mediaInfo.hasVideo = true;\n }\n\n meta = this._videoMetadata = {};\n meta.type = 'video';\n meta.id = track.id;\n meta.timescale = this._timescale;\n meta.duration = this._duration;\n } else {\n if (typeof meta.avcc !== 'undefined') {\n Log.w(this.TAG, 'Found another AVCDecoderConfigurationRecord!');\n }\n }\n\n let version = v.getUint8(0); // configurationVersion\n let avcProfile = v.getUint8(1); // avcProfileIndication\n let profileCompatibility = v.getUint8(2); // profile_compatibility\n let avcLevel = v.getUint8(3); // AVCLevelIndication\n\n if (version !== 1 || avcProfile === 0) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord');\n return;\n }\n\n this._naluLengthSize = (v.getUint8(4) & 3) + 1; // lengthSizeMinusOne\n if (this._naluLengthSize !== 3 && this._naluLengthSize !== 4) { // holy shit!!!\n this._onError(DemuxErrors.FORMAT_ERROR, `Flv: Strange NaluLengthSizeMinusOne: ${this._naluLengthSize - 1}`);\n return;\n }\n\n let spsCount = v.getUint8(5) & 31; // numOfSequenceParameterSets\n if (spsCount === 0) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord: No SPS');\n return;\n } else if (spsCount > 1) {\n Log.w(this.TAG, `Flv: Strange AVCDecoderConfigurationRecord: SPS Count = ${spsCount}`);\n }\n\n let offset = 6;\n\n for (let i = 0; i < spsCount; i++) {\n let len = v.getUint16(offset, !le); // sequenceParameterSetLength\n offset += 2;\n\n if (len === 0) {\n continue;\n }\n\n // Notice: Nalu without startcode header (00 00 00 01)\n let sps = new Uint8Array(arrayBuffer, dataOffset + offset, len);\n offset += len;\n\n let config = SPSParser.parseSPS(sps);\n if (i !== 0) {\n // ignore other sps's config\n continue;\n }\n\n meta.codecWidth = config.codec_size.width;\n meta.codecHeight = config.codec_size.height;\n meta.presentWidth = config.present_size.width;\n meta.presentHeight = config.present_size.height;\n\n meta.profile = config.profile_string;\n meta.level = config.level_string;\n meta.bitDepth = config.bit_depth;\n meta.chromaFormat = config.chroma_format;\n meta.sarRatio = config.sar_ratio;\n meta.frameRate = config.frame_rate;\n\n if (config.frame_rate.fixed === false ||\n config.frame_rate.fps_num === 0 ||\n config.frame_rate.fps_den === 0) {\n meta.frameRate = this._referenceFrameRate;\n }\n\n let fps_den = meta.frameRate.fps_den;\n let fps_num = meta.frameRate.fps_num;\n meta.refSampleDuration = meta.timescale * (fps_den / fps_num);\n\n let codecArray = sps.subarray(1, 4);\n let codecString = 'avc1.';\n for (let j = 0; j < 3; j++) {\n let h = codecArray[j].toString(16);\n if (h.length < 2) {\n h = '0' + h;\n }\n codecString += h;\n }\n meta.codec = codecString;\n\n let mi = this._mediaInfo;\n mi.width = meta.codecWidth;\n mi.height = meta.codecHeight;\n mi.fps = meta.frameRate.fps;\n mi.profile = meta.profile;\n mi.level = meta.level;\n mi.chromaFormat = config.chroma_format_string;\n mi.sarNum = meta.sarRatio.width;\n mi.sarDen = meta.sarRatio.height;\n mi.videoCodec = codecString;\n\n if (mi.hasAudio) {\n if (mi.audioCodec != null) {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + ',' + mi.audioCodec + '\"';\n }\n } else {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + '\"';\n }\n if (mi.isComplete()) {\n this._onMediaInfo(mi);\n }\n }\n\n let ppsCount = v.getUint8(offset); // numOfPictureParameterSets\n if (ppsCount === 0) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord: No PPS');\n return;\n } else if (ppsCount > 1) {\n Log.w(this.TAG, `Flv: Strange AVCDecoderConfigurationRecord: PPS Count = ${ppsCount}`);\n }\n\n offset++;\n\n for (let i = 0; i < ppsCount; i++) {\n let len = v.getUint16(offset, !le); // pictureParameterSetLength\n offset += 2;\n\n if (len === 0) {\n continue;\n }\n\n // pps is useless for extracting video information\n offset += len;\n }\n\n meta.avcc = new Uint8Array(dataSize);\n meta.avcc.set(new Uint8Array(arrayBuffer, dataOffset, dataSize), 0);\n Log.v(this.TAG, 'Parsed AVCDecoderConfigurationRecord');\n\n if (this._isInitialMetadataDispatched()) {\n // flush parsed frames\n if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {\n this._onDataAvailable(this._audioTrack, this._videoTrack);\n }\n } else {\n this._videoInitialMetadataDispatched = true;\n }\n // notify new metadata\n this._dispatch = false;\n this._onTrackMetadata('video', meta);\n }\n\n _parseAVCVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType, cts) {\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let units = [], length = 0;\n\n let offset = 0;\n const lengthSize = this._naluLengthSize;\n let dts = this._timestampBase + tagTimestamp;\n let keyframe = (frameType === 1); // from FLV Frame Type constants\n\n while (offset < dataSize) {\n if (offset + 4 >= dataSize) {\n Log.w(this.TAG, `Malformed Nalu near timestamp ${dts}, offset = ${offset}, dataSize = ${dataSize}`);\n break; // data not enough for next Nalu\n }\n // Nalu with length-header (AVC1)\n let naluSize = v.getUint32(offset, !le); // Big-Endian read\n if (lengthSize === 3) {\n naluSize >>>= 8;\n }\n if (naluSize > dataSize - lengthSize) {\n Log.w(this.TAG, `Malformed Nalus near timestamp ${dts}, NaluSize > DataSize!`);\n return;\n }\n\n let unitType = v.getUint8(offset + lengthSize) & 0x1F;\n\n if (unitType === 5) { // IDR\n keyframe = true;\n }\n\n let data = new Uint8Array(arrayBuffer, dataOffset + offset, lengthSize + naluSize);\n let unit = {type: unitType, data: data};\n units.push(unit);\n length += data.byteLength;\n\n offset += lengthSize + naluSize;\n }\n\n if (units.length) {\n let track = this._videoTrack;\n let avcSample = {\n units: units,\n length: length,\n isKeyframe: keyframe,\n dts: dts,\n cts: cts,\n pts: (dts + cts)\n };\n if (keyframe) {\n avcSample.fileposition = tagPosition;\n }\n track.samples.push(avcSample);\n track.length += length;\n }\n }\n\n}\n\nexport default FLVDemuxer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport ExpGolomb from './exp-golomb.js';\n\nclass SPSParser {\n\n static _ebsp2rbsp(uint8array) {\n let src = uint8array;\n let src_length = src.byteLength;\n let dst = new Uint8Array(src_length);\n let dst_idx = 0;\n\n for (let i = 0; i < src_length; i++) {\n if (i >= 2) {\n // Unescape: Skip 0x03 after 00 00\n if (src[i] === 0x03 && src[i - 1] === 0x00 && src[i - 2] === 0x00) {\n continue;\n }\n }\n dst[dst_idx] = src[i];\n dst_idx++;\n }\n\n return new Uint8Array(dst.buffer, 0, dst_idx);\n }\n\n static parseSPS(uint8array) {\n let rbsp = SPSParser._ebsp2rbsp(uint8array);\n let gb = new ExpGolomb(rbsp);\n\n gb.readByte();\n let profile_idc = gb.readByte(); // profile_idc\n gb.readByte(); // constraint_set_flags[5] + reserved_zero[3]\n let level_idc = gb.readByte(); // level_idc\n gb.readUEG(); // seq_parameter_set_id\n\n let profile_string = SPSParser.getProfileString(profile_idc);\n let level_string = SPSParser.getLevelString(level_idc);\n let chroma_format_idc = 1;\n let chroma_format = 420;\n let chroma_format_table = [0, 420, 422, 444];\n let bit_depth = 8;\n\n if (profile_idc === 100 || profile_idc === 110 || profile_idc === 122 ||\n profile_idc === 244 || profile_idc === 44 || profile_idc === 83 ||\n profile_idc === 86 || profile_idc === 118 || profile_idc === 128 ||\n profile_idc === 138 || profile_idc === 144) {\n\n chroma_format_idc = gb.readUEG();\n if (chroma_format_idc === 3) {\n gb.readBits(1); // separate_colour_plane_flag\n }\n if (chroma_format_idc <= 3) {\n chroma_format = chroma_format_table[chroma_format_idc];\n }\n\n bit_depth = gb.readUEG() + 8; // bit_depth_luma_minus8\n gb.readUEG(); // bit_depth_chroma_minus8\n gb.readBits(1); // qpprime_y_zero_transform_bypass_flag\n if (gb.readBool()) { // seq_scaling_matrix_present_flag\n let scaling_list_count = (chroma_format_idc !== 3) ? 8 : 12;\n for (let i = 0; i < scaling_list_count; i++) {\n if (gb.readBool()) { // seq_scaling_list_present_flag\n if (i < 6) {\n SPSParser._skipScalingList(gb, 16);\n } else {\n SPSParser._skipScalingList(gb, 64);\n }\n }\n }\n }\n }\n gb.readUEG(); // log2_max_frame_num_minus4\n let pic_order_cnt_type = gb.readUEG();\n if (pic_order_cnt_type === 0) {\n gb.readUEG(); // log2_max_pic_order_cnt_lsb_minus_4\n } else if (pic_order_cnt_type === 1) {\n gb.readBits(1); // delta_pic_order_always_zero_flag\n gb.readSEG(); // offset_for_non_ref_pic\n gb.readSEG(); // offset_for_top_to_bottom_field\n let num_ref_frames_in_pic_order_cnt_cycle = gb.readUEG();\n for (let i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) {\n gb.readSEG(); // offset_for_ref_frame\n }\n }\n gb.readUEG(); // max_num_ref_frames\n gb.readBits(1); // gaps_in_frame_num_value_allowed_flag\n\n let pic_width_in_mbs_minus1 = gb.readUEG();\n let pic_height_in_map_units_minus1 = gb.readUEG();\n\n let frame_mbs_only_flag = gb.readBits(1);\n if (frame_mbs_only_flag === 0) {\n gb.readBits(1); // mb_adaptive_frame_field_flag\n }\n gb.readBits(1); // direct_8x8_inference_flag\n\n let frame_crop_left_offset = 0;\n let frame_crop_right_offset = 0;\n let frame_crop_top_offset = 0;\n let frame_crop_bottom_offset = 0;\n\n let frame_cropping_flag = gb.readBool();\n if (frame_cropping_flag) {\n frame_crop_left_offset = gb.readUEG();\n frame_crop_right_offset = gb.readUEG();\n frame_crop_top_offset = gb.readUEG();\n frame_crop_bottom_offset = gb.readUEG();\n }\n\n let sar_width = 1, sar_height = 1;\n let fps = 0, fps_fixed = true, fps_num = 0, fps_den = 0;\n\n let vui_parameters_present_flag = gb.readBool();\n if (vui_parameters_present_flag) {\n if (gb.readBool()) { // aspect_ratio_info_present_flag\n let aspect_ratio_idc = gb.readByte();\n let sar_w_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2];\n let sar_h_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1];\n\n if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {\n sar_width = sar_w_table[aspect_ratio_idc - 1];\n sar_height = sar_h_table[aspect_ratio_idc - 1];\n } else if (aspect_ratio_idc === 255) {\n sar_width = gb.readByte() << 8 | gb.readByte();\n sar_height = gb.readByte() << 8 | gb.readByte();\n }\n }\n\n if (gb.readBool()) { // overscan_info_present_flag\n gb.readBool(); // overscan_appropriate_flag\n }\n if (gb.readBool()) { // video_signal_type_present_flag\n gb.readBits(4); // video_format & video_full_range_flag\n if (gb.readBool()) { // colour_description_present_flag\n gb.readBits(24); // colour_primaries & transfer_characteristics & matrix_coefficients\n }\n }\n if (gb.readBool()) { // chroma_loc_info_present_flag\n gb.readUEG(); // chroma_sample_loc_type_top_field\n gb.readUEG(); // chroma_sample_loc_type_bottom_field\n }\n if (gb.readBool()) { // timing_info_present_flag\n let num_units_in_tick = gb.readBits(32);\n let time_scale = gb.readBits(32);\n fps_fixed = gb.readBool(); // fixed_frame_rate_flag\n\n fps_num = time_scale;\n fps_den = num_units_in_tick * 2;\n fps = fps_num / fps_den;\n }\n }\n\n let sarScale = 1;\n if (sar_width !== 1 || sar_height !== 1) {\n sarScale = sar_width / sar_height;\n }\n\n let crop_unit_x = 0, crop_unit_y = 0;\n if (chroma_format_idc === 0) {\n crop_unit_x = 1;\n crop_unit_y = 2 - frame_mbs_only_flag;\n } else {\n let sub_wc = (chroma_format_idc === 3) ? 1 : 2;\n let sub_hc = (chroma_format_idc === 1) ? 2 : 1;\n crop_unit_x = sub_wc;\n crop_unit_y = sub_hc * (2 - frame_mbs_only_flag);\n }\n\n let codec_width = (pic_width_in_mbs_minus1 + 1) * 16;\n let codec_height = (2 - frame_mbs_only_flag) * ((pic_height_in_map_units_minus1 + 1) * 16);\n\n codec_width -= (frame_crop_left_offset + frame_crop_right_offset) * crop_unit_x;\n codec_height -= (frame_crop_top_offset + frame_crop_bottom_offset) * crop_unit_y;\n\n let present_width = Math.ceil(codec_width * sarScale);\n\n gb.destroy();\n gb = null;\n\n return {\n profile_string: profile_string, // baseline, high, high10, ...\n level_string: level_string, // 3, 3.1, 4, 4.1, 5, 5.1, ...\n bit_depth: bit_depth, // 8bit, 10bit, ...\n chroma_format: chroma_format, // 4:2:0, 4:2:2, ...\n chroma_format_string: SPSParser.getChromaFormatString(chroma_format),\n\n frame_rate: {\n fixed: fps_fixed,\n fps: fps,\n fps_den: fps_den,\n fps_num: fps_num\n },\n\n sar_ratio: {\n width: sar_width,\n height: sar_height\n },\n\n codec_size: {\n width: codec_width,\n height: codec_height\n },\n\n present_size: {\n width: present_width,\n height: codec_height\n }\n };\n }\n\n static _skipScalingList(gb, count) {\n let last_scale = 8, next_scale = 8;\n let delta_scale = 0;\n for (let i = 0; i < count; i++) {\n if (next_scale !== 0) {\n delta_scale = gb.readSEG();\n next_scale = (last_scale + delta_scale + 256) % 256;\n }\n last_scale = (next_scale === 0) ? last_scale : next_scale;\n }\n }\n\n static getProfileString(profile_idc) {\n switch (profile_idc) {\n case 66:\n return 'Baseline';\n case 77:\n return 'Main';\n case 88:\n return 'Extended';\n case 100:\n return 'High';\n case 110:\n return 'High10';\n case 122:\n return 'High422';\n case 244:\n return 'High444';\n default:\n return 'Unknown';\n }\n }\n\n static getLevelString(level_idc) {\n return (level_idc / 10).toFixed(1);\n }\n\n static getChromaFormatString(chroma) {\n switch (chroma) {\n case 420:\n return '4:2:0';\n case 422:\n return '4:2:2';\n case 444:\n return '4:4:4';\n default:\n return 'Unknown';\n }\n }\n\n}\n\nexport default SPSParser;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Polyfill from './utils/polyfill.js';\nimport Features from './core/features.js';\nimport FlvPlayer from './player/flv-player.js';\nimport NativePlayer from './player/native-player.js';\nimport PlayerEvents from './player/player-events.js';\nimport {ErrorTypes, ErrorDetails} from './player/player-errors.js';\nimport LoggingControl from './utils/logging-control.js';\nimport {InvalidArgumentException} from './utils/exception.js';\n\n// here are all the interfaces\n\n// install polyfills\nPolyfill.install();\n\n\n// factory method\nfunction createPlayer(mediaDataSource, optionalConfig) {\n let mds = mediaDataSource;\n if (mds == null || typeof mds !== 'object') {\n throw new InvalidArgumentException('MediaDataSource must be an javascript object!');\n }\n\n if (!mds.hasOwnProperty('type')) {\n throw new InvalidArgumentException('MediaDataSource must has type field to indicate video file type!');\n }\n\n switch (mds.type) {\n case 'flv':\n return new FlvPlayer(mds, optionalConfig);\n default:\n return new NativePlayer(mds, optionalConfig);\n }\n}\n\n\n// feature detection\nfunction isSupported() {\n return Features.supportMSEH264Playback();\n}\n\nfunction getFeatureList() {\n return Features.getFeatureList();\n}\n\n\n// interfaces\nlet flvjs = {};\n\nflvjs.createPlayer = createPlayer;\nflvjs.isSupported = isSupported;\nflvjs.getFeatureList = getFeatureList;\n\nflvjs.Events = PlayerEvents;\nflvjs.ErrorTypes = ErrorTypes;\nflvjs.ErrorDetails = ErrorDetails;\n\nflvjs.FlvPlayer = FlvPlayer;\nflvjs.NativePlayer = NativePlayer;\nflvjs.LoggingControl = LoggingControl;\n\nObject.defineProperty(flvjs, 'version', {\n enumerable: true,\n get: function () {\n // replaced by browserify-versionify transform\n return '__VERSION__';\n }\n});\n\nexport default flvjs;","// entry/index file\n\n// make it compatible with browserify's umd wrapper\nmodule.exports = require('./flv.js').default;\n","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n/* fetch + stream IO loader. Currently working on chrome 43+.\n * fetch provides a better alternative http API to XMLHttpRequest\n *\n * fetch spec https://fetch.spec.whatwg.org/\n * stream spec https://streams.spec.whatwg.org/\n */\nclass FetchStreamLoader extends BaseLoader {\n\n static isSupported() {\n try {\n // fetch + stream is broken on Microsoft Edge. Disable before build 15048.\n // see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8196907/\n // Fixed in Jan 10, 2017. Build 15048+ removed from blacklist.\n let isWorkWellEdge = Browser.msedge && Browser.version.minor >= 15048;\n let browserNotBlacklisted = Browser.msedge ? isWorkWellEdge : true;\n return (self.fetch && self.ReadableStream && browserNotBlacklisted);\n } catch (e) {\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('fetch-stream-loader');\n this.TAG = 'FetchStreamLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = true;\n\n this._requestAbort = false;\n this._contentLength = null;\n this._receivedLength = 0;\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n super.destroy();\n }\n\n open(dataSource, range) {\n this._dataSource = dataSource;\n this._range = range;\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n\n let headers = new self.Headers();\n\n if (typeof seekConfig.headers === 'object') {\n let configHeaders = seekConfig.headers;\n for (let key in configHeaders) {\n if (configHeaders.hasOwnProperty(key)) {\n headers.append(key, configHeaders[key]);\n }\n }\n }\n\n let params = {\n method: 'GET',\n headers: headers,\n mode: 'cors',\n cache: 'default',\n // The default policy of Fetch API in the whatwg standard\n // Safari incorrectly indicates 'no-referrer' as default policy, fuck it\n referrerPolicy: 'no-referrer-when-downgrade'\n };\n\n // cors is enabled by default\n if (dataSource.cors === false) {\n // no-cors means 'disregard cors policy', which can only be used in ServiceWorker\n params.mode = 'same-origin';\n }\n\n // withCredentials is disabled by default\n if (dataSource.withCredentials) {\n params.credentials = 'include';\n }\n\n // referrerPolicy from config\n if (dataSource.referrerPolicy) {\n params.referrerPolicy = dataSource.referrerPolicy;\n }\n\n this._status = LoaderStatus.kConnecting;\n self.fetch(seekConfig.url, params).then((res) => {\n if (this._requestAbort) {\n this._requestAbort = false;\n this._status = LoaderStatus.kIdle;\n return;\n }\n if (res.ok && (res.status >= 200 && res.status <= 299)) {\n if (res.url !== seekConfig.url) {\n if (this._onURLRedirect) {\n let redirectedURL = this._seekHandler.removeURLParameters(res.url);\n this._onURLRedirect(redirectedURL);\n }\n }\n\n let lengthHeader = res.headers.get('Content-Length');\n if (lengthHeader != null) {\n this._contentLength = parseInt(lengthHeader);\n if (this._contentLength !== 0) {\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n }\n\n return this._pump.call(this, res.body.getReader());\n } else {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: res.status, msg: res.statusText});\n } else {\n throw new RuntimeException('FetchStreamLoader: Http code invalid, ' + res.status + ' ' + res.statusText);\n }\n }\n }).catch((e) => {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, {code: -1, msg: e.message});\n } else {\n throw e;\n }\n });\n }\n\n abort() {\n this._requestAbort = true;\n }\n\n _pump(reader) { // ReadableStreamReader\n return reader.read().then((result) => {\n if (result.done) {\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);\n }\n } else {\n if (this._requestAbort === true) {\n this._requestAbort = false;\n this._status = LoaderStatus.kComplete;\n return reader.cancel();\n }\n\n this._status = LoaderStatus.kBuffering;\n\n let chunk = result.value.buffer;\n let byteStart = this._range.from + this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n\n this._pump(reader);\n }\n }).catch((e) => {\n if (e.code === 11 && Browser.msedge) { // InvalidStateError on Microsoft Edge\n // Workaround: Edge may throw InvalidStateError after ReadableStreamReader.cancel() call\n // Ignore the unknown exception.\n // Related issue: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11265202/\n return;\n }\n\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if ((e.code === 19 || e.message === 'network error') && // NETWORK_ERR\n (this._contentLength === null ||\n (this._contentLength !== null && this._receivedLength < this._contentLength))) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: e.code, msg: 'Fetch stream meet Early-EOF'};\n } else {\n type = LoaderErrors.EXCEPTION;\n info = {code: e.code, msg: e.message};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n });\n }\n\n}\n\nexport default FetchStreamLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport SpeedSampler from './speed-sampler.js';\nimport {LoaderStatus, LoaderErrors} from './loader.js';\nimport FetchStreamLoader from './fetch-stream-loader.js';\nimport MozChunkedLoader from './xhr-moz-chunked-loader.js';\nimport MSStreamLoader from './xhr-msstream-loader.js';\nimport RangeLoader from './xhr-range-loader.js';\nimport WebSocketLoader from './websocket-loader.js';\nimport RangeSeekHandler from './range-seek-handler.js';\nimport ParamSeekHandler from './param-seek-handler.js';\nimport {RuntimeException, IllegalStateException, InvalidArgumentException} from '../utils/exception.js';\n\n/**\n * DataSource: {\n * url: string,\n * filesize: number,\n * cors: boolean,\n * withCredentials: boolean\n * }\n * \n */\n\n// Manage IO Loaders\nclass IOController {\n\n constructor(dataSource, config, extraData) {\n this.TAG = 'IOController';\n\n this._config = config;\n this._extraData = extraData;\n\n this._stashInitialSize = 1024 * 384; // default initial size: 384KB\n if (config.stashInitialSize != undefined && config.stashInitialSize > 0) {\n // apply from config\n this._stashInitialSize = config.stashInitialSize;\n }\n\n this._stashUsed = 0;\n this._stashSize = this._stashInitialSize;\n this._bufferSize = 1024 * 1024 * 3; // initial size: 3MB\n this._stashBuffer = new ArrayBuffer(this._bufferSize);\n this._stashByteStart = 0;\n this._enableStash = true;\n if (config.enableStashBuffer === false) {\n this._enableStash = false;\n }\n\n this._loader = null;\n this._loaderClass = null;\n this._seekHandler = null;\n\n this._dataSource = dataSource;\n this._isWebSocketURL = /wss?:\\/\\/(.+?)/.test(dataSource.url);\n this._refTotalLength = dataSource.filesize ? dataSource.filesize : null;\n this._totalLength = this._refTotalLength;\n this._fullRequestFlag = false;\n this._currentRange = null;\n this._redirectedURL = null;\n\n this._speedNormalized = 0;\n this._speedSampler = new SpeedSampler();\n this._speedNormalizeList = [64, 128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096];\n\n this._isEarlyEofReconnecting = false;\n\n this._paused = false;\n this._resumeFrom = 0;\n\n this._onDataArrival = null;\n this._onSeeked = null;\n this._onError = null;\n this._onComplete = null;\n this._onRedirect = null;\n this._onRecoveredEarlyEof = null;\n\n this._selectSeekHandler();\n this._selectLoader();\n this._createLoader();\n }\n\n destroy() {\n if (this._loader.isWorking()) {\n this._loader.abort();\n }\n this._loader.destroy();\n this._loader = null;\n this._loaderClass = null;\n this._dataSource = null;\n this._stashBuffer = null;\n this._stashUsed = this._stashSize = this._bufferSize = this._stashByteStart = 0;\n this._currentRange = null;\n this._speedSampler = null;\n\n this._isEarlyEofReconnecting = false;\n\n this._onDataArrival = null;\n this._onSeeked = null;\n this._onError = null;\n this._onComplete = null;\n this._onRedirect = null;\n this._onRecoveredEarlyEof = null;\n\n this._extraData = null;\n }\n\n isWorking() {\n return this._loader && this._loader.isWorking() && !this._paused;\n }\n\n isPaused() {\n return this._paused;\n }\n\n get status() {\n return this._loader.status;\n }\n\n get extraData() {\n return this._extraData;\n }\n\n set extraData(data) {\n this._extraData = data;\n }\n\n // prototype: function onDataArrival(chunks: ArrayBuffer, byteStart: number): number\n get onDataArrival() {\n return this._onDataArrival;\n }\n\n set onDataArrival(callback) {\n this._onDataArrival = callback;\n }\n\n get onSeeked() {\n return this._onSeeked;\n }\n\n set onSeeked(callback) {\n this._onSeeked = callback;\n }\n\n // prototype: function onError(type: number, info: {code: number, msg: string}): void\n get onError() {\n return this._onError;\n }\n\n set onError(callback) {\n this._onError = callback;\n }\n\n get onComplete() {\n return this._onComplete;\n }\n\n set onComplete(callback) {\n this._onComplete = callback;\n }\n\n get onRedirect() {\n return this._onRedirect;\n }\n\n set onRedirect(callback) {\n this._onRedirect = callback;\n }\n\n get onRecoveredEarlyEof() {\n return this._onRecoveredEarlyEof;\n }\n\n set onRecoveredEarlyEof(callback) {\n this._onRecoveredEarlyEof = callback;\n }\n\n get currentURL() {\n return this._dataSource.url;\n }\n\n get hasRedirect() {\n return (this._redirectedURL != null || this._dataSource.redirectedURL != undefined);\n }\n\n get currentRedirectedURL() {\n return this._redirectedURL || this._dataSource.redirectedURL;\n }\n\n // in KB/s\n get currentSpeed() {\n if (this._loaderClass === RangeLoader) {\n // SpeedSampler is inaccuracy if loader is RangeLoader\n return this._loader.currentSpeed;\n }\n return this._speedSampler.lastSecondKBps;\n }\n\n get loaderType() {\n return this._loader.type;\n }\n\n _selectSeekHandler() {\n let config = this._config;\n\n if (config.seekType === 'range') {\n this._seekHandler = new RangeSeekHandler(this._config.rangeLoadZeroStart);\n } else if (config.seekType === 'param') {\n let paramStart = config.seekParamStart || 'bstart';\n let paramEnd = config.seekParamEnd || 'bend';\n\n this._seekHandler = new ParamSeekHandler(paramStart, paramEnd);\n } else if (config.seekType === 'custom') {\n if (typeof config.customSeekHandler !== 'function') {\n throw new InvalidArgumentException('Custom seekType specified in config but invalid customSeekHandler!');\n }\n this._seekHandler = new config.customSeekHandler();\n } else {\n throw new InvalidArgumentException(`Invalid seekType in config: ${config.seekType}`);\n }\n }\n\n _selectLoader() {\n if (this._isWebSocketURL) {\n this._loaderClass = WebSocketLoader;\n } else if (FetchStreamLoader.isSupported()) {\n this._loaderClass = FetchStreamLoader;\n } else if (MozChunkedLoader.isSupported()) {\n this._loaderClass = MozChunkedLoader;\n } else if (RangeLoader.isSupported()) {\n this._loaderClass = RangeLoader;\n } else {\n throw new RuntimeException('Your browser doesn\\'t support xhr with arraybuffer responseType!');\n }\n }\n\n _createLoader() {\n this._loader = new this._loaderClass(this._seekHandler, this._config);\n if (this._loader.needStashBuffer === false) {\n this._enableStash = false;\n }\n this._loader.onContentLengthKnown = this._onContentLengthKnown.bind(this);\n this._loader.onURLRedirect = this._onURLRedirect.bind(this);\n this._loader.onDataArrival = this._onLoaderChunkArrival.bind(this);\n this._loader.onComplete = this._onLoaderComplete.bind(this);\n this._loader.onError = this._onLoaderError.bind(this);\n }\n\n open(optionalFrom) {\n this._currentRange = {from: 0, to: -1};\n if (optionalFrom) {\n this._currentRange.from = optionalFrom;\n }\n\n this._speedSampler.reset();\n if (!optionalFrom) {\n this._fullRequestFlag = true;\n }\n\n this._loader.open(this._dataSource, Object.assign({}, this._currentRange));\n }\n\n abort() {\n this._loader.abort();\n\n if (this._paused) {\n this._paused = false;\n this._resumeFrom = 0;\n }\n }\n\n pause() {\n if (this.isWorking()) {\n this._loader.abort();\n\n if (this._stashUsed !== 0) {\n this._resumeFrom = this._stashByteStart;\n this._currentRange.to = this._stashByteStart - 1;\n } else {\n this._resumeFrom = this._currentRange.to + 1;\n }\n this._stashUsed = 0;\n this._stashByteStart = 0;\n this._paused = true;\n }\n }\n\n resume() {\n if (this._paused) {\n this._paused = false;\n let bytes = this._resumeFrom;\n this._resumeFrom = 0;\n this._internalSeek(bytes, true);\n }\n }\n\n seek(bytes) {\n this._paused = false;\n this._stashUsed = 0;\n this._stashByteStart = 0;\n this._internalSeek(bytes, true);\n }\n\n /**\n * When seeking request is from media seeking, unconsumed stash data should be dropped\n * However, stash data shouldn't be dropped if seeking requested from http reconnection\n *\n * @dropUnconsumed: Ignore and discard all unconsumed data in stash buffer\n */\n _internalSeek(bytes, dropUnconsumed) {\n if (this._loader.isWorking()) {\n this._loader.abort();\n }\n\n // dispatch & flush stash buffer before seek\n this._flushStashBuffer(dropUnconsumed);\n\n this._loader.destroy();\n this._loader = null;\n\n let requestRange = {from: bytes, to: -1};\n this._currentRange = {from: requestRange.from, to: -1};\n\n this._speedSampler.reset();\n this._stashSize = this._stashInitialSize;\n this._createLoader();\n this._loader.open(this._dataSource, requestRange);\n\n if (this._onSeeked) {\n this._onSeeked();\n }\n }\n\n updateUrl(url) {\n if (!url || typeof url !== 'string' || url.length === 0) {\n throw new InvalidArgumentException('Url must be a non-empty string!');\n }\n\n this._dataSource.url = url;\n\n // TODO: replace with new url\n }\n\n _expandBuffer(expectedBytes) {\n let bufferNewSize = this._stashSize;\n while (bufferNewSize + 1024 * 1024 * 1 < expectedBytes) {\n bufferNewSize *= 2;\n }\n\n bufferNewSize += 1024 * 1024 * 1; // bufferSize = stashSize + 1MB\n if (bufferNewSize === this._bufferSize) {\n return;\n }\n\n let newBuffer = new ArrayBuffer(bufferNewSize);\n\n if (this._stashUsed > 0) { // copy existing data into new buffer\n let stashOldArray = new Uint8Array(this._stashBuffer, 0, this._stashUsed);\n let stashNewArray = new Uint8Array(newBuffer, 0, bufferNewSize);\n stashNewArray.set(stashOldArray, 0);\n }\n\n this._stashBuffer = newBuffer;\n this._bufferSize = bufferNewSize;\n }\n\n _normalizeSpeed(input) {\n let list = this._speedNormalizeList;\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (input < list[0]) {\n return list[0];\n }\n\n // binary search\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (input >= list[mid] && input < list[mid + 1])) {\n return list[mid];\n } else if (list[mid] < input) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n }\n\n _adjustStashSize(normalized) {\n let stashSizeKB = 0;\n\n if (this._config.isLive) {\n // live stream: always use single normalized speed for size of stashSizeKB\n stashSizeKB = normalized;\n } else {\n if (normalized < 512) {\n stashSizeKB = normalized;\n } else if (normalized >= 512 && normalized <= 1024) {\n stashSizeKB = Math.floor(normalized * 1.5);\n } else {\n stashSizeKB = normalized * 2;\n }\n }\n\n if (stashSizeKB > 8192) {\n stashSizeKB = 8192;\n }\n\n let bufferSize = stashSizeKB * 1024 + 1024 * 1024 * 1; // stashSize + 1MB\n if (this._bufferSize < bufferSize) {\n this._expandBuffer(bufferSize);\n }\n this._stashSize = stashSizeKB * 1024;\n }\n\n _dispatchChunks(chunks, byteStart) {\n this._currentRange.to = byteStart + chunks.byteLength - 1;\n return this._onDataArrival(chunks, byteStart);\n }\n\n _onURLRedirect(redirectedURL) {\n this._redirectedURL = redirectedURL;\n if (this._onRedirect) {\n this._onRedirect(redirectedURL);\n }\n }\n\n _onContentLengthKnown(contentLength) {\n if (contentLength && this._fullRequestFlag) {\n this._totalLength = contentLength;\n this._fullRequestFlag = false;\n }\n }\n\n _onLoaderChunkArrival(chunk, byteStart, receivedLength) {\n if (!this._onDataArrival) {\n throw new IllegalStateException('IOController: No existing consumer (onDataArrival) callback!');\n }\n if (this._paused) {\n return;\n }\n if (this._isEarlyEofReconnecting) {\n // Auto-reconnect for EarlyEof succeed, notify to upper-layer by callback\n this._isEarlyEofReconnecting = false;\n if (this._onRecoveredEarlyEof) {\n this._onRecoveredEarlyEof();\n }\n }\n\n this._speedSampler.addBytes(chunk.byteLength);\n\n // adjust stash buffer size according to network speed dynamically\n let KBps = this._speedSampler.lastSecondKBps;\n if (KBps !== 0) {\n let normalized = this._normalizeSpeed(KBps);\n if (this._speedNormalized !== normalized) {\n this._speedNormalized = normalized;\n this._adjustStashSize(normalized);\n }\n }\n\n if (!this._enableStash) { // disable stash\n if (this._stashUsed === 0) {\n // dispatch chunk directly to consumer;\n // check ret value (consumed bytes) and stash unconsumed to stashBuffer\n let consumed = this._dispatchChunks(chunk, byteStart);\n if (consumed < chunk.byteLength) { // unconsumed data remain.\n let remain = chunk.byteLength - consumed;\n if (remain > this._bufferSize) {\n this._expandBuffer(remain);\n }\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n stashArray.set(new Uint8Array(chunk, consumed), 0);\n this._stashUsed += remain;\n this._stashByteStart = byteStart + consumed;\n }\n } else {\n // else: Merge chunk into stashBuffer, and dispatch stashBuffer to consumer.\n if (this._stashUsed + chunk.byteLength > this._bufferSize) {\n this._expandBuffer(this._stashUsed + chunk.byteLength);\n }\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n stashArray.set(new Uint8Array(chunk), this._stashUsed);\n this._stashUsed += chunk.byteLength;\n let consumed = this._dispatchChunks(this._stashBuffer.slice(0, this._stashUsed), this._stashByteStart);\n if (consumed < this._stashUsed && consumed > 0) { // unconsumed data remain\n let remainArray = new Uint8Array(this._stashBuffer, consumed);\n stashArray.set(remainArray, 0);\n }\n this._stashUsed -= consumed;\n this._stashByteStart += consumed;\n }\n } else { // enable stash\n if (this._stashUsed === 0 && this._stashByteStart === 0) { // seeked? or init chunk?\n // This is the first chunk after seek action\n this._stashByteStart = byteStart;\n }\n if (this._stashUsed + chunk.byteLength <= this._stashSize) {\n // just stash\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._stashSize);\n stashArray.set(new Uint8Array(chunk), this._stashUsed);\n this._stashUsed += chunk.byteLength;\n } else { // stashUsed + chunkSize > stashSize, size limit exceeded\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n if (this._stashUsed > 0) { // There're stash datas in buffer\n // dispatch the whole stashBuffer, and stash remain data\n // then append chunk to stashBuffer (stash)\n let buffer = this._stashBuffer.slice(0, this._stashUsed);\n let consumed = this._dispatchChunks(buffer, this._stashByteStart);\n if (consumed < buffer.byteLength) {\n if (consumed > 0) {\n let remainArray = new Uint8Array(buffer, consumed);\n stashArray.set(remainArray, 0);\n this._stashUsed = remainArray.byteLength;\n this._stashByteStart += consumed;\n }\n } else {\n this._stashUsed = 0;\n this._stashByteStart += consumed;\n }\n if (this._stashUsed + chunk.byteLength > this._bufferSize) {\n this._expandBuffer(this._stashUsed + chunk.byteLength);\n stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n }\n stashArray.set(new Uint8Array(chunk), this._stashUsed);\n this._stashUsed += chunk.byteLength;\n } else { // stash buffer empty, but chunkSize > stashSize (oh, holy shit)\n // dispatch chunk directly and stash remain data\n let consumed = this._dispatchChunks(chunk, byteStart);\n if (consumed < chunk.byteLength) {\n let remain = chunk.byteLength - consumed;\n if (remain > this._bufferSize) {\n this._expandBuffer(remain);\n stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n }\n stashArray.set(new Uint8Array(chunk, consumed), 0);\n this._stashUsed += remain;\n this._stashByteStart = byteStart + consumed;\n }\n }\n }\n }\n }\n\n _flushStashBuffer(dropUnconsumed) {\n if (this._stashUsed > 0) {\n let buffer = this._stashBuffer.slice(0, this._stashUsed);\n let consumed = this._dispatchChunks(buffer, this._stashByteStart);\n let remain = buffer.byteLength - consumed;\n\n if (consumed < buffer.byteLength) {\n if (dropUnconsumed) {\n Log.w(this.TAG, `${remain} bytes unconsumed data remain when flush buffer, dropped`);\n } else {\n if (consumed > 0) {\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n let remainArray = new Uint8Array(buffer, consumed);\n stashArray.set(remainArray, 0);\n this._stashUsed = remainArray.byteLength;\n this._stashByteStart += consumed;\n }\n return 0;\n }\n }\n this._stashUsed = 0;\n this._stashByteStart = 0;\n return remain;\n }\n return 0;\n }\n\n _onLoaderComplete(from, to) {\n // Force-flush stash buffer, and drop unconsumed data\n this._flushStashBuffer(true);\n\n if (this._onComplete) {\n this._onComplete(this._extraData);\n }\n }\n\n _onLoaderError(type, data) {\n Log.e(this.TAG, `Loader error, code = ${data.code}, msg = ${data.msg}`);\n\n this._flushStashBuffer(false);\n\n if (this._isEarlyEofReconnecting) {\n // Auto-reconnect for EarlyEof failed, throw UnrecoverableEarlyEof error to upper-layer\n this._isEarlyEofReconnecting = false;\n type = LoaderErrors.UNRECOVERABLE_EARLY_EOF;\n }\n\n switch (type) {\n case LoaderErrors.EARLY_EOF: {\n if (!this._config.isLive) {\n // Do internal http reconnect if not live stream\n if (this._totalLength) {\n let nextFrom = this._currentRange.to + 1;\n if (nextFrom < this._totalLength) {\n Log.w(this.TAG, 'Connection lost, trying reconnect...');\n this._isEarlyEofReconnecting = true;\n this._internalSeek(nextFrom, false);\n }\n return;\n }\n // else: We don't know totalLength, throw UnrecoverableEarlyEof\n }\n // live stream: throw UnrecoverableEarlyEof error to upper-layer\n type = LoaderErrors.UNRECOVERABLE_EARLY_EOF;\n break;\n }\n case LoaderErrors.UNRECOVERABLE_EARLY_EOF:\n case LoaderErrors.CONNECTING_TIMEOUT:\n case LoaderErrors.HTTP_STATUS_CODE_INVALID:\n case LoaderErrors.EXCEPTION:\n break;\n }\n\n if (this._onError) {\n this._onError(type, data);\n } else {\n throw new RuntimeException('IOException: ' + data.msg);\n }\n }\n\n}\n\nexport default IOController;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {NotImplementedException} from '../utils/exception.js';\n\nexport const LoaderStatus = {\n kIdle: 0,\n kConnecting: 1,\n kBuffering: 2,\n kError: 3,\n kComplete: 4\n};\n\nexport const LoaderErrors = {\n OK: 'OK',\n EXCEPTION: 'Exception',\n HTTP_STATUS_CODE_INVALID: 'HttpStatusCodeInvalid',\n CONNECTING_TIMEOUT: 'ConnectingTimeout',\n EARLY_EOF: 'EarlyEof',\n UNRECOVERABLE_EARLY_EOF: 'UnrecoverableEarlyEof'\n};\n\n/* Loader has callbacks which have following prototypes:\n * function onContentLengthKnown(contentLength: number): void\n * function onURLRedirect(url: string): void\n * function onDataArrival(chunk: ArrayBuffer, byteStart: number, receivedLength: number): void\n * function onError(errorType: number, errorInfo: {code: number, msg: string}): void\n * function onComplete(rangeFrom: number, rangeTo: number): void\n */\nexport class BaseLoader {\n\n constructor(typeName) {\n this._type = typeName || 'undefined';\n this._status = LoaderStatus.kIdle;\n this._needStash = false;\n // callbacks\n this._onContentLengthKnown = null;\n this._onURLRedirect = null;\n this._onDataArrival = null;\n this._onError = null;\n this._onComplete = null;\n }\n\n destroy() {\n this._status = LoaderStatus.kIdle;\n this._onContentLengthKnown = null;\n this._onURLRedirect = null;\n this._onDataArrival = null;\n this._onError = null;\n this._onComplete = null;\n }\n\n isWorking() {\n return this._status === LoaderStatus.kConnecting || this._status === LoaderStatus.kBuffering;\n }\n\n get type() {\n return this._type;\n }\n\n get status() {\n return this._status;\n }\n\n get needStashBuffer() {\n return this._needStash;\n }\n\n get onContentLengthKnown() {\n return this._onContentLengthKnown;\n }\n\n set onContentLengthKnown(callback) {\n this._onContentLengthKnown = callback;\n }\n\n get onURLRedirect() {\n return this._onURLRedirect;\n }\n\n set onURLRedirect(callback) {\n this._onURLRedirect = callback;\n }\n\n get onDataArrival() {\n return this._onDataArrival;\n }\n\n set onDataArrival(callback) {\n this._onDataArrival = callback;\n }\n\n get onError() {\n return this._onError;\n }\n\n set onError(callback) {\n this._onError = callback;\n }\n\n get onComplete() {\n return this._onComplete;\n }\n\n set onComplete(callback) {\n this._onComplete = callback;\n }\n\n // pure virtual\n open(dataSource, range) {\n throw new NotImplementedException('Unimplemented abstract function!');\n }\n\n abort() {\n throw new NotImplementedException('Unimplemented abstract function!');\n }\n\n\n}","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass ParamSeekHandler {\n\n constructor(paramStart, paramEnd) {\n this._startName = paramStart;\n this._endName = paramEnd;\n }\n\n getConfig(baseUrl, range) {\n let url = baseUrl;\n\n if (range.from !== 0 || range.to !== -1) {\n let needAnd = true;\n if (url.indexOf('?') === -1) {\n url += '?';\n needAnd = false;\n }\n\n if (needAnd) {\n url += '&';\n }\n\n url += `${this._startName}=${range.from.toString()}`;\n\n if (range.to !== -1) {\n url += `&${this._endName}=${range.to.toString()}`;\n }\n }\n\n return {\n url: url,\n headers: {}\n };\n }\n\n removeURLParameters(seekedURL) {\n let baseURL = seekedURL.split('?')[0];\n let params = undefined;\n\n let queryIndex = seekedURL.indexOf('?');\n if (queryIndex !== -1) {\n params = seekedURL.substring(queryIndex + 1);\n }\n\n let resultParams = '';\n\n if (params != undefined && params.length > 0) {\n let pairs = params.split('&');\n\n for (let i = 0; i < pairs.length; i++) {\n let pair = pairs[i].split('=');\n let requireAnd = (i > 0);\n\n if (pair[0] !== this._startName && pair[0] !== this._endName) {\n if (requireAnd) {\n resultParams += '&';\n }\n resultParams += pairs[i];\n }\n }\n }\n\n return (resultParams.length === 0) ? baseURL : baseURL + '?' + resultParams;\n }\n\n}\n\nexport default ParamSeekHandler;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass RangeSeekHandler {\n\n constructor(zeroStart) {\n this._zeroStart = zeroStart || false;\n }\n\n getConfig(url, range) {\n let headers = {};\n\n if (range.from !== 0 || range.to !== -1) {\n let param;\n if (range.to !== -1) {\n param = `bytes=${range.from.toString()}-${range.to.toString()}`;\n } else {\n param = `bytes=${range.from.toString()}-`;\n }\n headers['Range'] = param;\n } else if (this._zeroStart) {\n headers['Range'] = 'bytes=0-';\n }\n\n return {\n url: url,\n headers: headers\n };\n }\n\n removeURLParameters(seekedURL) {\n return seekedURL;\n }\n\n}\n\nexport default RangeSeekHandler;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Utility class to calculate realtime network I/O speed\nclass SpeedSampler {\n\n constructor() {\n // milliseconds\n this._firstCheckpoint = 0;\n this._lastCheckpoint = 0;\n this._intervalBytes = 0;\n this._totalBytes = 0;\n this._lastSecondBytes = 0;\n\n // compatibility detection\n if (self.performance && self.performance.now) {\n this._now = self.performance.now.bind(self.performance);\n } else {\n this._now = Date.now;\n }\n }\n\n reset() {\n this._firstCheckpoint = this._lastCheckpoint = 0;\n this._totalBytes = this._intervalBytes = 0;\n this._lastSecondBytes = 0;\n }\n\n addBytes(bytes) {\n if (this._firstCheckpoint === 0) {\n this._firstCheckpoint = this._now();\n this._lastCheckpoint = this._firstCheckpoint;\n this._intervalBytes += bytes;\n this._totalBytes += bytes;\n } else if (this._now() - this._lastCheckpoint < 1000) {\n this._intervalBytes += bytes;\n this._totalBytes += bytes;\n } else { // duration >= 1000\n this._lastSecondBytes = this._intervalBytes;\n this._intervalBytes = bytes;\n this._totalBytes += bytes;\n this._lastCheckpoint = this._now();\n }\n }\n\n get currentKBps() {\n this.addBytes(0);\n\n let durationSeconds = (this._now() - this._lastCheckpoint) / 1000;\n if (durationSeconds == 0) durationSeconds = 1;\n return (this._intervalBytes / durationSeconds) / 1024;\n }\n\n get lastSecondKBps() {\n this.addBytes(0);\n\n if (this._lastSecondBytes !== 0) {\n return this._lastSecondBytes / 1024;\n } else { // lastSecondBytes === 0\n if (this._now() - this._lastCheckpoint >= 500) {\n // if time interval since last checkpoint has exceeded 500ms\n // the speed is nearly accurate\n return this.currentKBps;\n } else {\n // We don't know\n return 0;\n }\n }\n }\n\n get averageKBps() {\n let durationSeconds = (this._now() - this._firstCheckpoint) / 1000;\n return (this._totalBytes / durationSeconds) / 1024;\n }\n\n}\n\nexport default SpeedSampler;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n// For FLV over WebSocket live stream\nclass WebSocketLoader extends BaseLoader {\n\n static isSupported() {\n try {\n return (typeof self.WebSocket !== 'undefined');\n } catch (e) {\n return false;\n }\n }\n\n constructor() {\n super('websocket-loader');\n this.TAG = 'WebSocketLoader';\n\n this._needStash = true;\n\n this._ws = null;\n this._requestAbort = false;\n this._receivedLength = 0;\n }\n\n destroy() {\n if (this._ws) {\n this.abort();\n }\n super.destroy();\n }\n\n open(dataSource) {\n try {\n let ws = this._ws = new self.WebSocket(dataSource.url);\n ws.binaryType = 'arraybuffer';\n ws.onopen = this._onWebSocketOpen.bind(this);\n ws.onclose = this._onWebSocketClose.bind(this);\n ws.onmessage = this._onWebSocketMessage.bind(this);\n ws.onerror = this._onWebSocketError.bind(this);\n\n this._status = LoaderStatus.kConnecting;\n } catch (e) {\n this._status = LoaderStatus.kError;\n\n let info = {code: e.code, msg: e.message};\n\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n }\n\n abort() {\n let ws = this._ws;\n if (ws && (ws.readyState === 0 || ws.readyState === 1)) { // CONNECTING || OPEN\n this._requestAbort = true;\n ws.close();\n }\n\n this._ws = null;\n this._status = LoaderStatus.kComplete;\n }\n\n _onWebSocketOpen(e) {\n this._status = LoaderStatus.kBuffering;\n }\n\n _onWebSocketClose(e) {\n if (this._requestAbort === true) {\n this._requestAbort = false;\n return;\n }\n\n this._status = LoaderStatus.kComplete;\n\n if (this._onComplete) {\n this._onComplete(0, this._receivedLength - 1);\n }\n }\n\n _onWebSocketMessage(e) {\n if (e.data instanceof ArrayBuffer) {\n this._dispatchArrayBuffer(e.data);\n } else if (e.data instanceof Blob) {\n let reader = new FileReader();\n reader.onload = () => {\n this._dispatchArrayBuffer(reader.result);\n };\n reader.readAsArrayBuffer(e.data);\n } else {\n this._status = LoaderStatus.kError;\n let info = {code: -1, msg: 'Unsupported WebSocket message type: ' + e.data.constructor.name};\n\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n }\n\n _dispatchArrayBuffer(arraybuffer) {\n let chunk = arraybuffer;\n let byteStart = this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n }\n\n _onWebSocketError(e) {\n this._status = LoaderStatus.kError;\n\n let info = {\n code: e.code,\n msg: e.message\n };\n\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n}\n\nexport default WebSocketLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n// For FireFox browser which supports `xhr.responseType = 'moz-chunked-arraybuffer'`\nclass MozChunkedLoader extends BaseLoader {\n\n static isSupported() {\n try {\n let xhr = new XMLHttpRequest();\n // Firefox 37- requires .open() to be called before setting responseType\n xhr.open('GET', 'https://example.com', true);\n xhr.responseType = 'moz-chunked-arraybuffer';\n return (xhr.responseType === 'moz-chunked-arraybuffer');\n } catch (e) {\n Log.w('MozChunkedLoader', e.message);\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('xhr-moz-chunked-loader');\n this.TAG = 'MozChunkedLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = true;\n\n this._xhr = null;\n this._requestAbort = false;\n this._contentLength = null;\n this._receivedLength = 0;\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr.onprogress = null;\n this._xhr.onloadend = null;\n this._xhr.onerror = null;\n this._xhr = null;\n }\n super.destroy();\n }\n\n open(dataSource, range) {\n this._dataSource = dataSource;\n this._range = range;\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n this._requestURL = seekConfig.url;\n\n let xhr = this._xhr = new XMLHttpRequest();\n xhr.open('GET', seekConfig.url, true);\n xhr.responseType = 'moz-chunked-arraybuffer';\n xhr.onreadystatechange = this._onReadyStateChange.bind(this);\n xhr.onprogress = this._onProgress.bind(this);\n xhr.onloadend = this._onLoadEnd.bind(this);\n xhr.onerror = this._onXhrError.bind(this);\n\n // cors is auto detected and enabled by xhr\n\n // withCredentials is disabled by default\n if (dataSource.withCredentials && xhr['withCredentials']) {\n xhr.withCredentials = true;\n }\n\n if (typeof seekConfig.headers === 'object') {\n let headers = seekConfig.headers;\n\n for (let key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n }\n\n this._status = LoaderStatus.kConnecting;\n xhr.send();\n }\n\n abort() {\n this._requestAbort = true;\n if (this._xhr) {\n this._xhr.abort();\n }\n this._status = LoaderStatus.kComplete;\n }\n\n _onReadyStateChange(e) {\n let xhr = e.target;\n\n if (xhr.readyState === 2) { // HEADERS_RECEIVED\n if (xhr.responseURL != undefined && xhr.responseURL !== this._requestURL) {\n if (this._onURLRedirect) {\n let redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);\n this._onURLRedirect(redirectedURL);\n }\n }\n\n if (xhr.status !== 0 && (xhr.status < 200 || xhr.status > 299)) {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});\n } else {\n throw new RuntimeException('MozChunkedLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);\n }\n } else {\n this._status = LoaderStatus.kBuffering;\n }\n }\n }\n\n _onProgress(e) {\n if (this._status === LoaderStatus.kError) {\n // Ignore error response\n return;\n }\n\n if (this._contentLength === null) {\n if (e.total !== null && e.total !== 0) {\n this._contentLength = e.total;\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n }\n\n let chunk = e.target.response;\n let byteStart = this._range.from + this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n }\n\n _onLoadEnd(e) {\n if (this._requestAbort === true) {\n this._requestAbort = false;\n return;\n } else if (this._status === LoaderStatus.kError) {\n return;\n }\n\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);\n }\n }\n\n _onXhrError(e) {\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if (this._contentLength && e.loaded < this._contentLength) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: 'Moz-Chunked stream meet Early-Eof'};\n } else {\n type = LoaderErrors.EXCEPTION;\n info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n}\n\nexport default MozChunkedLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n/* Notice: ms-stream may cause IE/Edge browser crash if seek too frequently!!!\n * The browser may crash in wininet.dll. Disable for now.\n *\n * For IE11/Edge browser by microsoft which supports `xhr.responseType = 'ms-stream'`\n * Notice that ms-stream API sucks. The buffer is always expanding along with downloading.\n *\n * We need to abort the xhr if buffer size exceeded limit size (e.g. 16 MiB), then do reconnect.\n * in order to release previous ArrayBuffer to avoid memory leak\n *\n * Otherwise, the ArrayBuffer will increase to a terrible size that equals final file size.\n */\nclass MSStreamLoader extends BaseLoader {\n\n static isSupported() {\n try {\n if (typeof self.MSStream === 'undefined' || typeof self.MSStreamReader === 'undefined') {\n return false;\n }\n\n let xhr = new XMLHttpRequest();\n xhr.open('GET', 'https://example.com', true);\n xhr.responseType = 'ms-stream';\n return (xhr.responseType === 'ms-stream');\n } catch (e) {\n Log.w('MSStreamLoader', e.message);\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('xhr-msstream-loader');\n this.TAG = 'MSStreamLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = true;\n\n this._xhr = null;\n this._reader = null; // MSStreamReader\n\n this._totalRange = null;\n this._currentRange = null;\n\n this._currentRequestURL = null;\n this._currentRedirectedURL = null;\n\n this._contentLength = null;\n this._receivedLength = 0;\n\n this._bufferLimit = 16 * 1024 * 1024; // 16MB\n this._lastTimeBufferSize = 0;\n this._isReconnecting = false;\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n if (this._reader) {\n this._reader.onprogress = null;\n this._reader.onload = null;\n this._reader.onerror = null;\n this._reader = null;\n }\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr = null;\n }\n super.destroy();\n }\n\n open(dataSource, range) {\n this._internalOpen(dataSource, range, false);\n }\n\n _internalOpen(dataSource, range, isSubrange) {\n this._dataSource = dataSource;\n\n if (!isSubrange) {\n this._totalRange = range;\n } else {\n this._currentRange = range;\n }\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL) {\n if (this._currentRedirectedURL != undefined) {\n sourceURL = this._currentRedirectedURL;\n } else if (dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n this._currentRequestURL = seekConfig.url;\n\n let reader = this._reader = new self.MSStreamReader();\n reader.onprogress = this._msrOnProgress.bind(this);\n reader.onload = this._msrOnLoad.bind(this);\n reader.onerror = this._msrOnError.bind(this);\n\n let xhr = this._xhr = new XMLHttpRequest();\n xhr.open('GET', seekConfig.url, true);\n xhr.responseType = 'ms-stream';\n xhr.onreadystatechange = this._xhrOnReadyStateChange.bind(this);\n xhr.onerror = this._xhrOnError.bind(this);\n\n if (dataSource.withCredentials) {\n xhr.withCredentials = true;\n }\n\n if (typeof seekConfig.headers === 'object') {\n let headers = seekConfig.headers;\n\n for (let key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n }\n\n if (this._isReconnecting) {\n this._isReconnecting = false;\n } else {\n this._status = LoaderStatus.kConnecting;\n }\n xhr.send();\n }\n\n abort() {\n this._internalAbort();\n this._status = LoaderStatus.kComplete;\n }\n\n _internalAbort() {\n if (this._reader) {\n if (this._reader.readyState === 1) { // LOADING\n this._reader.abort();\n }\n this._reader.onprogress = null;\n this._reader.onload = null;\n this._reader.onerror = null;\n this._reader = null;\n }\n if (this._xhr) {\n this._xhr.abort();\n this._xhr.onreadystatechange = null;\n this._xhr = null;\n }\n }\n\n _xhrOnReadyStateChange(e) {\n let xhr = e.target;\n\n if (xhr.readyState === 2) { // HEADERS_RECEIVED\n if (xhr.status >= 200 && xhr.status <= 299) {\n this._status = LoaderStatus.kBuffering;\n\n if (xhr.responseURL != undefined) {\n let redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);\n if (xhr.responseURL !== this._currentRequestURL && redirectedURL !== this._currentRedirectedURL) {\n this._currentRedirectedURL = redirectedURL;\n if (this._onURLRedirect) {\n this._onURLRedirect(redirectedURL);\n }\n }\n }\n\n let lengthHeader = xhr.getResponseHeader('Content-Length');\n if (lengthHeader != null && this._contentLength == null) {\n let length = parseInt(lengthHeader);\n if (length > 0) {\n this._contentLength = length;\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n }\n } else {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});\n } else {\n throw new RuntimeException('MSStreamLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);\n }\n }\n } else if (xhr.readyState === 3) { // LOADING\n if (xhr.status >= 200 && xhr.status <= 299) {\n this._status = LoaderStatus.kBuffering;\n\n let msstream = xhr.response;\n this._reader.readAsArrayBuffer(msstream);\n }\n }\n }\n\n _xhrOnError(e) {\n this._status = LoaderStatus.kError;\n let type = LoaderErrors.EXCEPTION;\n let info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n _msrOnProgress(e) {\n let reader = e.target;\n let bigbuffer = reader.result;\n if (bigbuffer == null) { // result may be null, workaround for buggy M$\n this._doReconnectIfNeeded();\n return;\n }\n\n let slice = bigbuffer.slice(this._lastTimeBufferSize);\n this._lastTimeBufferSize = bigbuffer.byteLength;\n let byteStart = this._totalRange.from + this._receivedLength;\n this._receivedLength += slice.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(slice, byteStart, this._receivedLength);\n }\n\n if (bigbuffer.byteLength >= this._bufferLimit) {\n Log.v(this.TAG, `MSStream buffer exceeded max size near ${byteStart + slice.byteLength}, reconnecting...`);\n this._doReconnectIfNeeded();\n }\n }\n\n _doReconnectIfNeeded() {\n if (this._contentLength == null || this._receivedLength < this._contentLength) {\n this._isReconnecting = true;\n this._lastTimeBufferSize = 0;\n this._internalAbort();\n\n let range = {\n from: this._totalRange.from + this._receivedLength,\n to: -1\n };\n this._internalOpen(this._dataSource, range, true);\n }\n }\n\n _msrOnLoad(e) { // actually it is onComplete event\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._totalRange.from, this._totalRange.from + this._receivedLength - 1);\n }\n }\n\n _msrOnError(e) {\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if (this._contentLength && this._receivedLength < this._contentLength) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: 'MSStream meet Early-Eof'};\n } else {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n}\n\nexport default MSStreamLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport SpeedSampler from './speed-sampler.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n// Universal IO Loader, implemented by adding Range header in xhr's request header\nclass RangeLoader extends BaseLoader {\n\n static isSupported() {\n try {\n let xhr = new XMLHttpRequest();\n xhr.open('GET', 'https://example.com', true);\n xhr.responseType = 'arraybuffer';\n return (xhr.responseType === 'arraybuffer');\n } catch (e) {\n Log.w('RangeLoader', e.message);\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('xhr-range-loader');\n this.TAG = 'RangeLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = false;\n\n this._chunkSizeKBList = [\n 128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192\n ];\n this._currentChunkSizeKB = 384;\n this._currentSpeedNormalized = 0;\n this._zeroSpeedChunkCount = 0;\n\n this._xhr = null;\n this._speedSampler = new SpeedSampler();\n\n this._requestAbort = false;\n this._waitForTotalLength = false;\n this._totalLengthReceived = false;\n\n this._currentRequestURL = null;\n this._currentRedirectedURL = null;\n this._currentRequestRange = null;\n this._totalLength = null; // size of the entire file\n this._contentLength = null; // Content-Length of entire request range\n this._receivedLength = 0; // total received bytes\n this._lastTimeLoaded = 0; // received bytes of current request sub-range\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr.onprogress = null;\n this._xhr.onload = null;\n this._xhr.onerror = null;\n this._xhr = null;\n }\n super.destroy();\n }\n\n get currentSpeed() {\n return this._speedSampler.lastSecondKBps;\n }\n\n open(dataSource, range) {\n this._dataSource = dataSource;\n this._range = range;\n this._status = LoaderStatus.kConnecting;\n\n let useRefTotalLength = false;\n if (this._dataSource.filesize != undefined && this._dataSource.filesize !== 0) {\n useRefTotalLength = true;\n this._totalLength = this._dataSource.filesize;\n }\n\n if (!this._totalLengthReceived && !useRefTotalLength) {\n // We need total filesize\n this._waitForTotalLength = true;\n this._internalOpen(this._dataSource, {from: 0, to: -1});\n } else {\n // We have filesize, start loading\n this._openSubRange();\n }\n }\n\n _openSubRange() {\n let chunkSize = this._currentChunkSizeKB * 1024;\n\n let from = this._range.from + this._receivedLength;\n let to = from + chunkSize;\n\n if (this._contentLength != null) {\n if (to - this._range.from >= this._contentLength) {\n to = this._range.from + this._contentLength - 1;\n }\n }\n\n this._currentRequestRange = {from, to};\n this._internalOpen(this._dataSource, this._currentRequestRange);\n }\n\n _internalOpen(dataSource, range) {\n this._lastTimeLoaded = 0;\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL) {\n if (this._currentRedirectedURL != undefined) {\n sourceURL = this._currentRedirectedURL;\n } else if (dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n this._currentRequestURL = seekConfig.url;\n\n let xhr = this._xhr = new XMLHttpRequest();\n xhr.open('GET', seekConfig.url, true);\n xhr.responseType = 'arraybuffer';\n xhr.onreadystatechange = this._onReadyStateChange.bind(this);\n xhr.onprogress = this._onProgress.bind(this);\n xhr.onload = this._onLoad.bind(this);\n xhr.onerror = this._onXhrError.bind(this);\n\n if (dataSource.withCredentials && xhr['withCredentials']) {\n xhr.withCredentials = true;\n }\n\n if (typeof seekConfig.headers === 'object') {\n let headers = seekConfig.headers;\n\n for (let key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n }\n\n xhr.send();\n }\n\n abort() {\n this._requestAbort = true;\n this._internalAbort();\n this._status = LoaderStatus.kComplete;\n }\n\n _internalAbort() {\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr.onprogress = null;\n this._xhr.onload = null;\n this._xhr.onerror = null;\n this._xhr.abort();\n this._xhr = null;\n }\n }\n\n _onReadyStateChange(e) {\n let xhr = e.target;\n\n if (xhr.readyState === 2) { // HEADERS_RECEIVED\n if (xhr.responseURL != undefined) { // if the browser support this property\n let redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);\n if (xhr.responseURL !== this._currentRequestURL && redirectedURL !== this._currentRedirectedURL) {\n this._currentRedirectedURL = redirectedURL;\n if (this._onURLRedirect) {\n this._onURLRedirect(redirectedURL);\n }\n }\n }\n\n if ((xhr.status >= 200 && xhr.status <= 299)) {\n if (this._waitForTotalLength) {\n return;\n }\n this._status = LoaderStatus.kBuffering;\n } else {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});\n } else {\n throw new RuntimeException('RangeLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);\n }\n }\n }\n }\n\n _onProgress(e) {\n if (this._status === LoaderStatus.kError) {\n // Ignore error response\n return;\n }\n\n if (this._contentLength === null) {\n let openNextRange = false;\n\n if (this._waitForTotalLength) {\n this._waitForTotalLength = false;\n this._totalLengthReceived = true;\n openNextRange = true;\n\n let total = e.total;\n this._internalAbort();\n if (total != null & total !== 0) {\n this._totalLength = total;\n }\n }\n\n // calculate currrent request range's contentLength\n if (this._range.to === -1) {\n this._contentLength = this._totalLength - this._range.from;\n } else { // to !== -1\n this._contentLength = this._range.to - this._range.from + 1;\n }\n\n if (openNextRange) {\n this._openSubRange();\n return;\n }\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n\n let delta = e.loaded - this._lastTimeLoaded;\n this._lastTimeLoaded = e.loaded;\n this._speedSampler.addBytes(delta);\n }\n\n _normalizeSpeed(input) {\n let list = this._chunkSizeKBList;\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (input < list[0]) {\n return list[0];\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (input >= list[mid] && input < list[mid + 1])) {\n return list[mid];\n } else if (list[mid] < input) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n }\n\n _onLoad(e) {\n if (this._status === LoaderStatus.kError) {\n // Ignore error response\n return;\n }\n\n if (this._waitForTotalLength) {\n this._waitForTotalLength = false;\n return;\n }\n\n this._lastTimeLoaded = 0;\n let KBps = this._speedSampler.lastSecondKBps;\n if (KBps === 0) {\n this._zeroSpeedChunkCount++;\n if (this._zeroSpeedChunkCount >= 3) {\n // Try get currentKBps after 3 chunks\n KBps = this._speedSampler.currentKBps;\n }\n }\n\n if (KBps !== 0) {\n let normalized = this._normalizeSpeed(KBps);\n if (this._currentSpeedNormalized !== normalized) {\n this._currentSpeedNormalized = normalized;\n this._currentChunkSizeKB = normalized;\n }\n }\n\n let chunk = e.target.response;\n let byteStart = this._range.from + this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n let reportComplete = false;\n\n if (this._contentLength != null && this._receivedLength < this._contentLength) {\n // continue load next chunk\n this._openSubRange();\n } else {\n reportComplete = true;\n }\n\n // dispatch received chunk\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n\n if (reportComplete) {\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);\n }\n }\n }\n\n _onXhrError(e) {\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if (this._contentLength && this._receivedLength > 0\n && this._receivedLength < this._contentLength) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: 'RangeLoader meet Early-Eof'};\n } else {\n type = LoaderErrors.EXCEPTION;\n info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n}\n\nexport default RangeLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport PlayerEvents from './player-events.js';\nimport Transmuxer from '../core/transmuxer.js';\nimport TransmuxingEvents from '../core/transmuxing-events.js';\nimport MSEController from '../core/mse-controller.js';\nimport MSEEvents from '../core/mse-events.js';\nimport {ErrorTypes, ErrorDetails} from './player-errors.js';\nimport {createDefaultConfig} from '../config.js';\nimport {InvalidArgumentException, IllegalStateException} from '../utils/exception.js';\n\nclass FlvPlayer {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'FlvPlayer';\n this._type = 'FlvPlayer';\n this._emitter = new EventEmitter();\n\n this._config = createDefaultConfig();\n if (typeof config === 'object') {\n Object.assign(this._config, config);\n }\n\n if (mediaDataSource.type.toLowerCase() !== 'flv') {\n throw new InvalidArgumentException('FlvPlayer requires an flv MediaDataSource input!');\n }\n\n if (mediaDataSource.isLive === true) {\n this._config.isLive = true;\n }\n\n this.e = {\n onvLoadedMetadata: this._onvLoadedMetadata.bind(this),\n onvSeeking: this._onvSeeking.bind(this),\n onvCanPlay: this._onvCanPlay.bind(this),\n onvStalled: this._onvStalled.bind(this),\n onvProgress: this._onvProgress.bind(this)\n };\n\n if (self.performance && self.performance.now) {\n this._now = self.performance.now.bind(self.performance);\n } else {\n this._now = Date.now;\n }\n\n this._pendingSeekTime = null; // in seconds\n this._requestSetTime = false;\n this._seekpointRecord = null;\n this._progressChecker = null;\n\n this._mediaDataSource = mediaDataSource;\n this._mediaElement = null;\n this._msectl = null;\n this._transmuxer = null;\n\n this._mseSourceOpened = false;\n this._hasPendingLoad = false;\n this._receivedCanPlay = false;\n\n this._mediaInfo = null;\n this._statisticsInfo = null;\n\n let chromeNeedIDRFix = (Browser.chrome &&\n (Browser.version.major < 50 ||\n (Browser.version.major === 50 && Browser.version.build < 2661)));\n this._alwaysSeekKeyframe = (chromeNeedIDRFix || Browser.msedge || Browser.msie) ? true : false;\n\n if (this._alwaysSeekKeyframe) {\n this._config.accurateSeek = false;\n }\n }\n\n destroy() {\n if (this._progressChecker != null) {\n window.clearInterval(this._progressChecker);\n this._progressChecker = null;\n }\n if (this._transmuxer) {\n this.unload();\n }\n if (this._mediaElement) {\n this.detachMediaElement();\n }\n this.e = null;\n this._mediaDataSource = null;\n\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n if (event === PlayerEvents.MEDIA_INFO) {\n if (this._mediaInfo != null) {\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.MEDIA_INFO, this.mediaInfo);\n });\n }\n } else if (event === PlayerEvents.STATISTICS_INFO) {\n if (this._statisticsInfo != null) {\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, this.statisticsInfo);\n });\n }\n }\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n attachMediaElement(mediaElement) {\n this._mediaElement = mediaElement;\n mediaElement.addEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n mediaElement.addEventListener('seeking', this.e.onvSeeking);\n mediaElement.addEventListener('canplay', this.e.onvCanPlay);\n mediaElement.addEventListener('stalled', this.e.onvStalled);\n mediaElement.addEventListener('progress', this.e.onvProgress);\n\n this._msectl = new MSEController(this._config);\n\n this._msectl.on(MSEEvents.UPDATE_END, this._onmseUpdateEnd.bind(this));\n this._msectl.on(MSEEvents.BUFFER_FULL, this._onmseBufferFull.bind(this));\n this._msectl.on(MSEEvents.SOURCE_OPEN, () => {\n this._mseSourceOpened = true;\n if (this._hasPendingLoad) {\n this._hasPendingLoad = false;\n this.load();\n }\n });\n this._msectl.on(MSEEvents.ERROR, (info) => {\n this._emitter.emit(PlayerEvents.ERROR,\n ErrorTypes.MEDIA_ERROR,\n ErrorDetails.MEDIA_MSE_ERROR,\n info\n );\n });\n\n this._msectl.attachMediaElement(mediaElement);\n\n if (this._pendingSeekTime != null) {\n try {\n mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n } catch (e) {\n // IE11 may throw InvalidStateError if readyState === 0\n // We can defer set currentTime operation after loadedmetadata\n }\n }\n }\n\n detachMediaElement() {\n if (this._mediaElement) {\n this._msectl.detachMediaElement();\n this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n this._mediaElement.removeEventListener('seeking', this.e.onvSeeking);\n this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);\n this._mediaElement.removeEventListener('stalled', this.e.onvStalled);\n this._mediaElement.removeEventListener('progress', this.e.onvProgress);\n this._mediaElement = null;\n }\n if (this._msectl) {\n this._msectl.destroy();\n this._msectl = null;\n }\n }\n\n load() {\n if (!this._mediaElement) {\n throw new IllegalStateException('HTMLMediaElement must be attached before load()!');\n }\n if (this._transmuxer) {\n throw new IllegalStateException('FlvPlayer.load() has been called, please call unload() first!');\n }\n if (this._hasPendingLoad) {\n return;\n }\n\n if (this._config.deferLoadAfterSourceOpen && this._mseSourceOpened === false) {\n this._hasPendingLoad = true;\n return;\n }\n\n if (this._mediaElement.readyState > 0) {\n this._requestSetTime = true;\n // IE11 may throw InvalidStateError if readyState === 0\n this._mediaElement.currentTime = 0;\n }\n\n this._transmuxer = new Transmuxer(this._mediaDataSource, this._config);\n\n this._transmuxer.on(TransmuxingEvents.INIT_SEGMENT, (type, is) => {\n this._msectl.appendInitSegment(is);\n });\n this._transmuxer.on(TransmuxingEvents.MEDIA_SEGMENT, (type, ms) => {\n this._msectl.appendMediaSegment(ms);\n\n // lazyLoad check\n if (this._config.lazyLoad && !this._config.isLive) {\n let currentTime = this._mediaElement.currentTime;\n if (ms.info.endDts >= (currentTime + this._config.lazyLoadMaxDuration) * 1000) {\n if (this._progressChecker == null) {\n Log.v(this.TAG, 'Maximum buffering duration exceeded, suspend transmuxing task');\n this._suspendTransmuxer();\n }\n }\n }\n });\n this._transmuxer.on(TransmuxingEvents.LOADING_COMPLETE, () => {\n this._msectl.endOfStream();\n this._emitter.emit(PlayerEvents.LOADING_COMPLETE);\n });\n this._transmuxer.on(TransmuxingEvents.RECOVERED_EARLY_EOF, () => {\n this._emitter.emit(PlayerEvents.RECOVERED_EARLY_EOF);\n });\n this._transmuxer.on(TransmuxingEvents.IO_ERROR, (detail, info) => {\n this._emitter.emit(PlayerEvents.ERROR, ErrorTypes.NETWORK_ERROR, detail, info);\n });\n this._transmuxer.on(TransmuxingEvents.DEMUX_ERROR, (detail, info) => {\n this._emitter.emit(PlayerEvents.ERROR, ErrorTypes.MEDIA_ERROR, detail, {code: -1, msg: info});\n });\n this._transmuxer.on(TransmuxingEvents.MEDIA_INFO, (mediaInfo) => {\n this._mediaInfo = mediaInfo;\n this._emitter.emit(PlayerEvents.MEDIA_INFO, Object.assign({}, mediaInfo));\n });\n this._transmuxer.on(TransmuxingEvents.STATISTICS_INFO, (statInfo) => {\n this._statisticsInfo = this._fillStatisticsInfo(statInfo);\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, Object.assign({}, this._statisticsInfo));\n });\n this._transmuxer.on(TransmuxingEvents.RECOMMEND_SEEKPOINT, (milliseconds) => {\n if (this._mediaElement && !this._config.accurateSeek) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = milliseconds / 1000;\n }\n });\n\n this._transmuxer.open();\n }\n\n unload() {\n if (this._mediaElement) {\n this._mediaElement.pause();\n }\n if (this._msectl) {\n this._msectl.seek(0);\n }\n if (this._transmuxer) {\n this._transmuxer.close();\n this._transmuxer.destroy();\n this._transmuxer = null;\n }\n }\n\n play() {\n return this._mediaElement.play();\n }\n\n pause() {\n this._mediaElement.pause();\n }\n\n get type() {\n return this._type;\n }\n\n get buffered() {\n return this._mediaElement.buffered;\n }\n\n get duration() {\n return this._mediaElement.duration;\n }\n\n get volume() {\n return this._mediaElement.volume;\n }\n\n set volume(value) {\n this._mediaElement.volume = value;\n }\n\n get muted() {\n return this._mediaElement.muted;\n }\n\n set muted(muted) {\n this._mediaElement.muted = muted;\n }\n\n get currentTime() {\n if (this._mediaElement) {\n return this._mediaElement.currentTime;\n }\n return 0;\n }\n\n set currentTime(seconds) {\n if (this._mediaElement) {\n this._internalSeek(seconds);\n } else {\n this._pendingSeekTime = seconds;\n }\n }\n\n get mediaInfo() {\n return Object.assign({}, this._mediaInfo);\n }\n\n get statisticsInfo() {\n if (this._statisticsInfo == null) {\n this._statisticsInfo = {};\n }\n this._statisticsInfo = this._fillStatisticsInfo(this._statisticsInfo);\n return Object.assign({}, this._statisticsInfo);\n }\n\n _fillStatisticsInfo(statInfo) {\n statInfo.playerType = this._type;\n\n if (!(this._mediaElement instanceof HTMLVideoElement)) {\n return statInfo;\n }\n\n let hasQualityInfo = true;\n let decoded = 0;\n let dropped = 0;\n\n if (this._mediaElement.getVideoPlaybackQuality) {\n let quality = this._mediaElement.getVideoPlaybackQuality();\n decoded = quality.totalVideoFrames;\n dropped = quality.droppedVideoFrames;\n } else if (this._mediaElement.webkitDecodedFrameCount != undefined) {\n decoded = this._mediaElement.webkitDecodedFrameCount;\n dropped = this._mediaElement.webkitDroppedFrameCount;\n } else {\n hasQualityInfo = false;\n }\n\n if (hasQualityInfo) {\n statInfo.decodedFrames = decoded;\n statInfo.droppedFrames = dropped;\n }\n\n return statInfo;\n }\n\n _onmseUpdateEnd() {\n if (!this._config.lazyLoad || this._config.isLive) {\n return;\n }\n\n let buffered = this._mediaElement.buffered;\n let currentTime = this._mediaElement.currentTime;\n let currentRangeStart = 0;\n let currentRangeEnd = 0;\n\n for (let i = 0; i < buffered.length; i++) {\n let start = buffered.start(i);\n let end = buffered.end(i);\n if (start <= currentTime && currentTime < end) {\n currentRangeStart = start;\n currentRangeEnd = end;\n break;\n }\n }\n\n if (currentRangeEnd >= currentTime + this._config.lazyLoadMaxDuration && this._progressChecker == null) {\n Log.v(this.TAG, 'Maximum buffering duration exceeded, suspend transmuxing task');\n this._suspendTransmuxer();\n }\n }\n\n _onmseBufferFull() {\n Log.v(this.TAG, 'MSE SourceBuffer is full, suspend transmuxing task');\n if (this._progressChecker == null) {\n this._suspendTransmuxer();\n }\n }\n\n _suspendTransmuxer() {\n if (this._transmuxer) {\n this._transmuxer.pause();\n\n if (this._progressChecker == null) {\n this._progressChecker = window.setInterval(this._checkProgressAndResume.bind(this), 1000);\n }\n }\n }\n\n _checkProgressAndResume() {\n let currentTime = this._mediaElement.currentTime;\n let buffered = this._mediaElement.buffered;\n\n let needResume = false;\n\n for (let i = 0; i < buffered.length; i++) {\n let from = buffered.start(i);\n let to = buffered.end(i);\n if (currentTime >= from && currentTime < to) {\n if (currentTime >= to - this._config.lazyLoadRecoverDuration) {\n needResume = true;\n }\n break;\n }\n }\n\n if (needResume) {\n window.clearInterval(this._progressChecker);\n this._progressChecker = null;\n if (needResume) {\n Log.v(this.TAG, 'Continue loading from paused position');\n this._transmuxer.resume();\n }\n }\n }\n\n _isTimepointBuffered(seconds) {\n let buffered = this._mediaElement.buffered;\n\n for (let i = 0; i < buffered.length; i++) {\n let from = buffered.start(i);\n let to = buffered.end(i);\n if (seconds >= from && seconds < to) {\n return true;\n }\n }\n return false;\n }\n\n _internalSeek(seconds) {\n let directSeek = this._isTimepointBuffered(seconds);\n\n let directSeekBegin = false;\n let directSeekBeginTime = 0;\n\n if (seconds < 1.0 && this._mediaElement.buffered.length > 0) {\n let videoBeginTime = this._mediaElement.buffered.start(0);\n if ((videoBeginTime < 1.0 && seconds < videoBeginTime) || Browser.safari) {\n directSeekBegin = true;\n // also workaround for Safari: Seek to 0 may cause video stuck, use 0.1 to avoid\n directSeekBeginTime = Browser.safari ? 0.1 : videoBeginTime;\n }\n }\n\n if (directSeekBegin) { // seek to video begin, set currentTime directly if beginPTS buffered\n this._requestSetTime = true;\n this._mediaElement.currentTime = directSeekBeginTime;\n } else if (directSeek) { // buffered position\n if (!this._alwaysSeekKeyframe) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = seconds;\n } else {\n let idr = this._msectl.getNearestKeyframe(Math.floor(seconds * 1000));\n this._requestSetTime = true;\n if (idr != null) {\n this._mediaElement.currentTime = idr.dts / 1000;\n } else {\n this._mediaElement.currentTime = seconds;\n }\n }\n if (this._progressChecker != null) {\n this._checkProgressAndResume();\n }\n } else {\n if (this._progressChecker != null) {\n window.clearInterval(this._progressChecker);\n this._progressChecker = null;\n }\n this._msectl.seek(seconds);\n this._transmuxer.seek(Math.floor(seconds * 1000)); // in milliseconds\n // no need to set mediaElement.currentTime if non-accurateSeek,\n // just wait for the recommend_seekpoint callback\n if (this._config.accurateSeek) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = seconds;\n }\n }\n }\n\n _checkAndApplyUnbufferedSeekpoint() {\n if (this._seekpointRecord) {\n if (this._seekpointRecord.recordTime <= this._now() - 100) {\n let target = this._mediaElement.currentTime;\n this._seekpointRecord = null;\n if (!this._isTimepointBuffered(target)) {\n if (this._progressChecker != null) {\n window.clearTimeout(this._progressChecker);\n this._progressChecker = null;\n }\n // .currentTime is consists with .buffered timestamp\n // Chrome/Edge use DTS, while FireFox/Safari use PTS\n this._msectl.seek(target);\n this._transmuxer.seek(Math.floor(target * 1000));\n // set currentTime if accurateSeek, or wait for recommend_seekpoint callback\n if (this._config.accurateSeek) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = target;\n }\n }\n } else {\n window.setTimeout(this._checkAndApplyUnbufferedSeekpoint.bind(this), 50);\n }\n }\n }\n\n _checkAndResumeStuckPlayback(stalled) {\n let media = this._mediaElement;\n if (stalled || !this._receivedCanPlay || media.readyState < 2) { // HAVE_CURRENT_DATA\n let buffered = media.buffered;\n if (buffered.length > 0 && media.currentTime < buffered.start(0)) {\n Log.w(this.TAG, `Playback seems stuck at ${media.currentTime}, seek to ${buffered.start(0)}`);\n this._requestSetTime = true;\n this._mediaElement.currentTime = buffered.start(0);\n this._mediaElement.removeEventListener('progress', this.e.onvProgress);\n }\n } else {\n // Playback didn't stuck, remove progress event listener\n this._mediaElement.removeEventListener('progress', this.e.onvProgress);\n }\n }\n\n _onvLoadedMetadata(e) {\n if (this._pendingSeekTime != null) {\n this._mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n }\n }\n\n _onvSeeking(e) { // handle seeking request from browser's progress bar\n let target = this._mediaElement.currentTime;\n let buffered = this._mediaElement.buffered;\n\n if (this._requestSetTime) {\n this._requestSetTime = false;\n return;\n }\n\n if (target < 1.0 && buffered.length > 0) {\n // seek to video begin, set currentTime directly if beginPTS buffered\n let videoBeginTime = buffered.start(0);\n if ((videoBeginTime < 1.0 && target < videoBeginTime) || Browser.safari) {\n this._requestSetTime = true;\n // also workaround for Safari: Seek to 0 may cause video stuck, use 0.1 to avoid\n this._mediaElement.currentTime = Browser.safari ? 0.1 : videoBeginTime;\n return;\n }\n }\n\n if (this._isTimepointBuffered(target)) {\n if (this._alwaysSeekKeyframe) {\n let idr = this._msectl.getNearestKeyframe(Math.floor(target * 1000));\n if (idr != null) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = idr.dts / 1000;\n }\n }\n if (this._progressChecker != null) {\n this._checkProgressAndResume();\n }\n return;\n }\n\n this._seekpointRecord = {\n seekPoint: target,\n recordTime: this._now()\n };\n window.setTimeout(this._checkAndApplyUnbufferedSeekpoint.bind(this), 50);\n }\n\n _onvCanPlay(e) {\n this._receivedCanPlay = true;\n this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);\n }\n\n _onvStalled(e) {\n this._checkAndResumeStuckPlayback(true);\n }\n\n _onvProgress(e) {\n this._checkAndResumeStuckPlayback();\n }\n\n}\n\nexport default FlvPlayer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport PlayerEvents from './player-events.js';\nimport {createDefaultConfig} from '../config.js';\nimport {InvalidArgumentException, IllegalStateException} from '../utils/exception.js';\n\n// Player wrapper for browser's native player (HTMLVideoElement) without MediaSource src. \nclass NativePlayer {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'NativePlayer';\n this._type = 'NativePlayer';\n this._emitter = new EventEmitter();\n\n this._config = createDefaultConfig();\n if (typeof config === 'object') {\n Object.assign(this._config, config);\n }\n\n if (mediaDataSource.type.toLowerCase() === 'flv') {\n throw new InvalidArgumentException('NativePlayer does\\'t support flv MediaDataSource input!');\n }\n if (mediaDataSource.hasOwnProperty('segments')) {\n throw new InvalidArgumentException(`NativePlayer(${mediaDataSource.type}) doesn't support multipart playback!`);\n }\n\n this.e = {\n onvLoadedMetadata: this._onvLoadedMetadata.bind(this)\n };\n\n this._pendingSeekTime = null;\n this._statisticsReporter = null;\n\n this._mediaDataSource = mediaDataSource;\n this._mediaElement = null;\n }\n\n destroy() {\n if (this._mediaElement) {\n this.unload();\n this.detachMediaElement();\n }\n this.e = null;\n this._mediaDataSource = null;\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n if (event === PlayerEvents.MEDIA_INFO) {\n if (this._mediaElement != null && this._mediaElement.readyState !== 0) { // HAVE_NOTHING\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.MEDIA_INFO, this.mediaInfo);\n });\n }\n } else if (event === PlayerEvents.STATISTICS_INFO) {\n if (this._mediaElement != null && this._mediaElement.readyState !== 0) {\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, this.statisticsInfo);\n });\n }\n }\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n attachMediaElement(mediaElement) {\n this._mediaElement = mediaElement;\n mediaElement.addEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n\n if (this._pendingSeekTime != null) {\n try {\n mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n } catch (e) {\n // IE11 may throw InvalidStateError if readyState === 0\n // Defer set currentTime operation after loadedmetadata\n }\n }\n }\n\n detachMediaElement() {\n if (this._mediaElement) {\n this._mediaElement.src = '';\n this._mediaElement.removeAttribute('src');\n this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n this._mediaElement = null;\n }\n if (this._statisticsReporter != null) {\n window.clearInterval(this._statisticsReporter);\n this._statisticsReporter = null;\n }\n }\n\n load() {\n if (!this._mediaElement) {\n throw new IllegalStateException('HTMLMediaElement must be attached before load()!');\n }\n this._mediaElement.src = this._mediaDataSource.url;\n\n if (this._mediaElement.readyState > 0) {\n this._mediaElement.currentTime = 0;\n }\n\n this._mediaElement.preload = 'auto';\n this._mediaElement.load();\n this._statisticsReporter = window.setInterval(\n this._reportStatisticsInfo.bind(this),\n this._config.statisticsInfoReportInterval);\n }\n\n unload() {\n if (this._mediaElement) {\n this._mediaElement.src = '';\n this._mediaElement.removeAttribute('src');\n }\n if (this._statisticsReporter != null) {\n window.clearInterval(this._statisticsReporter);\n this._statisticsReporter = null;\n }\n }\n\n play() {\n return this._mediaElement.play();\n }\n\n pause() {\n this._mediaElement.pause();\n }\n\n get type() {\n return this._type;\n }\n\n get buffered() {\n return this._mediaElement.buffered;\n }\n\n get duration() {\n return this._mediaElement.duration;\n }\n\n get volume() {\n return this._mediaElement.volume;\n }\n\n set volume(value) {\n this._mediaElement.volume = value;\n }\n\n get muted() {\n return this._mediaElement.muted;\n }\n\n set muted(muted) {\n this._mediaElement.muted = muted;\n }\n\n get currentTime() {\n if (this._mediaElement) {\n return this._mediaElement.currentTime;\n }\n return 0;\n }\n\n set currentTime(seconds) {\n if (this._mediaElement) {\n this._mediaElement.currentTime = seconds;\n } else {\n this._pendingSeekTime = seconds;\n }\n }\n\n get mediaInfo() {\n let mediaPrefix = (this._mediaElement instanceof HTMLAudioElement) ? 'audio/' : 'video/';\n let info = {\n mimeType: mediaPrefix + this._mediaDataSource.type\n };\n if (this._mediaElement) {\n info.duration = Math.floor(this._mediaElement.duration * 1000);\n if (this._mediaElement instanceof HTMLVideoElement) {\n info.width = this._mediaElement.videoWidth;\n info.height = this._mediaElement.videoHeight;\n }\n }\n return info;\n }\n\n get statisticsInfo() {\n let info = {\n playerType: this._type,\n url: this._mediaDataSource.url\n };\n\n if (!(this._mediaElement instanceof HTMLVideoElement)) {\n return info;\n }\n\n let hasQualityInfo = true;\n let decoded = 0;\n let dropped = 0;\n\n if (this._mediaElement.getVideoPlaybackQuality) {\n let quality = this._mediaElement.getVideoPlaybackQuality();\n decoded = quality.totalVideoFrames;\n dropped = quality.droppedVideoFrames;\n } else if (this._mediaElement.webkitDecodedFrameCount != undefined) {\n decoded = this._mediaElement.webkitDecodedFrameCount;\n dropped = this._mediaElement.webkitDroppedFrameCount;\n } else {\n hasQualityInfo = false;\n }\n\n if (hasQualityInfo) {\n info.decodedFrames = decoded;\n info.droppedFrames = dropped;\n }\n \n return info;\n }\n\n _onvLoadedMetadata(e) {\n if (this._pendingSeekTime != null) {\n this._mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n }\n this._emitter.emit(PlayerEvents.MEDIA_INFO, this.mediaInfo);\n }\n\n _reportStatisticsInfo() {\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, this.statisticsInfo);\n }\n\n}\n\nexport default NativePlayer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {LoaderErrors} from '../io/loader.js';\nimport DemuxErrors from '../demux/demux-errors.js';\n\nexport const ErrorTypes = {\n NETWORK_ERROR: 'NetworkError',\n MEDIA_ERROR: 'MediaError',\n OTHER_ERROR: 'OtherError'\n};\n\nexport const ErrorDetails = {\n NETWORK_EXCEPTION: LoaderErrors.EXCEPTION,\n NETWORK_STATUS_CODE_INVALID: LoaderErrors.HTTP_STATUS_CODE_INVALID,\n NETWORK_TIMEOUT: LoaderErrors.CONNECTING_TIMEOUT,\n NETWORK_UNRECOVERABLE_EARLY_EOF: LoaderErrors.UNRECOVERABLE_EARLY_EOF,\n\n MEDIA_MSE_ERROR: 'MediaMSEError',\n\n MEDIA_FORMAT_ERROR: DemuxErrors.FORMAT_ERROR,\n MEDIA_FORMAT_UNSUPPORTED: DemuxErrors.FORMAT_UNSUPPORTED,\n MEDIA_CODEC_UNSUPPORTED: DemuxErrors.CODEC_UNSUPPORTED\n};","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst PlayerEvents = {\n ERROR: 'error',\n LOADING_COMPLETE: 'loading_complete',\n RECOVERED_EARLY_EOF: 'recovered_early_eof',\n MEDIA_INFO: 'media_info',\n STATISTICS_INFO: 'statistics_info'\n};\n\nexport default PlayerEvents;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * This file is modified from dailymotion's hls.js library (hls.js/src/helper/aac.js)\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass AAC {\n\n static getSilentFrame(codec, channelCount) {\n if (codec === 'mp4a.40.2') {\n // handle LC-AAC\n if (channelCount === 1) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);\n } else if (channelCount === 2) {\n return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]);\n } else if (channelCount === 3) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]);\n } else if (channelCount === 4) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]);\n } else if (channelCount === 5) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]);\n } else if (channelCount === 6) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]);\n }\n } else {\n // handle HE-AAC (mp4a.40.5 / mp4a.40.29)\n if (channelCount === 1) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0:d=0.05\" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);\n } else if (channelCount === 2) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0|0:d=0.05\" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);\n } else if (channelCount === 3) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0|0|0:d=0.05\" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);\n }\n }\n return null;\n }\n\n}\n\nexport default AAC;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * This file is derived from dailymotion's hls.js library (hls.js/src/remux/mp4-generator.js)\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// MP4 boxes generator for ISO BMFF (ISO Base Media File Format, defined in ISO/IEC 14496-12)\nclass MP4 {\n\n static init() {\n MP4.types = {\n avc1: [], avcC: [], btrt: [], dinf: [],\n dref: [], esds: [], ftyp: [], hdlr: [],\n mdat: [], mdhd: [], mdia: [], mfhd: [],\n minf: [], moof: [], moov: [], mp4a: [],\n mvex: [], mvhd: [], sdtp: [], stbl: [],\n stco: [], stsc: [], stsd: [], stsz: [],\n stts: [], tfdt: [], tfhd: [], traf: [],\n trak: [], trun: [], trex: [], tkhd: [],\n vmhd: [], smhd: [], '.mp3': []\n };\n\n for (let name in MP4.types) {\n if (MP4.types.hasOwnProperty(name)) {\n MP4.types[name] = [\n name.charCodeAt(0),\n name.charCodeAt(1),\n name.charCodeAt(2),\n name.charCodeAt(3)\n ];\n }\n }\n\n let constants = MP4.constants = {};\n\n constants.FTYP = new Uint8Array([\n 0x69, 0x73, 0x6F, 0x6D, // major_brand: isom\n 0x0, 0x0, 0x0, 0x1, // minor_version: 0x01\n 0x69, 0x73, 0x6F, 0x6D, // isom\n 0x61, 0x76, 0x63, 0x31 // avc1\n ]);\n\n constants.STSD_PREFIX = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x01 // entry_count\n ]);\n\n constants.STTS = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00 // entry_count\n ]);\n\n constants.STSC = constants.STCO = constants.STTS;\n\n constants.STSZ = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // sample_size\n 0x00, 0x00, 0x00, 0x00 // sample_count\n ]);\n\n constants.HDLR_VIDEO = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // pre_defined\n 0x76, 0x69, 0x64, 0x65, // handler_type: 'vide'\n 0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x56, 0x69, 0x64, 0x65,\n 0x6F, 0x48, 0x61, 0x6E,\n 0x64, 0x6C, 0x65, 0x72, 0x00 // name: VideoHandler\n ]);\n\n constants.HDLR_AUDIO = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // pre_defined\n 0x73, 0x6F, 0x75, 0x6E, // handler_type: 'soun'\n 0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x53, 0x6F, 0x75, 0x6E,\n 0x64, 0x48, 0x61, 0x6E,\n 0x64, 0x6C, 0x65, 0x72, 0x00 // name: SoundHandler\n ]);\n\n constants.DREF = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x01, // entry_count\n 0x00, 0x00, 0x00, 0x0C, // entry_size\n 0x75, 0x72, 0x6C, 0x20, // type 'url '\n 0x00, 0x00, 0x00, 0x01 // version(0) + flags\n ]);\n\n // Sound media header\n constants.SMHD = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00 // balance(2) + reserved(2)\n ]);\n\n // video media header\n constants.VMHD = new Uint8Array([\n 0x00, 0x00, 0x00, 0x01, // version(0) + flags\n 0x00, 0x00, // graphicsmode: 2 bytes\n 0x00, 0x00, 0x00, 0x00, // opcolor: 3 * 2 bytes\n 0x00, 0x00\n ]);\n }\n\n // Generate a box\n static box(type) {\n let size = 8;\n let result = null;\n let datas = Array.prototype.slice.call(arguments, 1);\n let arrayCount = datas.length;\n\n for (let i = 0; i < arrayCount; i++) {\n size += datas[i].byteLength;\n }\n\n result = new Uint8Array(size);\n result[0] = (size >>> 24) & 0xFF; // size\n result[1] = (size >>> 16) & 0xFF;\n result[2] = (size >>> 8) & 0xFF;\n result[3] = (size) & 0xFF;\n\n result.set(type, 4); // type\n\n let offset = 8;\n for (let i = 0; i < arrayCount; i++) { // data body\n result.set(datas[i], offset);\n offset += datas[i].byteLength;\n }\n\n return result;\n }\n\n // emit ftyp & moov\n static generateInitSegment(meta) {\n let ftyp = MP4.box(MP4.types.ftyp, MP4.constants.FTYP);\n let moov = MP4.moov(meta);\n\n let result = new Uint8Array(ftyp.byteLength + moov.byteLength);\n result.set(ftyp, 0);\n result.set(moov, ftyp.byteLength);\n return result;\n }\n\n // Movie metadata box\n static moov(meta) {\n let mvhd = MP4.mvhd(meta.timescale, meta.duration);\n let trak = MP4.trak(meta);\n let mvex = MP4.mvex(meta);\n return MP4.box(MP4.types.moov, mvhd, trak, mvex);\n }\n\n // Movie header box\n static mvhd(timescale, duration) {\n return MP4.box(MP4.types.mvhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // creation_time\n 0x00, 0x00, 0x00, 0x00, // modification_time\n (timescale >>> 24) & 0xFF, // timescale: 4 bytes\n (timescale >>> 16) & 0xFF,\n (timescale >>> 8) & 0xFF,\n (timescale) & 0xFF,\n (duration >>> 24) & 0xFF, // duration: 4 bytes\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n 0x00, 0x01, 0x00, 0x00, // Preferred rate: 1.0\n 0x01, 0x00, 0x00, 0x00, // PreferredVolume(1.0, 2bytes) + reserved(2bytes)\n 0x00, 0x00, 0x00, 0x00, // reserved: 4 + 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x01, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x40, 0x00, 0x00, 0x00, // ----end composition matrix----\n 0x00, 0x00, 0x00, 0x00, // ----begin pre_defined 6 * 4 bytes----\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, // ----end pre_defined 6 * 4 bytes----\n 0xFF, 0xFF, 0xFF, 0xFF // next_track_ID\n ]));\n }\n\n // Track box\n static trak(meta) {\n return MP4.box(MP4.types.trak, MP4.tkhd(meta), MP4.mdia(meta));\n }\n\n // Track header box\n static tkhd(meta) {\n let trackId = meta.id, duration = meta.duration;\n let width = meta.presentWidth, height = meta.presentHeight;\n\n return MP4.box(MP4.types.tkhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x07, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // creation_time\n 0x00, 0x00, 0x00, 0x00, // modification_time\n (trackId >>> 24) & 0xFF, // track_ID: 4 bytes\n (trackId >>> 16) & 0xFF,\n (trackId >>> 8) & 0xFF,\n (trackId) & 0xFF,\n 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes\n (duration >>> 24) & 0xFF, // duration: 4 bytes\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, // layer(2bytes) + alternate_group(2bytes)\n 0x00, 0x00, 0x00, 0x00, // volume(2bytes) + reserved(2bytes)\n 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x01, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x40, 0x00, 0x00, 0x00, // ----end composition matrix----\n (width >>> 8) & 0xFF, // width and height\n (width) & 0xFF,\n 0x00, 0x00,\n (height >>> 8) & 0xFF,\n (height) & 0xFF,\n 0x00, 0x00\n ]));\n }\n\n // Media Box\n static mdia(meta) {\n return MP4.box(MP4.types.mdia, MP4.mdhd(meta), MP4.hdlr(meta), MP4.minf(meta));\n }\n\n // Media header box\n static mdhd(meta) {\n let timescale = meta.timescale;\n let duration = meta.duration;\n return MP4.box(MP4.types.mdhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // creation_time\n 0x00, 0x00, 0x00, 0x00, // modification_time\n (timescale >>> 24) & 0xFF, // timescale: 4 bytes\n (timescale >>> 16) & 0xFF,\n (timescale >>> 8) & 0xFF,\n (timescale) & 0xFF,\n (duration >>> 24) & 0xFF, // duration: 4 bytes\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n 0x55, 0xC4, // language: und (undetermined)\n 0x00, 0x00 // pre_defined = 0\n ]));\n }\n\n // Media handler reference box\n static hdlr(meta) {\n let data = null;\n if (meta.type === 'audio') {\n data = MP4.constants.HDLR_AUDIO;\n } else {\n data = MP4.constants.HDLR_VIDEO;\n }\n return MP4.box(MP4.types.hdlr, data);\n }\n\n // Media infomation box\n static minf(meta) {\n let xmhd = null;\n if (meta.type === 'audio') {\n xmhd = MP4.box(MP4.types.smhd, MP4.constants.SMHD);\n } else {\n xmhd = MP4.box(MP4.types.vmhd, MP4.constants.VMHD);\n }\n return MP4.box(MP4.types.minf, xmhd, MP4.dinf(), MP4.stbl(meta));\n }\n\n // Data infomation box\n static dinf() {\n let result = MP4.box(MP4.types.dinf,\n MP4.box(MP4.types.dref, MP4.constants.DREF)\n );\n return result;\n }\n\n // Sample table box\n static stbl(meta) {\n let result = MP4.box(MP4.types.stbl, // type: stbl\n MP4.stsd(meta), // Sample Description Table\n MP4.box(MP4.types.stts, MP4.constants.STTS), // Time-To-Sample\n MP4.box(MP4.types.stsc, MP4.constants.STSC), // Sample-To-Chunk\n MP4.box(MP4.types.stsz, MP4.constants.STSZ), // Sample size\n MP4.box(MP4.types.stco, MP4.constants.STCO) // Chunk offset\n ); \n return result; \n }\n\n // Sample description box\n static stsd(meta) {\n if (meta.type === 'audio') {\n if (meta.codec === 'mp3') {\n return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp3(meta));\n }\n // else: aac -> mp4a\n return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp4a(meta));\n } else {\n return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.avc1(meta));\n }\n }\n\n static mp3(meta) {\n let channelCount = meta.channelCount;\n let sampleRate = meta.audioSampleRate;\n\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)\n 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, channelCount, // channelCount(2)\n 0x00, 0x10, // sampleSize(2)\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n (sampleRate >>> 8) & 0xFF, // Audio sample rate\n (sampleRate) & 0xFF,\n 0x00, 0x00\n ]);\n\n return MP4.box(MP4.types['.mp3'], data);\n }\n\n static mp4a(meta) {\n let channelCount = meta.channelCount;\n let sampleRate = meta.audioSampleRate;\n\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)\n 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, channelCount, // channelCount(2)\n 0x00, 0x10, // sampleSize(2)\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n (sampleRate >>> 8) & 0xFF, // Audio sample rate\n (sampleRate) & 0xFF,\n 0x00, 0x00\n ]);\n\n return MP4.box(MP4.types.mp4a, data, MP4.esds(meta));\n }\n\n static esds(meta) {\n let config = meta.config || [];\n let configSize = config.length;\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version 0 + flags\n\n 0x03, // descriptor_type\n 0x17 + configSize, // length3\n 0x00, 0x01, // es_id\n 0x00, // stream_priority\n\n 0x04, // descriptor_type\n 0x0F + configSize, // length\n 0x40, // codec: mpeg4_audio\n 0x15, // stream_type: Audio\n 0x00, 0x00, 0x00, // buffer_size\n 0x00, 0x00, 0x00, 0x00, // maxBitrate\n 0x00, 0x00, 0x00, 0x00, // avgBitrate\n\n 0x05 // descriptor_type\n ].concat([\n configSize\n ]).concat(\n config\n ).concat([\n 0x06, 0x01, 0x02 // GASpecificConfig\n ]));\n return MP4.box(MP4.types.esds, data);\n }\n\n static avc1(meta) {\n let avcc = meta.avcc;\n let width = meta.codecWidth, height = meta.codecHeight;\n\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)\n 0x00, 0x00, 0x00, 0x00, // pre_defined(2) + reserved(2)\n 0x00, 0x00, 0x00, 0x00, // pre_defined: 3 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n (width >>> 8) & 0xFF, // width: 2 bytes\n (width) & 0xFF,\n (height >>> 8) & 0xFF, // height: 2 bytes\n (height) & 0xFF,\n 0x00, 0x48, 0x00, 0x00, // horizresolution: 4 bytes\n 0x00, 0x48, 0x00, 0x00, // vertresolution: 4 bytes\n 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes\n 0x00, 0x01, // frame_count\n 0x0A, // strlen\n 0x78, 0x71, 0x71, 0x2F, // compressorname: 32 bytes\n 0x66, 0x6C, 0x76, 0x2E,\n 0x6A, 0x73, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00,\n 0x00, 0x18, // depth\n 0xFF, 0xFF // pre_defined = -1\n ]);\n return MP4.box(MP4.types.avc1, data, MP4.box(MP4.types.avcC, avcc));\n }\n\n // Movie Extends box\n static mvex(meta) {\n return MP4.box(MP4.types.mvex, MP4.trex(meta));\n }\n\n // Track Extends box\n static trex(meta) {\n let trackId = meta.id;\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n (trackId >>> 24) & 0xFF, // track_ID\n (trackId >>> 16) & 0xFF,\n (trackId >>> 8) & 0xFF,\n (trackId) & 0xFF,\n 0x00, 0x00, 0x00, 0x01, // default_sample_description_index\n 0x00, 0x00, 0x00, 0x00, // default_sample_duration\n 0x00, 0x00, 0x00, 0x00, // default_sample_size\n 0x00, 0x01, 0x00, 0x01 // default_sample_flags\n ]);\n return MP4.box(MP4.types.trex, data);\n }\n\n // Movie fragment box\n static moof(track, baseMediaDecodeTime) {\n return MP4.box(MP4.types.moof, MP4.mfhd(track.sequenceNumber), MP4.traf(track, baseMediaDecodeTime));\n }\n\n static mfhd(sequenceNumber) {\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00,\n (sequenceNumber >>> 24) & 0xFF, // sequence_number: int32\n (sequenceNumber >>> 16) & 0xFF,\n (sequenceNumber >>> 8) & 0xFF,\n (sequenceNumber) & 0xFF\n ]);\n return MP4.box(MP4.types.mfhd, data);\n }\n\n // Track fragment box\n static traf(track, baseMediaDecodeTime) {\n let trackId = track.id;\n\n // Track fragment header box\n let tfhd = MP4.box(MP4.types.tfhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) & flags\n (trackId >>> 24) & 0xFF, // track_ID\n (trackId >>> 16) & 0xFF,\n (trackId >>> 8) & 0xFF,\n (trackId) & 0xFF\n ]));\n // Track Fragment Decode Time\n let tfdt = MP4.box(MP4.types.tfdt, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) & flags\n (baseMediaDecodeTime >>> 24) & 0xFF, // baseMediaDecodeTime: int32\n (baseMediaDecodeTime >>> 16) & 0xFF,\n (baseMediaDecodeTime >>> 8) & 0xFF,\n (baseMediaDecodeTime) & 0xFF\n ]));\n let sdtp = MP4.sdtp(track);\n let trun = MP4.trun(track, sdtp.byteLength + 16 + 16 + 8 + 16 + 8 + 8);\n\n return MP4.box(MP4.types.traf, tfhd, tfdt, trun, sdtp);\n }\n\n // Sample Dependency Type box\n static sdtp(track) {\n let samples = track.samples || [];\n let sampleCount = samples.length;\n let data = new Uint8Array(4 + sampleCount);\n // 0~4 bytes: version(0) & flags\n for (let i = 0; i < sampleCount; i++) {\n let flags = samples[i].flags;\n data[i + 4] = (flags.isLeading << 6) // is_leading: 2 (bit)\n | (flags.dependsOn << 4) // sample_depends_on\n | (flags.isDependedOn << 2) // sample_is_depended_on\n | (flags.hasRedundancy); // sample_has_redundancy\n }\n return MP4.box(MP4.types.sdtp, data);\n }\n\n // Track fragment run box\n static trun(track, offset) {\n let samples = track.samples || [];\n let sampleCount = samples.length;\n let dataSize = 12 + 16 * sampleCount;\n let data = new Uint8Array(dataSize);\n offset += 8 + dataSize;\n\n data.set([\n 0x00, 0x00, 0x0F, 0x01, // version(0) & flags\n (sampleCount >>> 24) & 0xFF, // sample_count\n (sampleCount >>> 16) & 0xFF,\n (sampleCount >>> 8) & 0xFF,\n (sampleCount) & 0xFF,\n (offset >>> 24) & 0xFF, // data_offset\n (offset >>> 16) & 0xFF,\n (offset >>> 8) & 0xFF,\n (offset) & 0xFF\n ], 0);\n\n for (let i = 0; i < sampleCount; i++) {\n let duration = samples[i].duration;\n let size = samples[i].size;\n let flags = samples[i].flags;\n let cts = samples[i].cts;\n data.set([\n (duration >>> 24) & 0xFF, // sample_duration\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n (size >>> 24) & 0xFF, // sample_size\n (size >>> 16) & 0xFF,\n (size >>> 8) & 0xFF,\n (size) & 0xFF,\n (flags.isLeading << 2) | flags.dependsOn, // sample_flags\n (flags.isDependedOn << 6) | (flags.hasRedundancy << 4) | flags.isNonSync,\n 0x00, 0x00, // sample_degradation_priority\n (cts >>> 24) & 0xFF, // sample_composition_time_offset\n (cts >>> 16) & 0xFF,\n (cts >>> 8) & 0xFF,\n (cts) & 0xFF\n ], 12 + 16 * i);\n }\n return MP4.box(MP4.types.trun, data);\n }\n\n static mdat(data) {\n return MP4.box(MP4.types.mdat, data);\n }\n\n}\n\nMP4.init();\n\nexport default MP4;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport MP4 from './mp4-generator.js';\nimport AAC from './aac-silent.js';\nimport Browser from '../utils/browser.js';\nimport {SampleInfo, MediaSegmentInfo, MediaSegmentInfoList} from '../core/media-segment-info.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\n\n// Fragmented mp4 remuxer\nclass MP4Remuxer {\n\n constructor(config) {\n this.TAG = 'MP4Remuxer';\n\n this._config = config;\n this._isLive = (config.isLive === true) ? true : false;\n\n this._dtsBase = -1;\n this._dtsBaseInited = false;\n this._audioDtsBase = Infinity;\n this._videoDtsBase = Infinity;\n this._audioNextDts = undefined;\n this._videoNextDts = undefined;\n\n this._audioMeta = null;\n this._videoMeta = null;\n\n this._audioSegmentInfoList = new MediaSegmentInfoList('audio');\n this._videoSegmentInfoList = new MediaSegmentInfoList('video');\n\n this._onInitSegment = null;\n this._onMediaSegment = null;\n\n // Workaround for chrome < 50: Always force first sample as a Random Access Point in media segment\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412\n this._forceFirstIDR = (Browser.chrome &&\n (Browser.version.major < 50 ||\n (Browser.version.major === 50 && Browser.version.build < 2661))) ? true : false;\n\n // Workaround for IE11/Edge: Fill silent aac frame after keyframe-seeking\n // Make audio beginDts equals with video beginDts, in order to fix seek freeze\n this._fillSilentAfterSeek = (Browser.msedge || Browser.msie);\n\n // While only FireFox supports 'audio/mp4, codecs=\"mp3\"', use 'audio/mpeg' for chrome, safari, ...\n this._mp3UseMpegAudio = !Browser.firefox;\n\n this._fillAudioTimestampGap = this._config.fixAudioTimestampGap;\n }\n\n destroy() {\n this._dtsBase = -1;\n this._dtsBaseInited = false;\n this._audioMeta = null;\n this._videoMeta = null;\n this._audioSegmentInfoList.clear();\n this._audioSegmentInfoList = null;\n this._videoSegmentInfoList.clear();\n this._videoSegmentInfoList = null;\n this._onInitSegment = null;\n this._onMediaSegment = null;\n }\n\n bindDataSource(producer) {\n producer.onDataAvailable = this.remux.bind(this);\n producer.onTrackMetadata = this._onTrackMetadataReceived.bind(this);\n return this;\n }\n\n /* prototype: function onInitSegment(type: string, initSegment: ArrayBuffer): void\n InitSegment: {\n type: string,\n data: ArrayBuffer,\n codec: string,\n container: string\n }\n */\n get onInitSegment() {\n return this._onInitSegment;\n }\n\n set onInitSegment(callback) {\n this._onInitSegment = callback;\n }\n\n /* prototype: function onMediaSegment(type: string, mediaSegment: MediaSegment): void\n MediaSegment: {\n type: string,\n data: ArrayBuffer,\n sampleCount: int32\n info: MediaSegmentInfo\n }\n */\n get onMediaSegment() {\n return this._onMediaSegment;\n }\n\n set onMediaSegment(callback) {\n this._onMediaSegment = callback;\n }\n\n insertDiscontinuity() {\n this._audioNextDts = this._videoNextDts = undefined;\n }\n\n seek(originalDts) {\n this._videoSegmentInfoList.clear();\n this._audioSegmentInfoList.clear();\n }\n\n remux(audioTrack, videoTrack) {\n if (!this._onMediaSegment) {\n throw new IllegalStateException('MP4Remuxer: onMediaSegment callback must be specificed!');\n }\n if (!this._dtsBaseInited) {\n this._calculateDtsBase(audioTrack, videoTrack);\n }\n this._remuxVideo(videoTrack);\n this._remuxAudio(audioTrack);\n }\n\n _onTrackMetadataReceived(type, metadata) {\n let metabox = null;\n\n let container = 'mp4';\n let codec = metadata.codec;\n\n if (type === 'audio') {\n this._audioMeta = metadata;\n if (metadata.codec === 'mp3' && this._mp3UseMpegAudio) {\n // 'audio/mpeg' for MP3 audio track\n container = 'mpeg';\n codec = '';\n metabox = new Uint8Array();\n } else {\n // 'audio/mp4, codecs=\"codec\"'\n metabox = MP4.generateInitSegment(metadata);\n }\n } else if (type === 'video') {\n this._videoMeta = metadata;\n metabox = MP4.generateInitSegment(metadata);\n } else {\n return;\n }\n\n // dispatch metabox (Initialization Segment)\n if (!this._onInitSegment) {\n throw new IllegalStateException('MP4Remuxer: onInitSegment callback must be specified!');\n }\n this._onInitSegment(type, {\n type: type,\n data: metabox.buffer,\n codec: codec,\n container: `${type}/${container}`,\n mediaDuration: metadata.duration // in timescale 1000 (milliseconds)\n });\n }\n\n _calculateDtsBase(audioTrack, videoTrack) {\n if (this._dtsBaseInited) {\n return;\n }\n\n if (audioTrack.samples && audioTrack.samples.length) {\n this._audioDtsBase = audioTrack.samples[0].dts;\n }\n if (videoTrack.samples && videoTrack.samples.length) {\n this._videoDtsBase = videoTrack.samples[0].dts;\n }\n\n this._dtsBase = Math.min(this._audioDtsBase, this._videoDtsBase);\n this._dtsBaseInited = true;\n }\n\n _remuxAudio(audioTrack) {\n if (this._audioMeta == null) {\n return;\n }\n\n let track = audioTrack;\n let samples = track.samples;\n let dtsCorrection = undefined;\n let firstDts = -1, lastDts = -1, lastPts = -1;\n let refSampleDuration = this._audioMeta.refSampleDuration;\n\n let mpegRawTrack = this._audioMeta.codec === 'mp3' && this._mp3UseMpegAudio;\n let firstSegmentAfterSeek = this._dtsBaseInited && this._audioNextDts === undefined;\n\n let insertPrefixSilentFrame = false;\n\n if (!samples || samples.length === 0) {\n return;\n }\n\n let offset = 0;\n let mdatbox = null;\n let mdatBytes = 0;\n\n // calculate initial mdat size\n if (mpegRawTrack) {\n // for raw mpeg buffer\n offset = 0;\n mdatBytes = track.length;\n } else {\n // for fmp4 mdat box\n offset = 8; // size + type\n mdatBytes = 8 + track.length;\n }\n\n let firstSampleOriginalDts = samples[0].dts - this._dtsBase;\n\n // calculate dtsCorrection\n if (this._audioNextDts) {\n dtsCorrection = firstSampleOriginalDts - this._audioNextDts;\n } else { // this._audioNextDts == undefined\n if (this._audioSegmentInfoList.isEmpty()) {\n dtsCorrection = 0;\n if (this._fillSilentAfterSeek && !this._videoSegmentInfoList.isEmpty()) {\n if (this._audioMeta.originalCodec !== 'mp3') {\n insertPrefixSilentFrame = true;\n }\n }\n } else {\n let lastSample = this._audioSegmentInfoList.getLastSampleBefore(firstSampleOriginalDts);\n if (lastSample != null) {\n let distance = (firstSampleOriginalDts - (lastSample.originalDts + lastSample.duration));\n if (distance <= 3) {\n distance = 0;\n }\n let expectedDts = lastSample.dts + lastSample.duration + distance;\n dtsCorrection = firstSampleOriginalDts - expectedDts;\n } else { // lastSample == null, cannot found\n dtsCorrection = 0;\n }\n }\n }\n\n if (insertPrefixSilentFrame) {\n // align audio segment beginDts to match with current video segment's beginDts\n let firstSampleDts = firstSampleOriginalDts - dtsCorrection;\n let videoSegment = this._videoSegmentInfoList.getLastSegmentBefore(firstSampleOriginalDts);\n if (videoSegment != null && videoSegment.beginDts < firstSampleDts) {\n let silentUnit = AAC.getSilentFrame(this._audioMeta.originalCodec, this._audioMeta.channelCount);\n if (silentUnit) {\n let dts = videoSegment.beginDts;\n let silentFrameDuration = firstSampleDts - videoSegment.beginDts;\n Log.v(this.TAG, `InsertPrefixSilentAudio: dts: ${dts}, duration: ${silentFrameDuration}`);\n samples.unshift({unit: silentUnit, dts: dts, pts: dts});\n mdatBytes += silentUnit.byteLength;\n } // silentUnit == null: Cannot generate, skip\n } else {\n insertPrefixSilentFrame = false;\n }\n }\n\n let mp4Samples = [];\n\n // Correct dts for each sample, and calculate sample duration. Then output to mp4Samples\n for (let i = 0; i < samples.length; i++) {\n let sample = samples[i];\n let unit = sample.unit;\n let originalDts = sample.dts - this._dtsBase;\n let dts = originalDts - dtsCorrection;\n\n if (firstDts === -1) {\n firstDts = dts;\n }\n\n let sampleDuration = 0;\n\n if (i !== samples.length - 1) {\n let nextDts = samples[i + 1].dts - this._dtsBase - dtsCorrection;\n sampleDuration = nextDts - dts;\n } else { // the last sample\n if (mp4Samples.length >= 1) { // use second last sample duration\n sampleDuration = mp4Samples[mp4Samples.length - 1].duration;\n } else { // the only one sample, use reference sample duration\n sampleDuration = Math.floor(refSampleDuration);\n }\n }\n\n let needFillSilentFrames = false;\n let silentFrames = null;\n\n // Silent frame generation, if large timestamp gap detected && config.fixAudioTimestampGap\n if (sampleDuration > refSampleDuration * 1.5 && this._audioMeta.codec !== 'mp3' && this._fillAudioTimestampGap && !Browser.safari) {\n // We need to insert silent frames to fill timestamp gap\n needFillSilentFrames = true;\n let delta = Math.abs(sampleDuration - refSampleDuration);\n let frameCount = Math.ceil(delta / refSampleDuration);\n let currentDts = dts + refSampleDuration; // Notice: in float\n\n Log.w(this.TAG, 'Large audio timestamp gap detected, may cause AV sync to drift. ' +\n 'Silent frames will be generated to avoid unsync.\\n' +\n `dts: ${dts + sampleDuration} ms, expected: ${dts + Math.round(refSampleDuration)} ms, ` +\n `delta: ${Math.round(delta)} ms, generate: ${frameCount} frames`);\n\n let silentUnit = AAC.getSilentFrame(this._audioMeta.originalCodec, this._audioMeta.channelCount);\n if (silentUnit == null) {\n Log.w(this.TAG, 'Unable to generate silent frame for ' +\n `${this._audioMeta.originalCodec} with ${this._audioMeta.channelCount} channels, repeat last frame`);\n // Repeat last frame\n silentUnit = unit;\n }\n silentFrames = [];\n\n for (let j = 0; j < frameCount; j++) {\n let intDts = Math.round(currentDts); // round to integer\n if (silentFrames.length > 0) {\n // Set previous frame sample duration\n let previousFrame = silentFrames[silentFrames.length - 1];\n previousFrame.duration = intDts - previousFrame.dts;\n }\n let frame = {\n dts: intDts,\n pts: intDts,\n cts: 0,\n unit: silentUnit,\n size: silentUnit.byteLength,\n duration: 0, // wait for next sample\n originalDts: originalDts,\n flags: {\n isLeading: 0,\n dependsOn: 1,\n isDependedOn: 0,\n hasRedundancy: 0\n }\n };\n silentFrames.push(frame);\n mdatBytes += unit.byteLength;\n currentDts += refSampleDuration;\n }\n\n // last frame: align end time to next frame dts\n let lastFrame = silentFrames[silentFrames.length - 1];\n lastFrame.duration = dts + sampleDuration - lastFrame.dts;\n\n // silentFrames.forEach((frame) => {\n // Log.w(this.TAG, `SilentAudio: dts: ${frame.dts}, duration: ${frame.duration}`);\n // });\n\n // Set correct sample duration for current frame\n sampleDuration = Math.round(refSampleDuration);\n }\n\n mp4Samples.push({\n dts: dts,\n pts: dts,\n cts: 0,\n unit: sample.unit,\n size: sample.unit.byteLength,\n duration: sampleDuration,\n originalDts: originalDts,\n flags: {\n isLeading: 0,\n dependsOn: 1,\n isDependedOn: 0,\n hasRedundancy: 0\n }\n });\n\n if (needFillSilentFrames) {\n // Silent frames should be inserted after wrong-duration frame\n mp4Samples.push.apply(mp4Samples, silentFrames);\n }\n }\n\n // allocate mdatbox\n if (mpegRawTrack) {\n // allocate for raw mpeg buffer\n mdatbox = new Uint8Array(mdatBytes);\n } else {\n // allocate for fmp4 mdat box\n mdatbox = new Uint8Array(mdatBytes);\n // size field\n mdatbox[0] = (mdatBytes >>> 24) & 0xFF;\n mdatbox[1] = (mdatBytes >>> 16) & 0xFF;\n mdatbox[2] = (mdatBytes >>> 8) & 0xFF;\n mdatbox[3] = (mdatBytes) & 0xFF;\n // type field (fourCC)\n mdatbox.set(MP4.types.mdat, 4);\n }\n\n // Write samples into mdatbox\n for (let i = 0; i < mp4Samples.length; i++) {\n let unit = mp4Samples[i].unit;\n mdatbox.set(unit, offset);\n offset += unit.byteLength;\n }\n\n let latest = mp4Samples[mp4Samples.length - 1];\n lastDts = latest.dts + latest.duration;\n this._audioNextDts = lastDts;\n\n // fill media segment info & add to info list\n let info = new MediaSegmentInfo();\n info.beginDts = firstDts;\n info.endDts = lastDts;\n info.beginPts = firstDts;\n info.endPts = lastDts;\n info.originalBeginDts = mp4Samples[0].originalDts;\n info.originalEndDts = latest.originalDts + latest.duration;\n info.firstSample = new SampleInfo(mp4Samples[0].dts,\n mp4Samples[0].pts,\n mp4Samples[0].duration,\n mp4Samples[0].originalDts,\n false);\n info.lastSample = new SampleInfo(latest.dts,\n latest.pts,\n latest.duration,\n latest.originalDts,\n false);\n if (!this._isLive) {\n this._audioSegmentInfoList.append(info);\n }\n\n track.samples = mp4Samples;\n track.sequenceNumber++;\n\n let moofbox = null;\n\n if (mpegRawTrack) {\n // Generate empty buffer, because useless for raw mpeg\n moofbox = new Uint8Array();\n } else {\n // Generate moof for fmp4 segment\n moofbox = MP4.moof(track, firstDts);\n }\n\n track.samples = [];\n track.length = 0;\n\n let segment = {\n type: 'audio',\n data: this._mergeBoxes(moofbox, mdatbox).buffer,\n sampleCount: mp4Samples.length,\n info: info\n };\n\n if (mpegRawTrack && firstSegmentAfterSeek) {\n // For MPEG audio stream in MSE, if seeking occurred, before appending new buffer\n // We need explicitly set timestampOffset to the desired point in timeline for mpeg SourceBuffer.\n segment.timestampOffset = firstDts;\n }\n\n this._onMediaSegment('audio', segment);\n }\n\n _remuxVideo(videoTrack) {\n if (this._videoMeta == null) {\n return;\n }\n\n let track = videoTrack;\n let samples = track.samples;\n let dtsCorrection = undefined;\n let firstDts = -1, lastDts = -1;\n let firstPts = -1, lastPts = -1;\n\n if (!samples || samples.length === 0) {\n return;\n }\n\n let offset = 8;\n let mdatBytes = 8 + videoTrack.length;\n let mdatbox = new Uint8Array(mdatBytes);\n mdatbox[0] = (mdatBytes >>> 24) & 0xFF;\n mdatbox[1] = (mdatBytes >>> 16) & 0xFF;\n mdatbox[2] = (mdatBytes >>> 8) & 0xFF;\n mdatbox[3] = (mdatBytes) & 0xFF;\n mdatbox.set(MP4.types.mdat, 4);\n\n let firstSampleOriginalDts = samples[0].dts - this._dtsBase;\n\n // calculate dtsCorrection\n if (this._videoNextDts) {\n dtsCorrection = firstSampleOriginalDts - this._videoNextDts;\n } else { // this._videoNextDts == undefined\n if (this._videoSegmentInfoList.isEmpty()) {\n dtsCorrection = 0;\n } else {\n let lastSample = this._videoSegmentInfoList.getLastSampleBefore(firstSampleOriginalDts);\n if (lastSample != null) {\n let distance = (firstSampleOriginalDts - (lastSample.originalDts + lastSample.duration));\n if (distance <= 3) {\n distance = 0;\n }\n let expectedDts = lastSample.dts + lastSample.duration + distance;\n dtsCorrection = firstSampleOriginalDts - expectedDts;\n } else { // lastSample == null, cannot found\n dtsCorrection = 0;\n }\n }\n }\n\n let info = new MediaSegmentInfo();\n let mp4Samples = [];\n\n // Correct dts for each sample, and calculate sample duration. Then output to mp4Samples\n for (let i = 0; i < samples.length; i++) {\n let sample = samples[i];\n let originalDts = sample.dts - this._dtsBase;\n let isKeyframe = sample.isKeyframe;\n let dts = originalDts - dtsCorrection;\n let cts = sample.cts;\n let pts = dts + cts;\n\n if (firstDts === -1) {\n firstDts = dts;\n firstPts = pts;\n }\n\n let sampleDuration = 0;\n\n if (i !== samples.length - 1) {\n let nextDts = samples[i + 1].dts - this._dtsBase - dtsCorrection;\n sampleDuration = nextDts - dts;\n } else { // the last sample\n if (mp4Samples.length >= 1) { // use second last sample duration\n sampleDuration = mp4Samples[mp4Samples.length - 1].duration;\n } else { // the only one sample, use reference sample duration\n sampleDuration = Math.floor(this._videoMeta.refSampleDuration);\n }\n }\n\n if (isKeyframe) {\n let syncPoint = new SampleInfo(dts, pts, sampleDuration, sample.dts, true);\n syncPoint.fileposition = sample.fileposition;\n info.appendSyncPoint(syncPoint);\n }\n\n mp4Samples.push({\n dts: dts,\n pts: pts,\n cts: cts,\n units: sample.units,\n size: sample.length,\n isKeyframe: isKeyframe,\n duration: sampleDuration,\n originalDts: originalDts,\n flags: {\n isLeading: 0,\n dependsOn: isKeyframe ? 2 : 1,\n isDependedOn: isKeyframe ? 1 : 0,\n hasRedundancy: 0,\n isNonSync: isKeyframe ? 0 : 1\n }\n });\n }\n\n // Write samples into mdatbox\n for (let i = 0; i < mp4Samples.length; i++) {\n let units = mp4Samples[i].units;\n while (units.length) {\n let unit = units.shift();\n let data = unit.data;\n mdatbox.set(data, offset);\n offset += data.byteLength;\n }\n }\n\n let latest = mp4Samples[mp4Samples.length - 1];\n lastDts = latest.dts + latest.duration;\n lastPts = latest.pts + latest.duration;\n this._videoNextDts = lastDts;\n\n // fill media segment info & add to info list\n info.beginDts = firstDts;\n info.endDts = lastDts;\n info.beginPts = firstPts;\n info.endPts = lastPts;\n info.originalBeginDts = mp4Samples[0].originalDts;\n info.originalEndDts = latest.originalDts + latest.duration;\n info.firstSample = new SampleInfo(mp4Samples[0].dts,\n mp4Samples[0].pts,\n mp4Samples[0].duration,\n mp4Samples[0].originalDts,\n mp4Samples[0].isKeyframe);\n info.lastSample = new SampleInfo(latest.dts,\n latest.pts,\n latest.duration,\n latest.originalDts,\n latest.isKeyframe);\n if (!this._isLive) {\n this._videoSegmentInfoList.append(info);\n }\n\n track.samples = mp4Samples;\n track.sequenceNumber++;\n\n // workaround for chrome < 50: force first sample as a random access point\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412\n if (this._forceFirstIDR) {\n let flags = mp4Samples[0].flags;\n flags.dependsOn = 2;\n flags.isNonSync = 0;\n }\n\n let moofbox = MP4.moof(track, firstDts);\n track.samples = [];\n track.length = 0;\n\n this._onMediaSegment('video', {\n type: 'video',\n data: this._mergeBoxes(moofbox, mdatbox).buffer,\n sampleCount: mp4Samples.length,\n info: info\n });\n }\n\n _mergeBoxes(moof, mdat) {\n let result = new Uint8Array(moof.byteLength + mdat.byteLength);\n result.set(moof, 0);\n result.set(mdat, moof.byteLength);\n return result;\n }\n\n}\n\nexport default MP4Remuxer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nlet Browser = {};\n\nfunction detect() {\n // modified from jquery-browser-plugin\n\n let ua = self.navigator.userAgent.toLowerCase();\n\n let match = /(edge)\\/([\\w.]+)/.exec(ua) ||\n /(opr)[\\/]([\\w.]+)/.exec(ua) ||\n /(chrome)[ \\/]([\\w.]+)/.exec(ua) ||\n /(iemobile)[\\/]([\\w.]+)/.exec(ua) ||\n /(version)(applewebkit)[ \\/]([\\w.]+).*(safari)[ \\/]([\\w.]+)/.exec(ua) ||\n /(webkit)[ \\/]([\\w.]+).*(version)[ \\/]([\\w.]+).*(safari)[ \\/]([\\w.]+)/.exec(ua) ||\n /(webkit)[ \\/]([\\w.]+)/.exec(ua) ||\n /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec(ua) ||\n /(msie) ([\\w.]+)/.exec(ua) ||\n ua.indexOf('trident') >= 0 && /(rv)(?::| )([\\w.]+)/.exec(ua) ||\n ua.indexOf('compatible') < 0 && /(firefox)[ \\/]([\\w.]+)/.exec(ua) ||\n [];\n\n let platform_match = /(ipad)/.exec(ua) ||\n /(ipod)/.exec(ua) ||\n /(windows phone)/.exec(ua) ||\n /(iphone)/.exec(ua) ||\n /(kindle)/.exec(ua) ||\n /(android)/.exec(ua) ||\n /(windows)/.exec(ua) ||\n /(mac)/.exec(ua) ||\n /(linux)/.exec(ua) ||\n /(cros)/.exec(ua) ||\n [];\n\n let matched = {\n browser: match[5] || match[3] || match[1] || '',\n version: match[2] || match[4] || '0',\n majorVersion: match[4] || match[2] || '0',\n platform: platform_match[0] || ''\n };\n\n let browser = {};\n if (matched.browser) {\n browser[matched.browser] = true;\n\n let versionArray = matched.majorVersion.split('.');\n browser.version = {\n major: parseInt(matched.majorVersion, 10),\n string: matched.version\n };\n if (versionArray.length > 1) {\n browser.version.minor = parseInt(versionArray[1], 10);\n }\n if (versionArray.length > 2) {\n browser.version.build = parseInt(versionArray[2], 10);\n }\n }\n\n if (matched.platform) {\n browser[matched.platform] = true;\n }\n\n if (browser.chrome || browser.opr || browser.safari) {\n browser.webkit = true;\n }\n\n // MSIE. IE11 has 'rv' identifer\n if (browser.rv || browser.iemobile) {\n if (browser.rv) {\n delete browser.rv;\n }\n let msie = 'msie';\n matched.browser = msie;\n browser[msie] = true;\n }\n\n // Microsoft Edge\n if (browser.edge) {\n delete browser.edge;\n let msedge = 'msedge';\n matched.browser = msedge;\n browser[msedge] = true;\n }\n\n // Opera 15+\n if (browser.opr) {\n let opera = 'opera';\n matched.browser = opera;\n browser[opera] = true;\n }\n\n // Stock android browsers are marked as Safari\n if (browser.safari && browser.android) {\n let android = 'android';\n matched.browser = android;\n browser[android] = true;\n }\n\n browser.name = matched.browser;\n browser.platform = matched.platform;\n\n for (let key in Browser) {\n if (Browser.hasOwnProperty(key)) {\n delete Browser[key];\n }\n }\n Object.assign(Browser, browser);\n}\n\ndetect();\n\nexport default Browser;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class RuntimeException {\n\n constructor(message) {\n this._message = message;\n }\n\n get name() {\n return 'RuntimeException';\n }\n\n get message() {\n return this._message;\n }\n\n toString() {\n return this.name + ': ' + this.message;\n }\n\n}\n\nexport class IllegalStateException extends RuntimeException {\n\n constructor(message) {\n super(message);\n }\n\n get name() {\n return 'IllegalStateException';\n }\n\n}\n\nexport class InvalidArgumentException extends RuntimeException {\n\n constructor(message) {\n super(message);\n }\n\n get name() {\n return 'InvalidArgumentException';\n }\n\n}\n\nexport class NotImplementedException extends RuntimeException {\n\n constructor(message) {\n super(message);\n }\n\n get name() {\n return 'NotImplementedException';\n }\n\n}\n","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\n\nclass Log {\n\n static e(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'error', str);\n }\n\n if (!Log.ENABLE_ERROR) {\n return;\n }\n\n if (console.error) {\n console.error(str);\n } else if (console.warn) {\n console.warn(str);\n } else {\n console.log(str);\n }\n }\n\n static i(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'info', str);\n }\n\n if (!Log.ENABLE_INFO) {\n return;\n }\n\n if (console.info) {\n console.info(str);\n } else {\n console.log(str);\n }\n }\n\n static w(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'warn', str);\n }\n\n if (!Log.ENABLE_WARN) {\n return;\n }\n\n if (console.warn) {\n console.warn(str);\n } else {\n console.log(str);\n }\n }\n\n static d(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'debug', str);\n }\n\n if (!Log.ENABLE_DEBUG) {\n return;\n }\n\n if (console.debug) {\n console.debug(str);\n } else {\n console.log(str);\n }\n }\n\n static v(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'verbose', str);\n }\n\n if (!Log.ENABLE_VERBOSE) {\n return;\n }\n\n console.log(str);\n }\n\n}\n\nLog.GLOBAL_TAG = 'flv.js';\nLog.FORCE_GLOBAL_TAG = false;\nLog.ENABLE_ERROR = true;\nLog.ENABLE_INFO = true;\nLog.ENABLE_WARN = true;\nLog.ENABLE_DEBUG = true;\nLog.ENABLE_VERBOSE = true;\n\nLog.ENABLE_CALLBACK = false;\n\nLog.emitter = new EventEmitter();\n\nexport default Log;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from './logger.js';\n\nclass LoggingControl {\n\n static get forceGlobalTag() {\n return Log.FORCE_GLOBAL_TAG;\n }\n\n static set forceGlobalTag(enable) {\n Log.FORCE_GLOBAL_TAG = enable;\n LoggingControl._notifyChange();\n }\n\n static get globalTag() {\n return Log.GLOBAL_TAG;\n }\n\n static set globalTag(tag) {\n Log.GLOBAL_TAG = tag;\n LoggingControl._notifyChange();\n }\n\n static get enableAll() {\n return Log.ENABLE_VERBOSE\n && Log.ENABLE_DEBUG\n && Log.ENABLE_INFO\n && Log.ENABLE_WARN\n && Log.ENABLE_ERROR;\n }\n\n static set enableAll(enable) {\n Log.ENABLE_VERBOSE = enable;\n Log.ENABLE_DEBUG = enable;\n Log.ENABLE_INFO = enable;\n Log.ENABLE_WARN = enable;\n Log.ENABLE_ERROR = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableDebug() {\n return Log.ENABLE_DEBUG;\n }\n\n static set enableDebug(enable) {\n Log.ENABLE_DEBUG = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableVerbose() {\n return Log.ENABLE_VERBOSE;\n }\n\n static set enableVerbose(enable) {\n Log.ENABLE_VERBOSE = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableInfo() {\n return Log.ENABLE_INFO;\n }\n\n static set enableInfo(enable) {\n Log.ENABLE_INFO = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableWarn() {\n return Log.ENABLE_WARN;\n }\n\n static set enableWarn(enable) {\n Log.ENABLE_WARN = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableError() {\n return Log.ENABLE_ERROR;\n }\n\n static set enableError(enable) {\n Log.ENABLE_ERROR = enable;\n LoggingControl._notifyChange();\n }\n\n static getConfig() {\n return {\n globalTag: Log.GLOBAL_TAG,\n forceGlobalTag: Log.FORCE_GLOBAL_TAG,\n enableVerbose: Log.ENABLE_VERBOSE,\n enableDebug: Log.ENABLE_DEBUG,\n enableInfo: Log.ENABLE_INFO,\n enableWarn: Log.ENABLE_WARN,\n enableError: Log.ENABLE_ERROR,\n enableCallback: Log.ENABLE_CALLBACK\n };\n }\n\n static applyConfig(config) {\n Log.GLOBAL_TAG = config.globalTag;\n Log.FORCE_GLOBAL_TAG = config.forceGlobalTag;\n Log.ENABLE_VERBOSE = config.enableVerbose;\n Log.ENABLE_DEBUG = config.enableDebug;\n Log.ENABLE_INFO = config.enableInfo;\n Log.ENABLE_WARN = config.enableWarn;\n Log.ENABLE_ERROR = config.enableError;\n Log.ENABLE_CALLBACK = config.enableCallback;\n }\n\n static _notifyChange() {\n let emitter = LoggingControl.emitter;\n\n if (emitter.listenerCount('change') > 0) {\n let config = LoggingControl.getConfig();\n emitter.emit('change', config);\n }\n }\n\n static registerListener(listener) {\n LoggingControl.emitter.addListener('change', listener);\n }\n\n static removeListener(listener) {\n LoggingControl.emitter.removeListener('change', listener);\n }\n\n static addLogListener(listener) {\n Log.emitter.addListener('log', listener);\n if (Log.emitter.listenerCount('log') > 0) {\n Log.ENABLE_CALLBACK = true;\n LoggingControl._notifyChange();\n }\n }\n\n static removeLogListener(listener) {\n Log.emitter.removeListener('log', listener);\n if (Log.emitter.listenerCount('log') === 0) {\n Log.ENABLE_CALLBACK = false;\n LoggingControl._notifyChange();\n }\n }\n\n}\n\nLoggingControl.emitter = new EventEmitter();\n\nexport default LoggingControl;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass Polyfill {\n\n static install() {\n // ES6 Object.setPrototypeOf\n Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {\n obj.__proto__ = proto;\n return obj;\n };\n\n // ES6 Object.assign\n Object.assign = Object.assign || function (target) {\n if (target === undefined || target === null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n let output = Object(target);\n for (let i = 1; i < arguments.length; i++) {\n let source = arguments[i];\n if (source !== undefined && source !== null) {\n for (let key in source) {\n if (source.hasOwnProperty(key)) {\n output[key] = source[key];\n }\n }\n }\n }\n return output;\n };\n\n // ES6 Promise (missing support in IE11)\n if (typeof self.Promise !== 'function') {\n require('es6-promise').polyfill();\n }\n }\n\n}\n\nPolyfill.install();\n\nexport default Polyfill;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * This file is derived from C++ project libWinTF8 (https://github.com/m13253/libWinTF8)\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nfunction checkContinuation(uint8array, start, checkLength) {\n let array = uint8array;\n if (start + checkLength < array.length) {\n while (checkLength--) {\n if ((array[++start] & 0xC0) !== 0x80)\n return false;\n }\n return true;\n } else {\n return false;\n }\n}\n\nfunction decodeUTF8(uint8array) {\n let out = [];\n let input = uint8array;\n let i = 0;\n let length = uint8array.length;\n\n while (i < length) {\n if (input[i] < 0x80) {\n out.push(String.fromCharCode(input[i]));\n ++i;\n continue;\n } else if (input[i] < 0xC0) {\n // fallthrough\n } else if (input[i] < 0xE0) {\n if (checkContinuation(input, i, 1)) {\n let ucs4 = (input[i] & 0x1F) << 6 | (input[i + 1] & 0x3F);\n if (ucs4 >= 0x80) {\n out.push(String.fromCharCode(ucs4 & 0xFFFF));\n i += 2;\n continue;\n }\n }\n } else if (input[i] < 0xF0) {\n if (checkContinuation(input, i, 2)) {\n let ucs4 = (input[i] & 0xF) << 12 | (input[i + 1] & 0x3F) << 6 | input[i + 2] & 0x3F;\n if (ucs4 >= 0x800 && (ucs4 & 0xF800) !== 0xD800) {\n out.push(String.fromCharCode(ucs4 & 0xFFFF));\n i += 3;\n continue;\n }\n }\n } else if (input[i] < 0xF8) {\n if (checkContinuation(input, i, 3)) {\n let ucs4 = (input[i] & 0x7) << 18 | (input[i + 1] & 0x3F) << 12\n | (input[i + 2] & 0x3F) << 6 | (input[i + 3] & 0x3F);\n if (ucs4 > 0x10000 && ucs4 < 0x110000) {\n ucs4 -= 0x10000;\n out.push(String.fromCharCode((ucs4 >>> 10) | 0xD800));\n out.push(String.fromCharCode((ucs4 & 0x3FF) | 0xDC00));\n i += 4;\n continue;\n }\n }\n }\n out.push(String.fromCharCode(0xFFFD));\n ++i;\n }\n\n return out.join('');\n}\n\nexport default decodeUTF8;"]} \ No newline at end of file diff --git a/tools/FLV Stream/index.html b/tools/FLV Stream/index.html new file mode 100644 index 0000000..86dc369 --- /dev/null +++ b/tools/FLV Stream/index.html @@ -0,0 +1,36 @@ + + + + + + + FLV to Web Test by Shinobi Systems + + + + + + + + + \ No newline at end of file diff --git a/tools/MP4 Stream/ffmpegToWeb.js b/tools/MP4 Stream/ffmpegToWeb.js new file mode 100644 index 0000000..23edd5f --- /dev/null +++ b/tools/MP4 Stream/ffmpegToWeb.js @@ -0,0 +1,95 @@ +// Shinobi (http://shinobi.video) - FFMPEG MP4 over HTTP Test +// How to Use +// 1. Navigate to directory where this file is. +// 2. Run `npm install express` +// 3. Start with `node ffmpegToWeb.js` +// 4. Get the IP address of the computer where you did step 1. Example : 127.0.0.1 +// 5. Open `http://127.0.0.1:8001/` in your browser. + +var child = require('child_process'); +var events = require('events'); +var express = require('express') +var app = express(); +var server = require('http').Server(app); +var spawn = child.spawn; +var exec = child.exec; +var Emitters = {} +var firstChunks = {} +var config = { + port:8001, + url:'rtsp://131.95.3.162/axis-media/media.3gp' +} +var initEmitter = function(feed){ + if(!Emitters[feed]){ + Emitters[feed] = new events.EventEmitter().setMaxListeners(0) + } + return Emitters[feed] +} +//hold first chunk of FLV video +var initFirstChunk = function(feed,firstBuffer){ + if(!firstChunks[feed]){ + firstChunks[feed] = firstBuffer + } + return firstChunks[feed] +} +console.log('Starting Express Web Server on Port '+config.port) +//start webserver +server.listen(config.port); + +//make libraries static +app.use('/libs',express.static(__dirname + '/../../web/libs')); +app.use('/',express.static(__dirname + '/')); + +//homepage with video element. +//static file send of index.html +app.get('/', function (req, res) { + res.sendFile(__dirname + '/index.html'); +}) + +//// MP4 Stream over HTTP, this URL goes in the flv.js javascript player +// see ./index.html +app.get('/s.mp4', function (req, res) { + //default to first feed + if(!req.params.feed){req.params.feed='1'} + //get emitter + req.Emitter = initEmitter(req.params.feed) + //variable name of contentWriter + var contentWriter + //set headers + res.setHeader('Content-Type', 'video/mp4'); + res.setHeader('Access-Control-Allow-Origin','*'); + //write first frame on stream + res.write(initFirstChunk(1)) + //write new frames as they happen + req.Emitter.on('data',contentWriter=function(buffer){ + console.log(buffer) + res.write(buffer) + }) + //remove contentWriter when client leaves + res.on('close', function () { + req.Emitter.removeListener('data',contentWriter) + }) +}); + +//ffmpeg +console.log('Starting FFMPEG') +var ffmpegString = '-reorder_queue_size 5 -i '+config.url+' -c:v copy -an -movflags +frag_keyframe+empty_moov+default_base_moof -f mp4 pipe:1' +//var ffmpegString = '-i '+config.url+' -c:v libx264 -preset superfast -tune zerolatency -c:a aac -ar 44100 -f flv pipe:4' +//ffmpegString += ' -f mpegts -c:v mpeg1video -an http://localhost:'+config.port+'/streamIn/2' +if(ffmpegString.indexOf('rtsp://')>-1){ + ffmpegString='-rtsp_transport tcp '+ffmpegString +} +console.log('Executing : ffmpeg '+ffmpegString) +var ffmpeg = spawn('ffmpeg',ffmpegString.split(' '),{stdio:['pipe','pipe','pipe','pipe','pipe']}); +ffmpeg.on('close', function (buffer) { + console.log('ffmpeg died') +}) +//// FFMPEG Error Logs +//ffmpeg.stderr.on('data', function (buffer) { +// console.log(buffer.toString()) +//}); +//data from pipe:1 output of ffmpeg +ffmpeg.stdio[1].on('data', function (buffer) { + initFirstChunk(1,buffer) + initEmitter(1).emit('data',buffer) +}); \ No newline at end of file diff --git a/tools/MP4 Stream/flv.min.js b/tools/MP4 Stream/flv.min.js new file mode 100644 index 0000000..94f1ddc --- /dev/null +++ b/tools/MP4 Stream/flv.min.js @@ -0,0 +1,7 @@ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.flvjs=e()}}(function(){var e;return function e(t,n,i){function r(a,o){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!o&&u)return u(a,!0);if(s)return s(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var d=n[a]={exports:{}};t[a][0].call(d.exports,function(e){var n=t[a][1][e];return r(n||e)},d,d.exports,e,t,n,i)}return n[a].exports}for(var s="function"==typeof require&&require,a=0;a0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},i.prototype.on=i.prototype.addListener,i.prototype.once=function(e,t){function n(){this.removeListener(e,n),i||(i=!0,t.apply(this,arguments))}if(!r(t))throw TypeError("listener must be a function");var i=!1;return n.listener=t,this.on(e,n),this},i.prototype.removeListener=function(e,t){var n,i,s,o;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],s=n.length,i=-1,n===t||r(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(a(n)){for(o=s;o-- >0;)if(n[o]===t||n[o].listener&&n[o].listener===t){i=o;break}if(i<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(i,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},i.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],r(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},i.prototype.listeners=function(e){return this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},i.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(r(t))return 1;if(t)return t.length}return 0},i.listenerCount=function(e,t){return e.listenerCount(t)}},{}],3:[function(e,t,n){function i(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function s(e){if(h===setTimeout)return setTimeout(e,0);if((h===i||!h)&&setTimeout)return h=setTimeout,setTimeout(e,0);try{return h(e,0)}catch(t){try{return h.call(null,e,0)}catch(t){return h.call(this,e,0)}}}function a(e){if(f===clearTimeout)return clearTimeout(e);if((f===r||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(e);try{return f(e)}catch(t){try{return f.call(null,e)}catch(t){return f.call(this,e)}}}function o(){p&&_&&(p=!1,_.length?m=_.concat(m):v=-1,m.length&&u())}function u(){if(!p){var e=s(o);p=!0;for(var t=m.length;t;){for(_=m,m=[];++v1)for(var n=1;n=e[r]&&t0&&e[0].originalDts=t[r].dts&&et[i].lastSample.originalDts&&e=t[i].lastSample.originalDts&&(i===t.length-1||i0&&(r=this._searchNearestSegmentBefore(n.originalBeginDts)+1),this._lastAppendLocation=r,this._list.splice(r,0,n)}},{key:"getLastSegmentBefore",value:function(e){var t=this._searchNearestSegmentBefore(e);return t>=0?this._list[t]:null}},{key:"getLastSampleBefore",value:function(e){var t=this.getLastSegmentBefore(e);return null!=t?t.lastSample:null}},{key:"getLastSyncPointBefore",value:function(e){for(var t=this._searchNearestSegmentBefore(e),n=this._list[t].syncPoints;0===n.length&&t>0;)t--,n=this._list[t].syncPoints;return n.length>0?n[n.length-1]:null}},{key:"type",get:function(){return this._type}},{key:"length",get:function(){return this._list.length}}]),e}()},{}],9:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0&&(i+=";codecs="+n.codec);var r=!1;if(l.default.v(this.TAG,"Received Initialization Segment, mimeType: "+i),this._lastInitSegments[n.type]=n,i!==this._mimeTypes[n.type]){if(this._mimeTypes[n.type])l.default.v(this.TAG,"Notice: "+n.type+" mimeType changed, origin: "+this._mimeTypes[n.type]+", target: "+i);else{r=!0;try{var s=this._sourceBuffers[n.type]=this._mediaSource.addSourceBuffer(i);s.addEventListener("error",this.e.onSourceBufferError),s.addEventListener("updateend",this.e.onSourceBufferUpdateEnd)}catch(e){return l.default.e(this.TAG,e.message),void this._emitter.emit(c.default.ERROR,{code:e.code,msg:e.message})}}this._mimeTypes[n.type]=i}t||this._pendingSegments[n.type].push(n),r||this._sourceBuffers[n.type]&&!this._sourceBuffers[n.type].updating&&this._doAppendSegments(),h.default.safari&&"audio/mpeg"===n.container&&n.mediaDuration>0&&(this._requireSetMediaDuration=!0,this._pendingMediaDuration=n.mediaDuration/1e3,this._updateMediaSourceDuration())}},{key:"appendMediaSegment",value:function(e){var t=e;this._pendingSegments[t.type].push(t),this._config.autoCleanupSourceBuffer&&this._needCleanupSourceBuffer()&&this._doCleanupSourceBuffer();var n=this._sourceBuffers[t.type];!n||n.updating||this._hasPendingRemoveRanges()||this._doAppendSegments()}},{key:"seek",value:function(e){for(var t in this._sourceBuffers)if(this._sourceBuffers[t]){var n=this._sourceBuffers[t];if("open"===this._mediaSource.readyState)try{n.abort()}catch(e){l.default.e(this.TAG,e.message)}this._idrList.clear();var i=this._pendingSegments[t];if(i.splice(0,i.length),"closed"!==this._mediaSource.readyState){for(var r=0;r=1&&e-i.start(0)>=this._config.autoCleanupMaxBackwardDuration)return!0}}return!1}},{key:"_doCleanupSourceBuffer",value:function(){var e=this._mediaElement.currentTime;for(var t in this._sourceBuffers){var n=this._sourceBuffers[t];if(n){for(var i=n.buffered,r=!1,s=0;s=this._config.autoCleanupMaxBackwardDuration){r=!0;var u=e-this._config.autoCleanupMinBackwardDuration;this._pendingRemoveRanges[t].push({start:a,end:u})}}else o0&&(isNaN(t)||n>t)&&(l.default.v(this.TAG,"Update MediaSource duration from "+t+" to "+n),this._mediaSource.duration=n),this._requireSetMediaDuration=!1,this._pendingMediaDuration=0}}},{key:"_doRemoveRanges",value:function(){for(var e in this._pendingRemoveRanges)if(this._sourceBuffers[e]&&!this._sourceBuffers[e].updating)for(var t=this._sourceBuffers[e],n=this._pendingRemoveRanges[e];n.length&&!t.updating;){var i=n.shift();t.remove(i.start,i.end)}}},{key:"_doAppendSegments",value:function(){var e=this._pendingSegments;for(var t in e)if(this._sourceBuffers[t]&&!this._sourceBuffers[t].updating&&e[t].length>0){var n=e[t].shift();if(n.timestampOffset){var i=this._sourceBuffers[t].timestampOffset,r=n.timestampOffset/1e3,s=Math.abs(i-r);s>.1&&(l.default.v(this.TAG,"Update MPEG audio timestampOffset from "+i+" to "+r),this._sourceBuffers[t].timestampOffset=r),delete n.timestampOffset}if(!n.data||0===n.data.byteLength)continue;try{this._sourceBuffers[t].appendBuffer(n.data),this._isBufferFull=!1,"video"===t&&n.hasOwnProperty("info")&&this._idrList.appendArray(n.info.syncPoints)}catch(e){this._pendingSegments[t].unshift(n),22===e.code?(this._isBufferFull||this._emitter.emit(c.default.BUFFER_FULL),this._isBufferFull=!0):(l.default.e(this.TAG,e.message),this._emitter.emit(c.default.ERROR,{code:e.code,msg:e.message}))}}}},{key:"_onSourceOpen",value:function(){if(l.default.v(this.TAG,"MediaSource onSourceOpen"),this._mediaSource.removeEventListener("sourceopen",this.e.onSourceOpen),this._pendingSourceBufferInit.length>0)for(var e=this._pendingSourceBufferInit;e.length;){var t=e.shift();this.appendInitSegment(t,!0)}this._hasPendingSegments()&&this._doAppendSegments(),this._emitter.emit(c.default.SOURCE_OPEN)}},{key:"_onSourceEnded",value:function(){l.default.v(this.TAG,"MediaSource onSourceEnded")}},{key:"_onSourceClose",value:function(){l.default.v(this.TAG,"MediaSource onSourceClose"),this._mediaSource&&null!=this.e&&(this._mediaSource.removeEventListener("sourceopen",this.e.onSourceOpen),this._mediaSource.removeEventListener("sourceended",this.e.onSourceEnded),this._mediaSource.removeEventListener("sourceclose",this.e.onSourceClose))}},{key:"_hasPendingSegments",value:function(){var e=this._pendingSegments;return e.video.length>0||e.audio.length>0}},{key:"_hasPendingRemoveRanges",value:function(){var e=this._pendingRemoveRanges;return e.video.length>0||e.audio.length>0}},{key:"_onSourceBufferUpdateEnd",value:function(){this._requireSetMediaDuration?this._updateMediaSourceDuration():this._hasPendingRemoveRanges()?this._doRemoveRanges():this._hasPendingSegments()?this._doAppendSegments():this._hasPendingEos&&this.endOfStream(),this._emitter.emit(c.default.UPDATE_END)}},{key:"_onSourceBufferError",value:function(e){l.default.e(this.TAG,"SourceBuffer Error: "+e)}}]),e}();n.default=p},{"../utils/browser.js":39,"../utils/exception.js":40,"../utils/logger.js":41,"./media-segment-info.js":8,"./mse-events.js":10,events:2}],10:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i={ERROR:"error",SOURCE_OPEN:"source_open",UPDATE_END:"update_end",BUFFER_FULL:"buffer_full"};n.default=i},{}],11:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0)this._demuxer.bindDataSource(this._ioctl),this._demuxer.timestampBase=this._mediaDataSource.segments[this._currentSegmentIndex].timestampBase,r=this._demuxer.parseChunks(e,t);else if((i=m.default.probe(e)).match){this._demuxer=new m.default(i,this._config),this._remuxer||(this._remuxer=new v.default(this._config));var s=this._mediaDataSource;void 0==s.duration||isNaN(s.duration)||(this._demuxer.overridedDuration=s.duration),"boolean"==typeof s.hasAudio&&(this._demuxer.overridedHasAudio=s.hasAudio),"boolean"==typeof s.hasVideo&&(this._demuxer.overridedHasVideo=s.hasVideo),this._demuxer.timestampBase=s.segments[this._currentSegmentIndex].timestampBase,this._demuxer.onError=this._onDemuxException.bind(this),this._demuxer.onMediaInfo=this._onMediaInfo.bind(this),this._remuxer.bindDataSource(this._demuxer.bindDataSource(this._ioctl)),this._remuxer.onInitSegment=this._onRemuxerInitSegmentArrival.bind(this),this._remuxer.onMediaSegment=this._onRemuxerMediaSegmentArrival.bind(this),r=this._demuxer.parseChunks(e,t)}else i=null,l.default.e(this.TAG,"Non-FLV, Unsupported media type!"),Promise.resolve().then(function(){n._internalAbort()}),this._emitter.emit(k.default.DEMUX_ERROR,y.default.FORMAT_UNSUPPORTED,"Non-FLV, Unsupported media type"),r=0;return r}},{key:"_onMediaInfo",value:function(e){var t=this;null==this._mediaInfo&&(this._mediaInfo=Object.assign({},e),this._mediaInfo.keyframesIndex=null,this._mediaInfo.segments=[],this._mediaInfo.segmentCount=this._mediaDataSource.segments.length,Object.setPrototypeOf(this._mediaInfo,c.default.prototype));var n=Object.assign({},e);Object.setPrototypeOf(n,c.default.prototype),this._mediaInfo.segments[this._currentSegmentIndex]=n,this._reportSegmentMediaInfo(this._currentSegmentIndex),null!=this._pendingSeekTime&&Promise.resolve().then(function(){var e=t._pendingSeekTime;t._pendingSeekTime=null,t.seek(e)})}},{key:"_onIOSeeked",value:function(){this._remuxer.insertDiscontinuity()}},{key:"_onIOComplete",value:function(e){var t=e,n=t+1;n0&&n[0].originalDts===i&&(i=n[0].pts),this._emitter.emit(k.default.RECOMMEND_SEEKPOINT,i)}}},{key:"_enableStatisticsReporter",value:function(){null==this._statisticsReporter&&(this._statisticsReporter=self.setInterval(this._reportStatisticsInfo.bind(this),this._config.statisticsInfoReportInterval))}},{key:"_disableStatisticsReporter",value:function(){this._statisticsReporter&&(self.clearInterval(this._statisticsReporter),this._statisticsReporter=null)}},{key:"_reportSegmentMediaInfo",value:function(e){var t=this._mediaInfo.segments[e],n=Object.assign({},t);n.duration=this._mediaInfo.duration,n.segmentCount=this._mediaInfo.segmentCount,delete n.segments,delete n.keyframesIndex,this._emitter.emit(k.default.MEDIA_INFO,n)}},{key:"_reportStatisticsInfo",value:function(){var e={};e.url=this._ioctl.currentURL,e.hasRedirect=this._ioctl.hasRedirect,e.hasRedirect&&(e.redirectedURL=this._ioctl.currentRedirectedURL),e.speed=this._ioctl.currentSpeed,e.loaderType=this._ioctl.loaderType,e.currentSegmentIndex=this._currentSegmentIndex,e.totalSegmentCount=this._mediaDataSource.segments.length,this._emitter.emit(k.default.STATISTICS_INFO,e)}}]),e}());n.default=L},{"../demux/demux-errors.js":16,"../demux/flv-demuxer.js":18,"../io/io-controller.js":23,"../io/loader.js":24,"../remux/mp4-remuxer.js":38,"../utils/browser.js":39,"../utils/logger.js":41,"./media-info.js":7,"./transmuxing-events.js":13,events:2}],13:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i={IO_ERROR:"io_error",DEMUX_ERROR:"demux_error",INIT_SEGMENT:"init_segment",MEDIA_SEGMENT:"media_segment",LOADING_COMPLETE:"loading_complete",RECOVERED_EARLY_EOF:"recovered_early_eof",MEDIA_INFO:"media_info",STATISTICS_INFO:"statistics_info",RECOMMEND_SEEKPOINT:"recommend_seekpoint"};n.default=i},{}],14:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(n,"__esModule",{value:!0});var r=e("../utils/logger.js"),s=(i(r),e("../utils/logging-control.js")),a=i(s),o=e("../utils/polyfill.js"),u=i(o),l=e("./transmuxing-controller.js"),d=i(l),h=e("./transmuxing-events.js"),f=i(h),c=function(e){function t(t,n){var i={msg:f.default.INIT_SEGMENT,data:{type:t,data:n}};e.postMessage(i,[n.data])}function n(t,n){var i={msg:f.default.MEDIA_SEGMENT,data:{type:t,data:n}};e.postMessage(i,[n.data])}function i(){var t={msg:f.default.LOADING_COMPLETE};e.postMessage(t)}function r(){var t={msg:f.default.RECOVERED_EARLY_EOF};e.postMessage(t)}function s(t){var n={msg:f.default.MEDIA_INFO,data:t};e.postMessage(n)}function o(t){var n={msg:f.default.STATISTICS_INFO,data:t};e.postMessage(n)}function l(t,n){e.postMessage({msg:f.default.IO_ERROR,data:{type:t,info:n}})}function h(t,n){e.postMessage({msg:f.default.DEMUX_ERROR,data:{type:t,info:n}})}function c(t){e.postMessage({msg:f.default.RECOMMEND_SEEKPOINT,data:t})}function _(t,n){e.postMessage({msg:"logcat_callback",data:{type:t,logcat:n}})}var m=null,p=_.bind(this);u.default.install(),e.addEventListener("message",function(u){switch(u.data.cmd){case"init":m=new d.default(u.data.param[0],u.data.param[1]),m.on(f.default.IO_ERROR,l.bind(this)),m.on(f.default.DEMUX_ERROR,h.bind(this)),m.on(f.default.INIT_SEGMENT,t.bind(this)),m.on(f.default.MEDIA_SEGMENT,n.bind(this)),m.on(f.default.LOADING_COMPLETE,i.bind(this)),m.on(f.default.RECOVERED_EARLY_EOF,r.bind(this)),m.on(f.default.MEDIA_INFO,s.bind(this)),m.on(f.default.STATISTICS_INFO,o.bind(this)),m.on(f.default.RECOMMEND_SEEKPOINT,c.bind(this));break;case"destroy":m&&(m.destroy(),m=null),e.postMessage({msg:"destroyed"});break;case"start":m.start();break;case"stop":m.stop();break;case"seek":m.seek(u.data.param);break;case"pause":m.pause();break;case"resume":m.resume();break;case"logging_config":var _=u.data.param;a.default.applyConfig(_),!0===_.enableCallback?a.default.addLogListener(p):a.default.removeLogListener(p)}})};n.default=c},{"../utils/logger.js":41,"../utils/logging-control.js":42,"../utils/polyfill.js":43,"./transmuxing-controller.js":12,"./transmuxing-events.js":13}],15:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0?(0,l.default)(new Uint8Array(e,t+2,r)):"",{data:s,size:2+r}}},{key:"parseLongString",value:function(e,t,n){if(n<4)throw new d.IllegalStateException("Data not enough when parse LongString");var i=new DataView(e,t,n),r=i.getUint32(0,!h),s=void 0;return s=r>0?(0,l.default)(new Uint8Array(e,t+4,r)):"",{data:s,size:4+r}}},{key:"parseDate",value:function(e,t,n){if(n<10)throw new d.IllegalStateException("Data size invalid when parse Date");var i=new DataView(e,t,n),r=i.getFloat64(0,!h);return r+=60*i.getInt16(8,!h)*1e3,{data:new Date(r),size:10}}},{key:"parseValue",value:function(t,n,i){if(i<1)throw new d.IllegalStateException("Data not enough when parse Value");var r=new DataView(t,n,i),s=1,a=r.getUint8(0),u=void 0,l=!1;try{switch(a){case 0:u=r.getFloat64(1,!h),s+=8;break;case 1:u=!!r.getUint8(1),s+=1;break;case 2:var f=e.parseString(t,n+1,i-1);u=f.data,s+=f.size;break;case 3:u={};var c=0;for(9==(16777215&r.getUint32(i-4,!h))&&(c=3);s32)throw new s.InvalidArgumentException("ExpGolomb: readBits() bits exceeded max 32bits!");if(e<=this._current_word_bits_left){var t=this._current_word>>>32-e;return this._current_word<<=e,this._current_word_bits_left-=e,t}var n=this._current_word_bits_left?this._current_word:0;n>>>=32-this._current_word_bits_left;var i=e-this._current_word_bits_left;this._fillCurrentWord();var r=Math.min(i,this._current_word_bits_left),a=this._current_word>>>32-r;return this._current_word<<=r,this._current_word_bits_left-=r,n=n<>>e))return this._current_word<<=e,this._current_word_bits_left-=e,e;return this._fillCurrentWord(),e+this._skipLeadingZero()}},{key:"readUEG",value:function(){var e=this._skipLeadingZero();return this.readBits(e+1)-1}},{key:"readSEG",value:function(){var e=this.readUEG();return 1&e?e+1>>>1:-1*(e>>>1)}}]),e}();n.default=a},{"../utils/exception.js":40}],18:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]}Object.defineProperty(n,"__esModule",{value:!0});var a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=function(){function e(e,t){for(var n=0;n13))return 0;i=e.probe(t).dataOffset}if(this._firstParse){this._firstParse=!1,n+i!==this._dataOffset&&l.default.w(this.TAG,"First time parsing but chunk byteStart invalid!");0!==new DataView(t,i).getUint32(0,!r)&&l.default.w(this.TAG,"PrevTagSize0 !== 0 !!!"),i+=4}for(;it.byteLength)break;var a=s.getUint8(0),o=16777215&s.getUint32(0,!r);if(i+11+o+4>t.byteLength)break;if(8===a||9===a||18===a){var u=s.getUint8(4),d=s.getUint8(5),h=s.getUint8(6),f=s.getUint8(7),c=h|d<<8|u<<16|f<<24;0!==(16777215&s.getUint32(7,!r))&&l.default.w(this.TAG,"Meet tag which has StreamID != 0!");var _=i+11;switch(a){case 8:this._parseAudioData(t,_,o,c);break;case 9:this._parseVideoData(t,_,o,c,n+i);break;case 18:this._parseScriptData(t,_,o)}var m=s.getUint32(11+o,!r);m!==11+o&&l.default.w(this.TAG,"Invalid PrevTagSize "+m),i+=11+o+4}else l.default.w(this.TAG,"Unsupported tag type "+a+", skipped"),i+=11+o+4}return this._isInitialMetadataDispatched()&&this._dispatch&&(this._audioTrack.length||this._videoTrack.length)&&this._onDataAvailable(this._audioTrack,this._videoTrack),i}},{key:"_parseScriptData",value:function(e,t,n){var i=h.default.parseScriptData(e,t,n);if(i.hasOwnProperty("onMetaData")){if(null==i.onMetaData||"object"!==a(i.onMetaData))return void l.default.w(this.TAG,"Invalid onMetaData structure!");this._metadata&&l.default.w(this.TAG,"Found another onMetaData tag!"),this._metadata=i;var r=this._metadata.onMetaData;if("boolean"==typeof r.hasAudio&&!1===this._hasAudioFlagOverrided&&(this._hasAudio=r.hasAudio,this._mediaInfo.hasAudio=this._hasAudio),"boolean"==typeof r.hasVideo&&!1===this._hasVideoFlagOverrided&&(this._hasVideo=r.hasVideo,this._mediaInfo.hasVideo=this._hasVideo),"number"==typeof r.audiodatarate&&(this._mediaInfo.audioDataRate=r.audiodatarate),"number"==typeof r.videodatarate&&(this._mediaInfo.videoDataRate=r.videodatarate),"number"==typeof r.width&&(this._mediaInfo.width=r.width),"number"==typeof r.height&&(this._mediaInfo.height=r.height),"number"==typeof r.duration){if(!this._durationOverrided){var s=Math.floor(r.duration*this._timescale);this._duration=s,this._mediaInfo.duration=s}}else this._mediaInfo.duration=0;if("number"==typeof r.framerate){var o=Math.floor(1e3*r.framerate);if(o>0){var u=o/1e3;this._referenceFrameRate.fixed=!0,this._referenceFrameRate.fps=u,this._referenceFrameRate.fps_num=o,this._referenceFrameRate.fps_den=1e3,this._mediaInfo.fps=u}}if("object"===a(r.keyframes)){this._mediaInfo.hasKeyframesIndex=!0;var d=r.keyframes;this._mediaInfo.keyframesIndex=this._parseKeyframesIndex(d),r.keyframes=null}else this._mediaInfo.hasKeyframesIndex=!1;this._dispatch=!1,this._mediaInfo.metadata=r,l.default.v(this.TAG,"Parsed onMetaData"),this._mediaInfo.isComplete()&&this._onMediaInfo(this._mediaInfo)}}},{key:"_parseKeyframesIndex",value:function(e){for(var t=[],n=[],i=1;i>>4;if(2!==a&&10!==a)return void this._onError(m.default.CODEC_UNSUPPORTED,"Flv: Unsupported audio codec idx: "+a);var o=0,u=(12&s)>>>2;if(!(u>=0&&u<=4))return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid audio sample rate idx: "+u);o=this._flvSoundRateTable[u];var d=1&s,h=this._audioMetadata,f=this._audioTrack;if(h||(!1===this._hasAudio&&!1===this._hasAudioFlagOverrided&&(this._hasAudio=!0,this._mediaInfo.hasAudio=!0),h=this._audioMetadata={},h.type="audio",h.id=f.id,h.timescale=this._timescale,h.duration=this._duration,h.audioSampleRate=o,h.channelCount=0===d?1:2),10===a){var c=this._parseAACAudioData(e,t+1,n-1);if(void 0==c)return;if(0===c.packetType){h.config&&l.default.w(this.TAG,"Found another AudioSpecificConfig!");var _=c.data;h.audioSampleRate=_.samplingRate,h.channelCount=_.channelCount,h.codec=_.codec,h.originalCodec=_.originalCodec,h.config=_.config,h.refSampleDuration=1024/h.audioSampleRate*h.timescale,l.default.v(this.TAG,"Parsed AudioSpecificConfig"),this._isInitialMetadataDispatched()?this._dispatch&&(this._audioTrack.length||this._videoTrack.length)&&this._onDataAvailable(this._audioTrack,this._videoTrack):this._audioInitialMetadataDispatched=!0,this._dispatch=!1,this._onTrackMetadata("audio",h);var p=this._mediaInfo;p.audioCodec=h.originalCodec,p.audioSampleRate=h.audioSampleRate,p.audioChannelCount=h.channelCount,p.hasVideo?null!=p.videoCodec&&(p.mimeType='video/x-flv; codecs="'+p.videoCodec+","+p.audioCodec+'"'):p.mimeType='video/x-flv; codecs="'+p.audioCodec+'"',p.isComplete()&&this._onMediaInfo(p)}else if(1===c.packetType){var v=this._timestampBase+i,g={unit:c.data,dts:v,pts:v};f.samples.push(g),f.length+=c.data.length}else l.default.e(this.TAG,"Flv: Unsupported AAC data type "+c.packetType)}else if(2===a){if(!h.codec){var y=this._parseMP3AudioData(e,t+1,n-1,!0);if(void 0==y)return;h.audioSampleRate=y.samplingRate,h.channelCount=y.channelCount,h.codec=y.codec,h.originalCodec=y.originalCodec,h.refSampleDuration=1152/h.audioSampleRate*h.timescale,l.default.v(this.TAG,"Parsed MPEG Audio Frame Header"),this._audioInitialMetadataDispatched=!0,this._onTrackMetadata("audio",h);var E=this._mediaInfo;E.audioCodec=h.codec,E.audioSampleRate=h.audioSampleRate,E.audioChannelCount=h.channelCount,E.audioDataRate=y.bitRate,E.hasVideo?null!=E.videoCodec&&(E.mimeType='video/x-flv; codecs="'+E.videoCodec+","+E.audioCodec+'"'):E.mimeType='video/x-flv; codecs="'+E.audioCodec+'"',E.isComplete()&&this._onMediaInfo(E)}var b=this._parseMP3AudioData(e,t+1,n-1,!1);if(void 0==b)return;var S=this._timestampBase+i,k={unit:b,dts:S,pts:S};f.samples.push(k),f.length+=b.length}}}},{ +key:"_parseAACAudioData",value:function(e,t,n){if(n<=1)return void l.default.w(this.TAG,"Flv: Invalid AAC packet, missing AACPacketType or/and Data!");var i={},r=new Uint8Array(e,t,n);return i.packetType=r[0],0===r[0]?i.data=this._parseAACAudioSpecificConfig(e,t+1,n-1):i.data=r.subarray(1),i}},{key:"_parseAACAudioSpecificConfig",value:function(e,t,n){var i=new Uint8Array(e,t,n),r=null,s=0,a=0,o=0,u=null;if(s=a=i[0]>>>3,(o=(7&i[0])<<1|i[1]>>>7)<0||o>=this._mpegSamplingRates.length)return void this._onError(m.default.FORMAT_ERROR,"Flv: AAC invalid sampling frequency index!");var l=this._mpegSamplingRates[o],d=(120&i[1])>>>3;if(d<0||d>=8)return void this._onError(m.default.FORMAT_ERROR,"Flv: AAC invalid channel configuration");5===s&&(u=(7&i[1])<<1|i[2]>>>7,i[2]);var h=self.navigator.userAgent.toLowerCase();return-1!==h.indexOf("firefox")?o>=6?(s=5,r=new Array(4),u=o-3):(s=2,r=new Array(2),u=o):-1!==h.indexOf("android")?(s=2,r=new Array(2),u=o):(s=5,u=o,r=new Array(4),o>=6?u=o-3:1===d&&(s=2,r=new Array(2),u=o)),r[0]=s<<3,r[0]|=(15&o)>>>1,r[1]=(15&o)<<7,r[1]|=(15&d)<<3,5===s&&(r[1]|=(15&u)>>>1,r[2]=(1&u)<<7,r[2]|=8,r[3]=0),{config:r,samplingRate:l,channelCount:d,codec:"mp4a.40."+s,originalCodec:"mp4a.40."+a}}},{key:"_parseMP3AudioData",value:function(e,t,n,i){if(n<4)return void l.default.w(this.TAG,"Flv: Invalid MP3 packet, header missing!");var r=(this._littleEndian,new Uint8Array(e,t,n)),s=null;if(i){if(255!==r[0])return;var a=r[1]>>>3&3,o=(6&r[1])>>1,u=(240&r[2])>>>4,d=(12&r[2])>>>2,h=r[3]>>>6&3,f=3!==h?2:1,c=0,_=0;switch(a){case 0:c=this._mpegAudioV25SampleRateTable[d];break;case 2:c=this._mpegAudioV20SampleRateTable[d];break;case 3:c=this._mpegAudioV10SampleRateTable[d]}switch(o){case 1:34,u>>4,o=15&s;if(7!==o)return void this._onError(m.default.CODEC_UNSUPPORTED,"Flv: Unsupported codec in video frame: "+o);this._parseAVCVideoPacket(e,t+1,n-1,i,r,a)}}},{key:"_parseAVCVideoPacket",value:function(e,t,n,i,r,s){if(n<4)return void l.default.w(this.TAG,"Flv: Invalid AVC packet, missing AVCPacketType or/and CompositionTime");var a=this._littleEndian,o=new DataView(e,t,n),u=o.getUint8(0),d=16777215&o.getUint32(0,!a);if(0===u)this._parseAVCDecoderConfigurationRecord(e,t+4,n-4);else if(1===u)this._parseAVCVideoData(e,t+4,n-4,i,r,s,d);else if(2!==u)return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid video packet type "+u)}},{key:"_parseAVCDecoderConfigurationRecord",value:function(e,t,n){if(n<7)return void l.default.w(this.TAG,"Flv: Invalid AVCDecoderConfigurationRecord, lack of data!");var i=this._videoMetadata,r=this._videoTrack,s=this._littleEndian,a=new DataView(e,t,n);i?void 0!==i.avcc&&l.default.w(this.TAG,"Found another AVCDecoderConfigurationRecord!"):(!1===this._hasVideo&&!1===this._hasVideoFlagOverrided&&(this._hasVideo=!0,this._mediaInfo.hasVideo=!0),i=this._videoMetadata={},i.type="video",i.id=r.id,i.timescale=this._timescale,i.duration=this._duration);var o=a.getUint8(0),u=a.getUint8(1);a.getUint8(2),a.getUint8(3);if(1!==o||0===u)return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid AVCDecoderConfigurationRecord");if(this._naluLengthSize=1+(3&a.getUint8(4)),3!==this._naluLengthSize&&4!==this._naluLengthSize)return void this._onError(m.default.FORMAT_ERROR,"Flv: Strange NaluLengthSizeMinusOne: "+(this._naluLengthSize-1));var d=31&a.getUint8(5);if(0===d)return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid AVCDecoderConfigurationRecord: No SPS");d>1&&l.default.w(this.TAG,"Flv: Strange AVCDecoderConfigurationRecord: SPS Count = "+d);for(var h=6,f=0;f1&&l.default.w(this.TAG,"Flv: Strange AVCDecoderConfigurationRecord: PPS Count = "+w),h++;for(var R=0;R=n){l.default.w(this.TAG,"Malformed Nalu near timestamp "+_+", offset = "+f+", dataSize = "+n);break}var p=u.getUint32(f,!o);if(3===c&&(p>>>=8),p>n-c)return void l.default.w(this.TAG,"Malformed Nalus near timestamp "+_+", NaluSize > DataSize!");var v=31&u.getUint8(f+c);5===v&&(m=!0);var g=new Uint8Array(e,t+f,c+p),y={type:v,data:g};d.push(y),h+=g.byteLength,f+=c+p}if(d.length){var E=this._videoTrack,b={units:d,length:h,isKeyframe:m,dts:_,cts:a,pts:_+a};m&&(b.fileposition=r),E.samples.push(b),E.length+=h}}},{key:"onTrackMetadata",get:function(){return this._onTrackMetadata},set:function(e){this._onTrackMetadata=e}},{key:"onMediaInfo",get:function(){return this._onMediaInfo},set:function(e){this._onMediaInfo=e}},{key:"onError",get:function(){return this._onError},set:function(e){this._onError=e}},{key:"onDataAvailable",get:function(){return this._onDataAvailable},set:function(e){this._onDataAvailable=e}},{key:"timestampBase",get:function(){return this._timestampBase},set:function(e){this._timestampBase=e}},{key:"overridedDuration",get:function(){return this._duration},set:function(e){this._durationOverrided=!0,this._duration=e,this._mediaInfo.duration=e}},{key:"overridedHasAudio",set:function(e){this._hasAudioFlagOverrided=!0,this._hasAudio=e,this._mediaInfo.hasAudio=e}},{key:"overridedHasVideo",set:function(e){this._hasVideoFlagOverrided=!0,this._hasVideo=e,this._mediaInfo.hasVideo=e}}],[{key:"probe",value:function(e){var t=new Uint8Array(e),n={match:!1};if(70!==t[0]||76!==t[1]||86!==t[2]||1!==t[3])return n;var i=(4&t[4])>>>2!=0,r=0!=(1&t[4]),a=s(t,5);return a<9?n:{match:!0,consumed:a,dataOffset:a,hasAudioTrack:i,hasVideoTrack:r}}}]),e}();n.default=y},{"../core/media-info.js":7,"../utils/exception.js":40,"../utils/logger.js":41,"./amf-parser.js":15,"./demux-errors.js":16,"./sps-parser.js":19}],19:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=2&&3===t[s]&&0===t[s-1]&&0===t[s-2]||(i[r]=t[s],r++);return new Uint8Array(i.buffer,0,r)}},{key:"parseSPS",value:function(t){var n=e._ebsp2rbsp(t),i=new a.default(n);i.readByte();var r=i.readByte();i.readByte();var s=i.readByte();i.readUEG();var o=e.getProfileString(r),u=e.getLevelString(s),l=1,d=420,h=[0,420,422,444],f=8;if((100===r||110===r||122===r||244===r||44===r||83===r||86===r||118===r||128===r||138===r||144===r)&&(l=i.readUEG(),3===l&&i.readBits(1),l<=3&&(d=h[l]),f=i.readUEG()+8,i.readUEG(),i.readBits(1),i.readBool()))for(var c=3!==l?8:12,_=0;_0&&I<16?(w=x[I-1],R=M[I-1]):255===I&&(w=i.readByte()<<8|i.readByte(),R=i.readByte()<<8|i.readByte())}if(i.readBool()&&i.readBool(),i.readBool()&&(i.readBits(4),i.readBool()&&i.readBits(24)),i.readBool()&&(i.readUEG(),i.readUEG()),i.readBool()){var D=i.readBits(32),B=i.readBits(32);O=i.readBool(),T=B,C=2*D,A=T/C}}var j=1;1===w&&1===R||(j=w/R);var P=0,U=0;if(0===l)P=1,U=2-E;else{var N=3===l?1:2,F=1===l?2:1;P=N,U=F*(2-E)}var G=16*(g+1),V=16*(y+1)*(2-E);G-=(b+S)*P,V-=(k+L)*U;var z=Math.ceil(G*j);return i.destroy(),i=null,{profile_string:o,level_string:u,bit_depth:f,chroma_format:d,chroma_format_string:e.getChromaFormatString(d),frame_rate:{fixed:O,fps:A,fps_den:C,fps_num:T},sar_ratio:{width:w,height:R},codec_size:{width:G,height:V},present_size:{width:z,height:V}}}},{key:"_skipScalingList",value:function(e,t){for(var n=8,i=8,r=0,s=0;s=15048,t=!f.default.msedge||e;return self.fetch&&self.ReadableStream&&t}catch(e){return!1}}}]),l(t,[{key:"destroy",value:function(){this.isWorking()&&this.abort(),u(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"destroy",this).call(this)}},{key:"open",value:function(e,t){var n=this;this._dataSource=e,this._range=t;var i=e.url;this._config.reuseRedirectedURL&&void 0!=e.redirectedURL&&(i=e.redirectedURL);var r=this._seekHandler.getConfig(i,t),s=new self.Headers;if("object"===o(r.headers)){var a=r.headers;for(var u in a)a.hasOwnProperty(u)&&s.append(u,a[u])}var l={method:"GET",headers:s,mode:"cors",cache:"default",referrerPolicy:"no-referrer-when-downgrade"};!1===e.cors&&(l.mode="same-origin"),e.withCredentials&&(l.credentials="include"),e.referrerPolicy&&(l.referrerPolicy=e.referrerPolicy),this._status=c.LoaderStatus.kConnecting,self.fetch(r.url,l).then(function(e){if(n._requestAbort)return n._requestAbort=!1,void(n._status=c.LoaderStatus.kIdle);if(e.ok&&e.status>=200&&e.status<=299){if(e.url!==r.url&&n._onURLRedirect){var t=n._seekHandler.removeURLParameters(e.url);n._onURLRedirect(t)}var i=e.headers.get("Content-Length");return null!=i&&(n._contentLength=parseInt(i),0!==n._contentLength&&n._onContentLengthKnown&&n._onContentLengthKnown(n._contentLength)),n._pump.call(n,e.body.getReader())}if(n._status=c.LoaderStatus.kError,!n._onError)throw new _.RuntimeException("FetchStreamLoader: Http code invalid, "+e.status+" "+e.statusText);n._onError(c.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:e.status,msg:e.statusText})}).catch(function(e){if(n._status=c.LoaderStatus.kError,!n._onError)throw e;n._onError(c.LoaderErrors.EXCEPTION,{code:-1,msg:e.message})})}},{key:"abort",value:function(){this._requestAbort=!0}},{key:"_pump",value:function(e){var t=this;return e.read().then(function(n){if(n.done)t._status=c.LoaderStatus.kComplete,t._onComplete&&t._onComplete(t._range.from,t._range.from+t._receivedLength-1);else{if(!0===t._requestAbort)return t._requestAbort=!1,t._status=c.LoaderStatus.kComplete,e.cancel();t._status=c.LoaderStatus.kBuffering;var i=n.value.buffer,r=t._range.from+t._receivedLength;t._receivedLength+=i.byteLength,t._onDataArrival&&t._onDataArrival(i,r,t._receivedLength),t._pump(e)}}).catch(function(e){if(11!==e.code||!f.default.msedge){t._status=c.LoaderStatus.kError;var n=0,i=null;if(19!==e.code&&"network error"!==e.message||!(null===t._contentLength||null!==t._contentLength&&t._receivedLength0&&(this._stashInitialSize=n.stashInitialSize),this._stashUsed=0,this._stashSize=this._stashInitialSize,this._bufferSize=3145728,this._stashBuffer=new ArrayBuffer(this._bufferSize),this._stashByteStart=0,this._enableStash=!0,!1===n.enableStashBuffer&&(this._enableStash=!1),this._loader=null,this._loaderClass=null,this._seekHandler=null,this._dataSource=t,this._isWebSocketURL=/wss?:\/\/(.+?)/.test(t.url),this._refTotalLength=t.filesize?t.filesize:null,this._totalLength=this._refTotalLength,this._fullRequestFlag=!1,this._currentRange=null,this._redirectedURL=null,this._speedNormalized=0,this._speedSampler=new l.default,this._speedNormalizeList=[64,128,256,384,512,768,1024,1536,2048,3072,4096],this._isEarlyEofReconnecting=!1,this._paused=!1,this._resumeFrom=0,this._onDataArrival=null,this._onSeeked=null,this._onError=null,this._onComplete=null,this._onRedirect=null,this._onRecoveredEarlyEof=null,this._selectSeekHandler(),this._selectLoader(),this._createLoader()}return s(e,[{key:"destroy",value:function(){this._loader.isWorking()&&this._loader.abort(),this._loader.destroy(),this._loader=null,this._loaderClass=null,this._dataSource=null,this._stashBuffer=null,this._stashUsed=this._stashSize=this._bufferSize=this._stashByteStart=0,this._currentRange=null,this._speedSampler=null,this._isEarlyEofReconnecting=!1,this._onDataArrival=null,this._onSeeked=null,this._onError=null,this._onComplete=null,this._onRedirect=null,this._onRecoveredEarlyEof=null,this._extraData=null}},{key:"isWorking",value:function(){return this._loader&&this._loader.isWorking()&&!this._paused}},{key:"isPaused",value:function(){return this._paused}},{key:"_selectSeekHandler",value:function(){var e=this._config;if("range"===e.seekType)this._seekHandler=new b.default(this._config.rangeLoadZeroStart);else if("param"===e.seekType){var t=e.seekParamStart||"bstart",n=e.seekParamEnd||"bend";this._seekHandler=new k.default(t,n)}else{if("custom"!==e.seekType)throw new L.InvalidArgumentException("Invalid seekType in config: "+e.seekType);if("function"!=typeof e.customSeekHandler)throw new L.InvalidArgumentException("Custom seekType specified in config but invalid customSeekHandler!");this._seekHandler=new e.customSeekHandler}}},{key:"_selectLoader",value:function(){if(this._isWebSocketURL)this._loaderClass=y.default;else if(f.default.isSupported())this._loaderClass=f.default;else if(_.default.isSupported())this._loaderClass=_.default;else{if(!v.default.isSupported())throw new L.RuntimeException("Your browser doesn't support xhr with arraybuffer responseType!");this._loaderClass=v.default}}},{key:"_createLoader",value:function(){this._loader=new this._loaderClass(this._seekHandler,this._config),!1===this._loader.needStashBuffer&&(this._enableStash=!1),this._loader.onContentLengthKnown=this._onContentLengthKnown.bind(this),this._loader.onURLRedirect=this._onURLRedirect.bind(this),this._loader.onDataArrival=this._onLoaderChunkArrival.bind(this),this._loader.onComplete=this._onLoaderComplete.bind(this),this._loader.onError=this._onLoaderError.bind(this)}},{key:"open",value:function(e){this._currentRange={from:0,to:-1},e&&(this._currentRange.from=e),this._speedSampler.reset(),e||(this._fullRequestFlag=!0),this._loader.open(this._dataSource,Object.assign({},this._currentRange))}},{key:"abort",value:function(){this._loader.abort(),this._paused&&(this._paused=!1,this._resumeFrom=0)}},{key:"pause",value:function(){this.isWorking()&&(this._loader.abort(),0!==this._stashUsed?(this._resumeFrom=this._stashByteStart,this._currentRange.to=this._stashByteStart-1):this._resumeFrom=this._currentRange.to+1,this._stashUsed=0,this._stashByteStart=0,this._paused=!0)}},{key:"resume",value:function(){if(this._paused){this._paused=!1;var e=this._resumeFrom;this._resumeFrom=0,this._internalSeek(e,!0)}}},{key:"seek",value:function(e){this._paused=!1,this._stashUsed=0,this._stashByteStart=0,this._internalSeek(e,!0)}},{key:"_internalSeek",value:function(e,t){this._loader.isWorking()&&this._loader.abort(),this._flushStashBuffer(t),this._loader.destroy(),this._loader=null;var n={from:e,to:-1};this._currentRange={from:n.from,to:-1},this._speedSampler.reset(),this._stashSize=this._stashInitialSize,this._createLoader(),this._loader.open(this._dataSource,n),this._onSeeked&&this._onSeeked()}},{key:"updateUrl",value:function(e){if(!e||"string"!=typeof e||0===e.length)throw new L.InvalidArgumentException("Url must be a non-empty string!");this._dataSource.url=e}},{key:"_expandBuffer",value:function(e){for(var t=this._stashSize;t+10485760){var i=new Uint8Array(this._stashBuffer,0,this._stashUsed);new Uint8Array(n,0,t).set(i,0)}this._stashBuffer=n,this._bufferSize=t}}},{key:"_normalizeSpeed",value:function(e){var t=this._speedNormalizeList,n=t.length-1,i=0,r=0,s=n;if(e=t[i]&&e=512&&e<=1024?Math.floor(1.5*e):2*e)>8192&&(t=8192);var n=1024*t+1048576;this._bufferSize0){var o=this._stashBuffer.slice(0,this._stashUsed),u=this._dispatchChunks(o,this._stashByteStart);if(u0){var l=new Uint8Array(o,u);a.set(l,0),this._stashUsed=l.byteLength,this._stashByteStart+=u}}else this._stashUsed=0,this._stashByteStart+=u;this._stashUsed+e.byteLength>this._bufferSize&&(this._expandBuffer(this._stashUsed+e.byteLength),a=new Uint8Array(this._stashBuffer,0,this._bufferSize)),a.set(new Uint8Array(e),this._stashUsed),this._stashUsed+=e.byteLength}else{var d=this._dispatchChunks(e,t);if(dthis._bufferSize&&(this._expandBuffer(h),a=new Uint8Array(this._stashBuffer,0,this._bufferSize)),a.set(new Uint8Array(e,d),0),this._stashUsed+=h,this._stashByteStart=t+d}}}else if(0===this._stashUsed){var f=this._dispatchChunks(e,t);if(fthis._bufferSize&&this._expandBuffer(c);var _=new Uint8Array(this._stashBuffer,0,this._bufferSize);_.set(new Uint8Array(e,f),0),this._stashUsed+=c,this._stashByteStart=t+f}}else{this._stashUsed+e.byteLength>this._bufferSize&&this._expandBuffer(this._stashUsed+e.byteLength);var m=new Uint8Array(this._stashBuffer,0,this._bufferSize);m.set(new Uint8Array(e),this._stashUsed),this._stashUsed+=e.byteLength;var p=this._dispatchChunks(this._stashBuffer.slice(0,this._stashUsed),this._stashByteStart);if(p0){var v=new Uint8Array(this._stashBuffer,p);m.set(v,0)}this._stashUsed-=p,this._stashByteStart+=p}}}},{key:"_flushStashBuffer",value:function(e){if(this._stashUsed>0){var t=this._stashBuffer.slice(0,this._stashUsed),n=this._dispatchChunks(t,this._stashByteStart),i=t.byteLength-n;if(n0){var r=new Uint8Array(this._stashBuffer,0,this._bufferSize),s=new Uint8Array(t,n);r.set(s,0),this._stashUsed=s.byteLength,this._stashByteStart+=n}return 0}o.default.w(this.TAG,i+" bytes unconsumed data remain when flush buffer, dropped")}return this._stashUsed=0,this._stashByteStart=0,i}return 0}},{key:"_onLoaderComplete",value:function(e,t){this._flushStashBuffer(!0),this._onComplete&&this._onComplete(this._extraData)}},{key:"_onLoaderError",value:function(e,t){switch(o.default.e(this.TAG,"Loader error, code = "+t.code+", msg = "+t.msg),this._flushStashBuffer(!1),this._isEarlyEofReconnecting&&(this._isEarlyEofReconnecting=!1,e=d.LoaderErrors.UNRECOVERABLE_EARLY_EOF),e){case d.LoaderErrors.EARLY_EOF:if(!this._config.isLive&&this._totalLength){var n=this._currentRange.to+1;return void(n0)for(var s=n.split("&"),a=0;a0;o[0]!==this._startName&&o[0]!==this._endName&&(u&&(r+="&"),r+=s[a])}return 0===r.length?t:t+"?"+r}}]),e}();n.default=s},{}],26:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=500?this.currentKBps:0}},{key:"averageKBps",get:function(){var e=(this._now()-this._firstCheckpoint)/1e3;return this._totalBytes/e/1024}}]),e}();n.default=s},{}],28:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(n,"__esModule",{value:!0});var a=function e(t,n,i){null===t&&(t=Function.prototype);var r=Object.getOwnPropertyDescriptor(t,n);if(void 0===r){var s=Object.getPrototypeOf(t);return null===s?void 0:e(s,n,i)}if("value"in r)return r.value;var a=r.get;if(void 0!==a)return a.call(i)},o=function(){function e(e,t){for(var n=0;n299)){if(this._status=h.LoaderStatus.kError,!this._onError)throw new f.RuntimeException("MozChunkedLoader: Http code invalid, "+t.status+" "+t.statusText);this._onError(h.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:t.status,msg:t.statusText})}else this._status=h.LoaderStatus.kBuffering}}},{key:"_onProgress",value:function(e){if(this._status!==h.LoaderStatus.kError){null===this._contentLength&&null!==e.total&&0!==e.total&&(this._contentLength=e.total,this._onContentLengthKnown&&this._onContentLengthKnown(this._contentLength));var t=e.target.response,n=this._range.from+this._receivedLength;this._receivedLength+=t.byteLength,this._onDataArrival&&this._onDataArrival(t,n,this._receivedLength)}}},{key:"_onLoadEnd",value:function(e){if(!0===this._requestAbort)return void(this._requestAbort=!1);this._status!==h.LoaderStatus.kError&&(this._status=h.LoaderStatus.kComplete,this._onComplete&&this._onComplete(this._range.from,this._range.from+this._receivedLength-1))}},{key:"_onXhrError",value:function(e){this._status=h.LoaderStatus.kError;var t=0,n=null;if(this._contentLength&&e.loaded=200&&t.status<=299){if(this._status=h.LoaderStatus.kBuffering,void 0!=t.responseURL){var n=this._seekHandler.removeURLParameters(t.responseURL);t.responseURL!==this._currentRequestURL&&n!==this._currentRedirectedURL&&(this._currentRedirectedURL=n,this._onURLRedirect&&this._onURLRedirect(n))}var i=t.getResponseHeader("Content-Length");if(null!=i&&null==this._contentLength){var r=parseInt(i);r>0&&(this._contentLength=r,this._onContentLengthKnown&&this._onContentLengthKnown(this._contentLength))}}else{if(this._status=h.LoaderStatus.kError,!this._onError)throw new f.RuntimeException("MSStreamLoader: Http code invalid, "+t.status+" "+t.statusText);this._onError(h.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:t.status,msg:t.statusText})}else if(3===t.readyState&&t.status>=200&&t.status<=299){this._status=h.LoaderStatus.kBuffering;var s=t.response;this._reader.readAsArrayBuffer(s)}}},{key:"_xhrOnError",value:function(e){this._status=h.LoaderStatus.kError;var t=h.LoaderErrors.EXCEPTION,n={code:-1,msg:e.constructor.name+" "+e.type};if(!this._onError)throw new f.RuntimeException(n.msg);this._onError(t,n)}},{key:"_msrOnProgress",value:function(e){var t=e.target,n=t.result;if(null==n)return void this._doReconnectIfNeeded();var i=n.slice(this._lastTimeBufferSize);this._lastTimeBufferSize=n.byteLength;var r=this._totalRange.from+this._receivedLength;this._receivedLength+=i.byteLength,this._onDataArrival&&this._onDataArrival(i,r,this._receivedLength),n.byteLength>=this._bufferLimit&&(d.default.v(this.TAG,"MSStream buffer exceeded max size near "+(r+i.byteLength)+", reconnecting..."),this._doReconnectIfNeeded())}},{key:"_doReconnectIfNeeded",value:function(){if(null==this._contentLength||this._receivedLength=this._contentLength&&(n=this._range.from+this._contentLength-1),this._currentRequestRange={from:t,to:n},this._internalOpen(this._dataSource,this._currentRequestRange)}},{key:"_internalOpen",value:function(e,t){this._lastTimeLoaded=0;var n=e.url;this._config.reuseRedirectedURL&&(void 0!=this._currentRedirectedURL?n=this._currentRedirectedURL:void 0!=e.redirectedURL&&(n=e.redirectedURL));var i=this._seekHandler.getConfig(n,t);this._currentRequestURL=i.url;var r=this._xhr=new XMLHttpRequest;if(r.open("GET",i.url,!0),r.responseType="arraybuffer",r.onreadystatechange=this._onReadyStateChange.bind(this),r.onprogress=this._onProgress.bind(this),r.onload=this._onLoad.bind(this),r.onerror=this._onXhrError.bind(this),e.withCredentials&&r.withCredentials&&(r.withCredentials=!0),"object"===o(i.headers)){var s=i.headers;for(var a in s)s.hasOwnProperty(a)&&r.setRequestHeader(a,s[a])}r.send()}},{key:"abort",value:function(){this._requestAbort=!0,this._internalAbort(),this._status=_.LoaderStatus.kComplete}},{key:"_internalAbort",value:function(){this._xhr&&(this._xhr.onreadystatechange=null,this._xhr.onprogress=null,this._xhr.onload=null,this._xhr.onerror=null,this._xhr.abort(),this._xhr=null)}},{key:"_onReadyStateChange",value:function(e){var t=e.target;if(2===t.readyState){if(void 0!=t.responseURL){var n=this._seekHandler.removeURLParameters(t.responseURL);t.responseURL!==this._currentRequestURL&&n!==this._currentRedirectedURL&&(this._currentRedirectedURL=n,this._onURLRedirect&&this._onURLRedirect(n))}if(t.status>=200&&t.status<=299){if(this._waitForTotalLength)return;this._status=_.LoaderStatus.kBuffering}else{if(this._status=_.LoaderStatus.kError,!this._onError)throw new m.RuntimeException("RangeLoader: Http code invalid, "+t.status+" "+t.statusText);this._onError(_.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:t.status,msg:t.statusText})}}}},{key:"_onProgress",value:function(e){if(this._status!==_.LoaderStatus.kError){if(null===this._contentLength){var t=!1;if(this._waitForTotalLength){this._waitForTotalLength=!1,this._totalLengthReceived=!0,t=!0;var n=e.total;this._internalAbort(),null!=n&0!==n&&(this._totalLength=n)}if(-1===this._range.to?this._contentLength=this._totalLength-this._range.from:this._contentLength=this._range.to-this._range.from+1,t)return void this._openSubRange();this._onContentLengthKnown&&this._onContentLengthKnown(this._contentLength)}var i=e.loaded-this._lastTimeLoaded;this._lastTimeLoaded=e.loaded,this._speedSampler.addBytes(i)}}},{key:"_normalizeSpeed",value:function(e){var t=this._chunkSizeKBList,n=t.length-1,i=0,r=0,s=n;if(e=t[i]&&e=3&&(t=this._speedSampler.currentKBps),0!==t){var n=this._normalizeSpeed(t);this._currentSpeedNormalized!==n&&(this._currentSpeedNormalized=n,this._currentChunkSizeKB=n)}var i=e.target.response,r=this._range.from+this._receivedLength;this._receivedLength+=i.byteLength;var s=!1;null!=this._contentLength&&this._receivedLength0&&this._receivedLength0&&(this._requestSetTime=!0,this._mediaElement.currentTime=0),this._transmuxer=new p.default(this._mediaDataSource,this._config),this._transmuxer.on(g.default.INIT_SEGMENT,function(t,n){e._msectl.appendInitSegment(n)}),this._transmuxer.on(g.default.MEDIA_SEGMENT,function(t,n){if(e._msectl.appendMediaSegment(n),e._config.lazyLoad&&!e._config.isLive){var i=e._mediaElement.currentTime;n.info.endDts>=1e3*(i+e._config.lazyLoadMaxDuration)&&null==e._progressChecker&&(d.default.v(e.TAG,"Maximum buffering duration exceeded, suspend transmuxing task"),e._suspendTransmuxer())}}),this._transmuxer.on(g.default.LOADING_COMPLETE,function(){e._msectl.endOfStream(),e._emitter.emit(_.default.LOADING_COMPLETE)}),this._transmuxer.on(g.default.RECOVERED_EARLY_EOF,function(){e._emitter.emit(_.default.RECOVERED_EARLY_EOF)}),this._transmuxer.on(g.default.IO_ERROR,function(t,n){e._emitter.emit(_.default.ERROR,k.ErrorTypes.NETWORK_ERROR,t,n)}),this._transmuxer.on(g.default.DEMUX_ERROR,function(t,n){e._emitter.emit(_.default.ERROR,k.ErrorTypes.MEDIA_ERROR,t,{code:-1,msg:n})}), +this._transmuxer.on(g.default.MEDIA_INFO,function(t){e._mediaInfo=t,e._emitter.emit(_.default.MEDIA_INFO,Object.assign({},t))}),this._transmuxer.on(g.default.STATISTICS_INFO,function(t){e._statisticsInfo=e._fillStatisticsInfo(t),e._emitter.emit(_.default.STATISTICS_INFO,Object.assign({},e._statisticsInfo))}),this._transmuxer.on(g.default.RECOMMEND_SEEKPOINT,function(t){e._mediaElement&&!e._config.accurateSeek&&(e._requestSetTime=!0,e._mediaElement.currentTime=t/1e3)}),this._transmuxer.open()}}},{key:"unload",value:function(){this._mediaElement&&this._mediaElement.pause(),this._msectl&&this._msectl.seek(0),this._transmuxer&&(this._transmuxer.close(),this._transmuxer.destroy(),this._transmuxer=null)}},{key:"play",value:function(){return this._mediaElement.play()}},{key:"pause",value:function(){this._mediaElement.pause()}},{key:"_fillStatisticsInfo",value:function(e){if(e.playerType=this._type,!(this._mediaElement instanceof HTMLVideoElement))return e;var t=!0,n=0,i=0;if(this._mediaElement.getVideoPlaybackQuality){var r=this._mediaElement.getVideoPlaybackQuality();n=r.totalVideoFrames,i=r.droppedVideoFrames}else void 0!=this._mediaElement.webkitDecodedFrameCount?(n=this._mediaElement.webkitDecodedFrameCount,i=this._mediaElement.webkitDroppedFrameCount):t=!1;return t&&(e.decodedFrames=n,e.droppedFrames=i),e}},{key:"_onmseUpdateEnd",value:function(){if(this._config.lazyLoad&&!this._config.isLive){for(var e=this._mediaElement.buffered,t=this._mediaElement.currentTime,n=0,i=0;i=t+this._config.lazyLoadMaxDuration&&null==this._progressChecker&&(d.default.v(this.TAG,"Maximum buffering duration exceeded, suspend transmuxing task"),this._suspendTransmuxer())}}},{key:"_onmseBufferFull",value:function(){d.default.v(this.TAG,"MSE SourceBuffer is full, suspend transmuxing task"),null==this._progressChecker&&this._suspendTransmuxer()}},{key:"_suspendTransmuxer",value:function(){this._transmuxer&&(this._transmuxer.pause(),null==this._progressChecker&&(this._progressChecker=window.setInterval(this._checkProgressAndResume.bind(this),1e3)))}},{key:"_checkProgressAndResume",value:function(){for(var e=this._mediaElement.currentTime,t=this._mediaElement.buffered,n=!1,i=0;i=r&&e=s-this._config.lazyLoadRecoverDuration&&(n=!0);break}}n&&(window.clearInterval(this._progressChecker),this._progressChecker=null,n&&(d.default.v(this.TAG,"Continue loading from paused position"),this._transmuxer.resume()))}},{key:"_isTimepointBuffered",value:function(e){for(var t=this._mediaElement.buffered,n=0;n=i&&e0){var r=this._mediaElement.buffered.start(0);(r<1&&e0&&t.currentTime0){var i=n.start(0);if(i<1&&t0&&(this._mediaElement.currentTime=0),this._mediaElement.preload="auto",this._mediaElement.load(),this._statisticsReporter=window.setInterval(this._reportStatisticsInfo.bind(this),this._config.statisticsInfoReportInterval)}},{key:"unload",value:function(){this._mediaElement&&(this._mediaElement.src="",this._mediaElement.removeAttribute("src")),null!=this._statisticsReporter&&(window.clearInterval(this._statisticsReporter),this._statisticsReporter=null)}},{key:"play",value:function(){return this._mediaElement.play()}},{key:"pause",value:function(){this._mediaElement.pause()}},{key:"_onvLoadedMetadata",value:function(e){null!=this._pendingSeekTime&&(this._mediaElement.currentTime=this._pendingSeekTime,this._pendingSeekTime=null),this._emitter.emit(d.default.MEDIA_INFO,this.mediaInfo)}},{key:"_reportStatisticsInfo",value:function(){this._emitter.emit(d.default.STATISTICS_INFO,this.statisticsInfo)}},{key:"type",get:function(){return this._type}},{key:"buffered",get:function(){return this._mediaElement.buffered}},{key:"duration",get:function(){return this._mediaElement.duration}},{key:"volume",get:function(){return this._mediaElement.volume},set:function(e){this._mediaElement.volume=e}},{key:"muted",get:function(){return this._mediaElement.muted},set:function(e){this._mediaElement.muted=e}},{key:"currentTime",get:function(){return this._mediaElement?this._mediaElement.currentTime:0},set:function(e){this._mediaElement?this._mediaElement.currentTime=e:this._pendingSeekTime=e}},{key:"mediaInfo",get:function(){var e=this._mediaElement instanceof HTMLAudioElement?"audio/":"video/",t={mimeType:e+this._mediaDataSource.type};return this._mediaElement&&(t.duration=Math.floor(1e3*this._mediaElement.duration),this._mediaElement instanceof HTMLVideoElement&&(t.width=this._mediaElement.videoWidth,t.height=this._mediaElement.videoHeight)),t}},{key:"statisticsInfo",get:function(){var e={playerType:this._type,url:this._mediaDataSource.url};if(!(this._mediaElement instanceof HTMLVideoElement))return e;var t=!0,n=0,i=0;if(this._mediaElement.getVideoPlaybackQuality){var r=this._mediaElement.getVideoPlaybackQuality();n=r.totalVideoFrames,i=r.droppedVideoFrames}else void 0!=this._mediaElement.webkitDecodedFrameCount?(n=this._mediaElement.webkitDecodedFrameCount,i=this._mediaElement.webkitDroppedFrameCount):t=!1;return t&&(e.decodedFrames=n,e.droppedFrames=i),e}}]),e}();n.default=c},{"../config.js":5,"../utils/exception.js":40,"./player-events.js":35,events:2}],34:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.ErrorDetails=n.ErrorTypes=void 0;var i=e("../io/loader.js"),r=e("../demux/demux-errors.js"),s=function(e){return e&&e.__esModule?e:{default:e}}(r);n.ErrorTypes={NETWORK_ERROR:"NetworkError",MEDIA_ERROR:"MediaError",OTHER_ERROR:"OtherError"},n.ErrorDetails={NETWORK_EXCEPTION:i.LoaderErrors.EXCEPTION,NETWORK_STATUS_CODE_INVALID:i.LoaderErrors.HTTP_STATUS_CODE_INVALID,NETWORK_TIMEOUT:i.LoaderErrors.CONNECTING_TIMEOUT,NETWORK_UNRECOVERABLE_EARLY_EOF:i.LoaderErrors.UNRECOVERABLE_EARLY_EOF,MEDIA_MSE_ERROR:"MediaMSEError",MEDIA_FORMAT_ERROR:s.default.FORMAT_ERROR,MEDIA_FORMAT_UNSUPPORTED:s.default.FORMAT_UNSUPPORTED,MEDIA_CODEC_UNSUPPORTED:s.default.CODEC_UNSUPPORTED}},{"../demux/demux-errors.js":16,"../io/loader.js":24}],35:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i={ERROR:"error",LOADING_COMPLETE:"loading_complete",RECOVERED_EARLY_EOF:"recovered_early_eof",MEDIA_INFO:"media_info",STATISTICS_INFO:"statistics_info"};n.default=i},{}],36:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n>>24&255,n[1]=t>>>16&255,n[2]=t>>>8&255,n[3]=255&t,n.set(e,4);for(var a=8,o=0;o>>24&255,t>>>16&255,t>>>8&255,255&t,n>>>24&255,n>>>16&255,n>>>8&255,255&n,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]))}},{key:"trak",value:function(t){return e.box(e.types.trak,e.tkhd(t),e.mdia(t))}},{key:"tkhd",value:function(t){var n=t.id,i=t.duration,r=t.presentWidth,s=t.presentHeight;return e.box(e.types.tkhd,new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,0,0,0,0,i>>>24&255,i>>>16&255,i>>>8&255,255&i,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,r>>>8&255,255&r,0,0,s>>>8&255,255&s,0,0]))}},{key:"mdia",value:function(t){return e.box(e.types.mdia,e.mdhd(t),e.hdlr(t),e.minf(t))}},{key:"mdhd",value:function(t){var n=t.timescale,i=t.duration;return e.box(e.types.mdhd,new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,i>>>24&255,i>>>16&255,i>>>8&255,255&i,85,196,0,0]))}},{key:"hdlr",value:function(t){var n=null;return n="audio"===t.type?e.constants.HDLR_AUDIO:e.constants.HDLR_VIDEO,e.box(e.types.hdlr,n)}},{key:"minf",value:function(t){var n=null;return n="audio"===t.type?e.box(e.types.smhd,e.constants.SMHD):e.box(e.types.vmhd,e.constants.VMHD),e.box(e.types.minf,n,e.dinf(),e.stbl(t))}},{key:"dinf",value:function(){return e.box(e.types.dinf,e.box(e.types.dref,e.constants.DREF))}},{key:"stbl",value:function(t){return e.box(e.types.stbl,e.stsd(t),e.box(e.types.stts,e.constants.STTS),e.box(e.types.stsc,e.constants.STSC),e.box(e.types.stsz,e.constants.STSZ),e.box(e.types.stco,e.constants.STCO))}},{key:"stsd",value:function(t){return"audio"===t.type?"mp3"===t.codec?e.box(e.types.stsd,e.constants.STSD_PREFIX,e.mp3(t)):e.box(e.types.stsd,e.constants.STSD_PREFIX,e.mp4a(t)):e.box(e.types.stsd,e.constants.STSD_PREFIX,e.avc1(t))}},{key:"mp3",value:function(t){var n=t.channelCount,i=t.audioSampleRate,r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,n,0,16,0,0,0,0,i>>>8&255,255&i,0,0]);return e.box(e.types[".mp3"],r)}},{key:"mp4a",value:function(t){var n=t.channelCount,i=t.audioSampleRate,r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,n,0,16,0,0,0,0,i>>>8&255,255&i,0,0]);return e.box(e.types.mp4a,r,e.esds(t))}},{key:"esds",value:function(t){var n=t.config||[],i=n.length,r=new Uint8Array([0,0,0,0,3,23+i,0,1,0,4,15+i,64,21,0,0,0,0,0,0,0,0,0,0,0,5].concat([i]).concat(n).concat([6,1,2]));return e.box(e.types.esds,r)}},{key:"avc1",value:function(t){var n=t.avcc,i=t.codecWidth,r=t.codecHeight,s=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i>>>8&255,255&i,r>>>8&255,255&r,0,72,0,0,0,72,0,0,0,0,0,0,0,1,10,120,113,113,47,102,108,118,46,106,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,255,255]);return e.box(e.types.avc1,s,e.box(e.types.avcC,n))}},{key:"mvex",value:function(t){return e.box(e.types.mvex,e.trex(t))}},{key:"trex",value:function(t){var n=t.id,i=new Uint8Array([0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return e.box(e.types.trex,i)}},{key:"moof",value:function(t,n){return e.box(e.types.moof,e.mfhd(t.sequenceNumber),e.traf(t,n))}},{key:"mfhd",value:function(t){var n=new Uint8Array([0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,255&t]);return e.box(e.types.mfhd,n)}},{key:"traf",value:function(t,n){var i=t.id,r=e.box(e.types.tfhd,new Uint8Array([0,0,0,0,i>>>24&255,i>>>16&255,i>>>8&255,255&i])),s=e.box(e.types.tfdt,new Uint8Array([0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n])),a=e.sdtp(t),o=e.trun(t,a.byteLength+16+16+8+16+8+8);return e.box(e.types.traf,r,s,o,a)}},{key:"sdtp",value:function(t){for(var n=t.samples||[],i=n.length,r=new Uint8Array(4+i),s=0;s>>24&255,r>>>16&255,r>>>8&255,255&r,n>>>24&255,n>>>16&255,n>>>8&255,255&n],0);for(var o=0;o>>24&255,u>>>16&255,u>>>8&255,255&u,l>>>24&255,l>>>16&255,l>>>8&255,255&l,d.isLeading<<2|d.dependsOn,d.isDependedOn<<6|d.hasRedundancy<<4|d.isNonSync,0,0,h>>>24&255,h>>>16&255,h>>>8&255,255&h],12+16*o)}return e.box(e.types.trun,a)}},{key:"mdat",value:function(t){return e.box(e.types.mdat,t)}}]),e}();s.init(),n.default=s},{}],38:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n=1?A[A.length-1].duration:Math.floor(a);var D=!1,B=null;if(M>1.5*a&&"mp3"!==this._audioMeta.codec&&this._fillAudioTimestampGap&&!c.default.safari){D=!0;var j=Math.abs(M-a),P=Math.ceil(j/a),U=x+a;o.default.w(this.TAG,"Large audio timestamp gap detected, may cause AV sync to drift. Silent frames will be generated to avoid unsync.\ndts: "+(x+M)+" ms, expected: "+(x+Math.round(a))+" ms, delta: "+Math.round(j)+" ms, generate: "+P+" frames");var N=h.default.getSilentFrame(this._audioMeta.originalCodec,this._audioMeta.channelCount);null==N&&(o.default.w(this.TAG,"Unable to generate silent frame for "+this._audioMeta.originalCodec+" with "+this._audioMeta.channelCount+" channels, repeat last frame"),N=C),B=[];for(var F=0;F0){var V=B[B.length-1];V.duration=G-V.dts}var z={dts:G,pts:G,cts:0,unit:N,size:N.byteLength,duration:0,originalDts:I,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0}};B.push(z),v+=C.byteLength,U+=a}var H=B[B.length-1];H.duration=x+M-H.dts,M=Math.round(a)}A.push({dts:x,pts:x,cts:0,unit:T.unit,size:T.unit.byteLength,duration:M,originalDts:I,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0}}),D&&A.push.apply(A,B)}u?p=new Uint8Array(v):(p=new Uint8Array(v),p[0]=v>>>24&255,p[1]=v>>>16&255,p[2]=v>>>8&255,p[3]=255&v,p.set(l.default.types.mdat,4));for(var K=0;K>>24&255,h[1]=d>>>16&255,h[2]=d>>>8&255,h[3]=255&d,h.set(l.default.types.mdat,4);var f=n[0].dts-this._dtsBase;if(this._videoNextDts)i=f-this._videoNextDts;else if(this._videoSegmentInfoList.isEmpty())i=0;else{var c=this._videoSegmentInfoList.getLastSampleBefore(f);if(null!=c){var m=f-(c.originalDts+c.duration);m<=3&&(m=0);var p=c.dts+c.duration+m;i=f-p}else i=0}for(var v=new _.MediaSegmentInfo,g=[],y=0;y=1?g[g.length-1].duration:Math.floor(this._videoMeta.refSampleDuration);if(S){var A=new _.SampleInfo(k,w,R,E.dts,!0);A.fileposition=E.fileposition,v.appendSyncPoint(A)}g.push({dts:k,pts:w,cts:L,units:E.units,size:E.length,isKeyframe:S,duration:R,originalDts:b,flags:{isLeading:0,dependsOn:S?2:1,isDependedOn:S?1:0,hasRedundancy:0,isNonSync:S?0:1}})}for(var O=0;O=0&&/(rv)(?::| )([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(firefox)[ \/]([\w.]+)/.exec(e)||[],n=/(ipad)/.exec(e)||/(ipod)/.exec(e)||/(windows phone)/.exec(e)||/(iphone)/.exec(e)||/(kindle)/.exec(e)||/(android)/.exec(e)||/(windows)/.exec(e)||/(mac)/.exec(e)||/(linux)/.exec(e)||/(cros)/.exec(e)||[],r={browser:t[5]||t[3]||t[1]||"",version:t[2]||t[4]||"0",majorVersion:t[4]||t[2]||"0",platform:n[0]||""},s={};if(r.browser){s[r.browser]=!0;var a=r.majorVersion.split(".");s.version={major:parseInt(r.majorVersion,10),string:r.version},a.length>1&&(s.version.minor=parseInt(a[1],10)),a.length>2&&(s.version.build=parseInt(a[2],10))}r.platform&&(s[r.platform]=!0), +(s.chrome||s.opr||s.safari)&&(s.webkit=!0),(s.rv||s.iemobile)&&(s.rv&&delete s.rv,r.browser="msie",s.msie=!0),s.edge&&(delete s.edge,r.browser="msedge",s.msedge=!0),s.opr&&(r.browser="opera",s.opera=!0),s.safari&&s.android&&(r.browser="android",s.android=!0),s.name=r.browser,s.platform=r.platform;for(var o in i)i.hasOwnProperty(o)&&delete i[o];Object.assign(i,s)}(),n.default=i},{}],40:[function(e,t,n){"use strict";function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function r(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","error",i),e.ENABLE_ERROR&&(console.error?console.error(i):console.warn?console.warn(i):console.log(i))}},{key:"i",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","info",i),e.ENABLE_INFO&&(console.info?console.info(i):console.log(i))}},{key:"w",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","warn",i),e.ENABLE_WARN&&(console.warn?console.warn(i):console.log(i))}},{key:"d",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","debug",i),e.ENABLE_DEBUG&&(console.debug?console.debug(i):console.log(i))}},{key:"v",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","verbose",i),e.ENABLE_VERBOSE&&console.log(i)}}]),e}();o.GLOBAL_TAG="flv.js",o.FORCE_GLOBAL_TAG=!1,o.ENABLE_ERROR=!0,o.ENABLE_INFO=!0,o.ENABLE_WARN=!0,o.ENABLE_DEBUG=!0,o.ENABLE_VERBOSE=!0,o.ENABLE_CALLBACK=!1,o.emitter=new a.default,n.default=o},{events:2}],42:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0){var n=e.getConfig();t.emit("change",n)}}},{key:"registerListener",value:function(t){e.emitter.addListener("change",t)}},{key:"removeListener",value:function(t){e.emitter.removeListener("change",t)}},{key:"addLogListener",value:function(t){l.default.emitter.addListener("log",t),l.default.emitter.listenerCount("log")>0&&(l.default.ENABLE_CALLBACK=!0,e._notifyChange())}},{key:"removeLogListener",value:function(t){l.default.emitter.removeListener("log",t),0===l.default.emitter.listenerCount("log")&&(l.default.ENABLE_CALLBACK=!1,e._notifyChange())}},{key:"forceGlobalTag",get:function(){return l.default.FORCE_GLOBAL_TAG},set:function(t){l.default.FORCE_GLOBAL_TAG=t,e._notifyChange()}},{key:"globalTag",get:function(){return l.default.GLOBAL_TAG},set:function(t){l.default.GLOBAL_TAG=t,e._notifyChange()}},{key:"enableAll",get:function(){return l.default.ENABLE_VERBOSE&&l.default.ENABLE_DEBUG&&l.default.ENABLE_INFO&&l.default.ENABLE_WARN&&l.default.ENABLE_ERROR},set:function(t){l.default.ENABLE_VERBOSE=t,l.default.ENABLE_DEBUG=t,l.default.ENABLE_INFO=t,l.default.ENABLE_WARN=t,l.default.ENABLE_ERROR=t,e._notifyChange()}},{key:"enableDebug",get:function(){return l.default.ENABLE_DEBUG},set:function(t){l.default.ENABLE_DEBUG=t,e._notifyChange()}},{key:"enableVerbose",get:function(){return l.default.ENABLE_VERBOSE},set:function(t){l.default.ENABLE_VERBOSE=t,e._notifyChange()}},{key:"enableInfo",get:function(){return l.default.ENABLE_INFO},set:function(t){l.default.ENABLE_INFO=t,e._notifyChange()}},{key:"enableWarn",get:function(){return l.default.ENABLE_WARN},set:function(t){l.default.ENABLE_WARN=t,e._notifyChange()}},{key:"enableError",get:function(){return l.default.ENABLE_ERROR},set:function(t){l.default.ENABLE_ERROR=t,e._notifyChange()}}]),e}();d.emitter=new o.default,n.default=d},{"./logger.js":41,events:2}],43:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=128){t.push(String.fromCharCode(65535&a)),r+=2;continue}}}else if(n[r]<240){if(i(n,r,2)){var o=(15&n[r])<<12|(63&n[r+1])<<6|63&n[r+2];if(o>=2048&&55296!=(63488&o)){t.push(String.fromCharCode(65535&o)),r+=3;continue}}}else if(n[r]<248&&i(n,r,3)){var u=(7&n[r])<<18|(63&n[r+1])<<12|(63&n[r+2])<<6|63&n[r+3];if(u>65536&&u<1114112){u-=65536,t.push(String.fromCharCode(u>>>10|55296)),t.push(String.fromCharCode(1023&u|56320)),r+=4;continue}}t.push(String.fromCharCode(65533)),++r}return t.join("")}Object.defineProperty(n,"__esModule",{value:!0}),n.default=r},{}]},{},[21])(21)}); +//# sourceMappingURL=flv.min.js.map diff --git a/tools/MP4 Stream/flv.min.js.map b/tools/MP4 Stream/flv.min.js.map new file mode 100644 index 0000000..05e110e --- /dev/null +++ b/tools/MP4 Stream/flv.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/es6-promise/dist/es6-promise.js","node_modules/events/events.js","node_modules/process/browser.js","node_modules/webworkify/index.js","src/config.js","src/core/features.js","src/core/media-info.js","src/core/media-segment-info.js","src/core/mse-controller.js","src/core/mse-events.js","src/core/transmuxer.js","src/core/transmuxing-controller.js","src/core/transmuxing-events.js","src/core/transmuxing-worker.js","src/demux/amf-parser.js","src/demux/demux-errors.js","src/demux/exp-golomb.js","src/demux/flv-demuxer.js","src/demux/sps-parser.js","src/flv.js","src/index.js","src/io/fetch-stream-loader.js","src/io/io-controller.js","src/io/loader.js","src/io/param-seek-handler.js","src/io/range-seek-handler.js","src/io/speed-sampler.js","src/io/websocket-loader.js","src/io/xhr-moz-chunked-loader.js","src/io/xhr-msstream-loader.js","src/io/xhr-range-loader.js","src/player/flv-player.js","src/player/native-player.js","src/player/player-errors.js","src/player/player-events.js","src/remux/aac-silent.js","src/remux/mp4-generator.js","src/remux/mp4-remuxer.js","src/utils/browser.js","src/utils/exception.js","src/utils/logger.js","src/utils/logging-control.js","src/utils/polyfill.js","src/utils/utf8-conv.js"],"names":["f","exports","module","define","amd","g","window","global","self","this","flvjs","e","t","n","r","s","o","u","a","require","i","Error","code","l","call","length","1","_dereq_","factory","ES6Promise","objectOrFunction","x","isFunction","setScheduler","scheduleFn","customSchedulerFn","setAsap","asapFn","asap","useVertxTimer","vertxNext","flush","useSetTimeout","globalSetTimeout","setTimeout","len","callback","queue","undefined","then","onFulfillment","onRejection","_arguments","arguments","parent","child","constructor","noop","PROMISE_ID","makePromise","_state","invokeCallback","_result","subscribe","resolve","object","Constructor","promise","_resolve","selfFulfillment","TypeError","cannotReturnOwn","getThen","error","GET_THEN_ERROR","tryThen","value","fulfillmentHandler","rejectionHandler","handleForeignThenable","thenable","sealed","fulfill","reason","_reject","_label","handleOwnThenable","FULFILLED","REJECTED","handleMaybeThenable","maybeThenable","then$$","publishRejection","_onerror","publish","PENDING","_subscribers","subscribers","settled","detail","ErrorObject","tryCatch","TRY_CATCH_ERROR","hasCallback","succeeded","failed","initializePromise","resolver","nextId","id","Enumerator","input","_instanceConstructor","isArray","_input","_remaining","Array","_enumerate","validationError","all","entries","race","reject","_","needsResolver","needsNew","Promise","polyfill","local","Function","P","promiseToString","Object","prototype","toString","cast","_isArray","arg","scheduleFlush","browserWindow","browserGlobal","BrowserMutationObserver","MutationObserver","WebKitMutationObserver","isNode","process","isWorker","Uint8ClampedArray","importScripts","MessageChannel","nextTick","iterations","observer","node","document","createTextNode","observe","characterData","data","channel","port1","onmessage","port2","postMessage","vertx","runOnLoop","runOnContext","Math","random","substring","_eachEntry","entry","c","resolve$$","_then","_settledAt","_willSettleAt","state","enumerator","_setScheduler","_setAsap","_asap","catch","EventEmitter","_events","_maxListeners","isNumber","isObject","isUndefined","defaultMaxListeners","setMaxListeners","isNaN","emit","type","er","handler","args","listeners","err","context","slice","apply","addListener","listener","m","newListener","push","warned","console","trace","on","once","removeListener","fired","list","position","splice","removeAllListeners","key","listenerCount","evlistener","emitter","defaultSetTimout","defaultClearTimeout","runTimeout","fun","cachedSetTimeout","runClearTimeout","marker","cachedClearTimeout","clearTimeout","cleanUpNextTick","draining","currentQueue","concat","queueIndex","drainQueue","timeout","run","Item","array","title","browser","env","argv","version","versions","off","prependListener","prependOnceListener","name","binding","cwd","chdir","dir","umask","bundleFn","sources","cache","stringify","JSON","fn","options","resolveSources","workerSources","depPath","depKey","wkey","cacheKeys","keys","exp","default","floor","pow","wcache","skey","scache","src","map","join","URL","webkitURL","mozURL","msURL","blob","Blob","bare","workerUrl","createObjectURL","worker","Worker","objectURL","createDefaultConfig","assign","defaultConfig","enableWorker","enableStashBuffer","stashInitialSize","isLive","lazyLoad","lazyLoadMaxDuration","lazyLoadRecoverDuration","deferLoadAfterSourceOpen","autoCleanupMaxBackwardDuration","autoCleanupMinBackwardDuration","statisticsInfoReportInterval","fixAudioTimestampGap","accurateSeek","seekType","seekParamStart","seekParamEnd","rangeLoadZeroStart","customSeekHandler","reuseRedirectedURL","_ioController","_config","Features","MediaSource","isTypeSupported","ioctl","_ioController2","loaderType","destroy","mimeType","videoElement","createElement","canPlay","canPlayType","features","mseFlvPlayback","mseLiveFlvPlayback","networkStreamIO","networkLoaderName","nativeMP4H264Playback","nativeWebmVP8Playback","nativeWebmVP9Playback","supportMSEH264Playback","supportNetworkStreamIO","getNetworkLoaderTypeName","supportNativeMediaPlayback","MediaInfo","_classCallCheck","duration","hasAudio","hasVideo","audioCodec","videoCodec","audioDataRate","videoDataRate","audioSampleRate","audioChannelCount","width","height","fps","profile","level","chromaFormat","sarNum","sarDen","metadata","segments","segmentCount","hasKeyframesIndex","keyframesIndex","audioInfoComplete","videoInfoComplete","milliseconds","table","keyframeIdx","_search","times","index","fileposition","filepositions","idx","last","mid","lbound","ubound","SampleInfo","dts","pts","originalDts","isSync","isSyncPoint","MediaSegmentInfo","beginDts","endDts","beginPts","endPts","originalBeginDts","originalEndDts","syncPoints","firstSample","lastSample","sampleInfo","IDRSampleList","_list","clear","MediaSegmentInfoList","_type","_lastAppendLocation","_searchNearestSegmentBefore","mediaSegmentInfo","msi","lastAppendIdx","insertIdx","segment","getLastSegmentBefore","segmentIdx","_logger","_browser","_mseEvents","_mediaSegmentInfo","_exception","MSEController","config","TAG","_emitter","_events2","autoCleanupSourceBuffer","onSourceOpen","_onSourceOpen","bind","onSourceEnded","_onSourceEnded","onSourceClose","_onSourceClose","onSourceBufferError","_onSourceBufferError","onSourceBufferUpdateEnd","_onSourceBufferUpdateEnd","_mediaSource","_mediaSourceObjectURL","_mediaElement","_isBufferFull","_hasPendingEos","_requireSetMediaDuration","_pendingMediaDuration","_pendingSourceBufferInit","_mimeTypes","video","audio","_sourceBuffers","_lastInitSegments","_pendingSegments","_pendingRemoveRanges","_idrList","detachMediaElement","event","mediaElement","IllegalStateException","ms","addEventListener","ps","sb","readyState","removeSourceBuffer","removeEventListener","endOfStream","_logger2","message","removeAttribute","revokeObjectURL","initSegment","deferred","is","container","codec","firstInitSegment","v","addSourceBuffer","_mseEvents2","ERROR","msg","updating","_doAppendSegments","_browser2","safari","mediaDuration","_updateMediaSourceDuration","mediaSegment","_needCleanupSourceBuffer","_doCleanupSourceBuffer","_hasPendingRemoveRanges","seconds","abort","buffered","start","end","_doRemoveRanges","lastInitSegment","_hasPendingSegments","getLastSyncPointBeforeDts","currentTime","doRemove","removeEnd","current","target","ranges","range","shift","remove","pendingSegments","timestampOffset","currentOffset","targetOffset","delta","abs","byteLength","appendBuffer","hasOwnProperty","appendArray","info","unshift","BUFFER_FULL","pendings","appendInitSegment","SOURCE_OPEN","prr","UPDATE_END","MSEEvents","_loggingControl","_transmuxingController","_transmuxingEvents","_transmuxingWorker","_mediaInfo","Transmuxer","mediaDataSource","work","_worker","_transmuxingWorker2","_workerDestroying","_onWorkerMessage","cmd","param","onLoggingConfigChanged","_onLoggingConfigChanged","_loggingControl2","registerListener","getConfig","_controller","_transmuxingController2","ctl","_transmuxingEvents2","IO_ERROR","_onIOError","DEMUX_ERROR","_onDemuxError","INIT_SEGMENT","_onInitSegment","MEDIA_SEGMENT","_onMediaSegment","LOADING_COMPLETE","_onLoadingComplete","RECOVERED_EARLY_EOF","_onRecoveredEarlyEof","MEDIA_INFO","_onMediaInfo","STATISTICS_INFO","_onStatisticsInfo","RECOMMEND_SEEKPOINT","_onRecommendSeekpoint","stop","seek","pause","resume","_this","_this2","_this3","_this4","mediaInfo","_this5","statisticsInfo","_this6","_this7","_this8","_this9","terminate","setPrototypeOf","_mediaInfo2","logcat","_flvDemuxer","_mp4Remuxer","_demuxErrors","TransmuxingController","filesize","url","cors","withCredentials","_mediaDataSource","_currentSegmentIndex","totalDuration","forEach","timestampBase","referrerPolicy","_demuxer","_remuxer","_ioctl","_pendingSeekTime","_pendingResolveSeekPoint","_statisticsReporter","_disableStatisticsReporter","_loadSegment","_enableStatisticsReporter","segmentIndex","optionalFrom","dataSource","onError","_onIOException","onSeeked","_onIOSeeked","onComplete","_onIOComplete","onRedirect","_onIORedirect","onRecoveredEarlyEof","_onIORecoveredEarlyEof","bindDataSource","onDataArrival","_onInitChunkArrival","open","_internalAbort","isWorking","isPaused","isSeekable","targetSegmentIndex","_searchSegmentIndexContains","segmentInfo","keyframe","getNearestKeyframe","targetSegmentInfo","insertDiscontinuity","_keyframe","resetMediaInfo","_reportSegmentMediaInfo","byteStart","probeData","consumed","parseChunks","_flvDemuxer2","probe","match","_mp4Remuxer2","mds","overridedDuration","overridedHasAudio","overridedHasVideo","_onDemuxException","onMediaInfo","onInitSegment","_onRemuxerInitSegmentArrival","onMediaSegment","_onRemuxerMediaSegmentArrival","_demuxErrors2","FORMAT_UNSUPPORTED","extraData","nextSegmentIndex","redirectedURL","seekpoint","setInterval","_reportStatisticsInfo","clearInterval","exportInfo","currentURL","hasRedirect","currentRedirectedURL","speed","currentSpeed","currentSegmentIndex","totalSegmentCount","TransmuxingEvents","_polyfill","TransmuxingWorker","obj","onLoadingComplete","onStatisticsInfo","statInfo","onIOError","onDemuxError","onRecommendSeekpoint","onLogcatCallback","str","controller","logcatListener","_polyfill2","install","applyConfig","enableCallback","addLogListener","removeLogListener","_utf8Conv","le","buf","ArrayBuffer","DataView","setInt16","Int16Array","AMF","arrayBuffer","dataOffset","dataSize","parseValue","size","parseString","isObjectEnd","objectEnd","parseObject","getUint16","_utf8Conv2","Uint8Array","getUint32","timestamp","getFloat64","getInt16","Date","offset","getUint8","amfstr","terminal","amfobj","_terminal","amfvar","parseVariable","strictArrayLength","val","date","parseDate","amfLongStr","w","DemuxErrors","OK","FORMAT_ERROR","CODEC_UNSUPPORTED","ExpGolomb","uint8array","_buffer","_buffer_index","_total_bytes","_total_bits","_current_word","_current_word_bits_left","buffer_bytes_left","bytes_read","min","word","set","subarray","buffer","bits","InvalidArgumentException","result","bits_need_left","_fillCurrentWord","bits_read_next","result2","readBits","zero_count","_skipLeadingZero","leading_zeros","readUEG","ReadBig32","_amfParser","_spsParser","FLVDemuxer","_onError","_onTrackMetadata","_onDataAvailable","_dataOffset","_firstParse","_dispatch","_hasAudio","hasAudioTrack","_hasVideo","hasVideoTrack","_hasAudioFlagOverrided","_hasVideoFlagOverrided","_audioInitialMetadataDispatched","_videoInitialMetadataDispatched","_metadata","_audioMetadata","_videoMetadata","_naluLengthSize","_timestampBase","_timescale","_duration","_durationOverrided","_referenceFrameRate","fixed","fps_num","fps_den","_flvSoundRateTable","_mpegSamplingRates","_mpegAudioV10SampleRateTable","_mpegAudioV20SampleRateTable","_mpegAudioV25SampleRateTable","_mpegAudioL1BitRateTable","_mpegAudioL2BitRateTable","_mpegAudioL3BitRateTable","_videoTrack","sequenceNumber","samples","_audioTrack","_littleEndian","loader","chunk","_v","tagType","ts2","ts1","ts0","ts3","_parseAudioData","_parseVideoData","_parseScriptData","prevTagSize","_isInitialMetadataDispatched","scriptData","_amfParser2","parseScriptData","onMetaData","_typeof","audiodatarate","videodatarate","framerate","keyframes","_parseKeyframesIndex","isComplete","time","tagTimestamp","soundSpec","soundFormat","soundRate","soundRateIndex","soundType","meta","track","timescale","channelCount","aacData","_parseAACAudioData","packetType","misc","samplingRate","originalCodec","refSampleDuration","mi","aacSample","unit","_misc","_parseMP3AudioData","_mi","bitRate","_dts","mp3Sample","_parseAACAudioSpecificConfig","audioObjectType","originalAudioObjectType","samplingIndex","extensionSamplingIndex","samplingFrequence","channelConfig","userAgent","navigator","toLowerCase","indexOf","requestHeader","ver","layer","bitrate_index","sampling_freq_index","channel_mode","channel_count","sample_rate","bit_rate","tagPosition","spec","frameType","codecId","_parseAVCVideoPacket","cts","_parseAVCDecoderConfigurationRecord","_parseAVCVideoData","avcc","avcProfile","spsCount","sps","_spsParser2","parseSPS","codecWidth","codec_size","codecHeight","presentWidth","present_size","presentHeight","profile_string","level_string","bitDepth","bit_depth","chroma_format","sarRatio","sar_ratio","frameRate","frame_rate","codecArray","codecString","j","h","chroma_format_string","ppsCount","_i","_len","units","lengthSize","naluSize","unitType","avcSample","isKeyframe","base","mismatch","_expGolomb","SPSParser","src_length","dst","dst_idx","rbsp","_ebsp2rbsp","gb","_expGolomb2","readByte","profile_idc","level_idc","getProfileString","getLevelString","chroma_format_idc","chroma_format_table","readBool","scaling_list_count","_skipScalingList","pic_order_cnt_type","readSEG","num_ref_frames_in_pic_order_cnt_cycle","pic_width_in_mbs_minus1","pic_height_in_map_units_minus1","frame_mbs_only_flag","frame_crop_left_offset","frame_crop_right_offset","frame_crop_top_offset","frame_crop_bottom_offset","sar_width","sar_height","fps_fixed","aspect_ratio_idc","sar_w_table","sar_h_table","num_units_in_tick","time_scale","sarScale","crop_unit_x","crop_unit_y","sub_wc","sub_hc","codec_width","codec_height","present_width","ceil","getChromaFormatString","count","last_scale","next_scale","delta_scale","toFixed","chroma","createPlayer","optionalConfig","_flvPlayer2","_nativePlayer2","isSupported","_features2","getFeatureList","_features","_flvPlayer","_nativePlayer","_playerEvents","_playerErrors","Events","_playerEvents2","ErrorTypes","ErrorDetails","FlvPlayer","NativePlayer","LoggingControl","defineProperty","enumerable","get","_loader","FetchStreamLoader","seekHandler","_possibleConstructorReturn","__proto__","getPrototypeOf","_seekHandler","_needStash","_requestAbort","_contentLength","_receivedLength","isWorkWellEdge","msedge","minor","browserNotBlacklisted","fetch","ReadableStream","_get","_dataSource","_range","sourceURL","seekConfig","headers","Headers","configHeaders","append","params","method","mode","credentials","_status","LoaderStatus","kConnecting","res","kIdle","ok","status","_onURLRedirect","removeURLParameters","lengthHeader","parseInt","_onContentLengthKnown","_pump","body","getReader","kError","RuntimeException","statusText","LoaderErrors","HTTP_STATUS_CODE_INVALID","EXCEPTION","reader","read","done","kComplete","_onComplete","from","cancel","kBuffering","_onDataArrival","EARLY_EOF","_speedSampler","_fetchStreamLoader","_xhrMozChunkedLoader","_xhrMsstreamLoader","_xhrRangeLoader","_websocketLoader","_rangeSeekHandler","_paramSeekHandler","IOController","_extraData","_stashInitialSize","_stashUsed","_stashSize","_bufferSize","_stashBuffer","_stashByteStart","_enableStash","_loaderClass","_isWebSocketURL","test","_refTotalLength","_totalLength","_fullRequestFlag","_currentRange","_redirectedURL","_speedNormalized","_speedSampler2","_speedNormalizeList","_isEarlyEofReconnecting","_paused","_resumeFrom","_onSeeked","_onRedirect","_selectSeekHandler","_selectLoader","_createLoader","_rangeSeekHandler2","paramStart","paramEnd","_paramSeekHandler2","_websocketLoader2","_fetchStreamLoader2","_xhrMozChunkedLoader2","_xhrRangeLoader2","needStashBuffer","onContentLengthKnown","onURLRedirect","_onLoaderChunkArrival","_onLoaderComplete","_onLoaderError","to","reset","bytes","_internalSeek","dropUnconsumed","_flushStashBuffer","requestRange","expectedBytes","bufferNewSize","newBuffer","stashOldArray","normalized","stashSizeKB","bufferSize","_expandBuffer","chunks","contentLength","receivedLength","addBytes","KBps","lastSecondKBps","_normalizeSpeed","_adjustStashSize","_stashArray2","_stashArray3","_consumed2","_dispatchChunks","_remainArray","_consumed3","_remain","remain","stashArray","_stashArray","_consumed","remainArray","UNRECOVERABLE_EARLY_EOF","nextFrom","CONNECTING_TIMEOUT","BaseLoader","typeName","NotImplementedException","ParamSeekHandler","_startName","_endName","baseUrl","needAnd","seekedURL","baseURL","split","queryIndex","resultParams","pairs","pair","requireAnd","RangeSeekHandler","zeroStart","_zeroStart","SpeedSampler","_firstCheckpoint","_lastCheckpoint","_intervalBytes","_totalBytes","_lastSecondBytes","performance","now","_now","durationSeconds","currentKBps","WebSocketLoader","_ws","WebSocket","ws","binaryType","onopen","_onWebSocketOpen","onclose","_onWebSocketClose","_onWebSocketMessage","onerror","_onWebSocketError","close","_dispatchArrayBuffer","FileReader","onload","readAsArrayBuffer","arraybuffer","MozChunkedLoader","_xhr","xhr","XMLHttpRequest","responseType","onreadystatechange","onprogress","onloadend","_requestURL","_onReadyStateChange","_onProgress","_onLoadEnd","_onXhrError","setRequestHeader","send","responseURL","total","response","loaded","MSStreamLoader","_reader","_totalRange","_currentRequestURL","_currentRedirectedURL","_bufferLimit","_lastTimeBufferSize","_isReconnecting","MSStream","MSStreamReader","_internalOpen","isSubrange","_msrOnProgress","_msrOnLoad","_msrOnError","_xhrOnReadyStateChange","_xhrOnError","getResponseHeader","msstream","bigbuffer","_doReconnectIfNeeded","RangeLoader","_chunkSizeKBList","_currentChunkSizeKB","_currentSpeedNormalized","_zeroSpeedChunkCount","_waitForTotalLength","_totalLengthReceived","_currentRequestRange","_lastTimeLoaded","useRefTotalLength","_openSubRange","chunkSize","_onLoad","openNextRange","reportComplete","_transmuxer","_mseController","onvLoadedMetadata","_onvLoadedMetadata","onvSeeking","_onvSeeking","onvCanPlay","_onvCanPlay","onvStalled","_onvStalled","onvProgress","_onvProgress","_requestSetTime","_seekpointRecord","_progressChecker","_msectl","_mseSourceOpened","_hasPendingLoad","_receivedCanPlay","_statisticsInfo","chromeNeedIDRFix","chrome","major","build","_alwaysSeekKeyframe","msie","unload","_mseController2","_onmseUpdateEnd","_onmseBufferFull","load","MEDIA_ERROR","MEDIA_MSE_ERROR","attachMediaElement","_transmuxer2","appendMediaSegment","_suspendTransmuxer","NETWORK_ERROR","_fillStatisticsInfo","play","playerType","HTMLVideoElement","hasQualityInfo","decoded","dropped","getVideoPlaybackQuality","quality","totalVideoFrames","droppedVideoFrames","webkitDecodedFrameCount","webkitDroppedFrameCount","decodedFrames","droppedFrames","currentRangeEnd","_checkProgressAndResume","needResume","directSeek","_isTimepointBuffered","directSeekBegin","directSeekBeginTime","videoBeginTime","idr","recordTime","_checkAndApplyUnbufferedSeekpoint","stalled","media","seekPoint","_checkAndResumeStuckPlayback","volume","muted","preload","mediaPrefix","HTMLAudioElement","videoWidth","videoHeight","OTHER_ERROR","NETWORK_EXCEPTION","NETWORK_STATUS_CODE_INVALID","NETWORK_TIMEOUT","NETWORK_UNRECOVERABLE_EARLY_EOF","MEDIA_FORMAT_ERROR","MEDIA_FORMAT_UNSUPPORTED","MEDIA_CODEC_UNSUPPORTED","PlayerEvents","AAC","MP4","types","avc1","avcC","btrt","dinf","dref","esds","ftyp","hdlr","mdat","mdhd","mdia","mfhd","minf","moof","moov","mp4a","mvex","mvhd","sdtp","stbl","stco","stsc","stsd","stsz","stts","tfdt","tfhd","traf","trak","trun","trex","tkhd","vmhd","smhd",".mp3","charCodeAt","constants","FTYP","STSD_PREFIX","STTS","STSC","STCO","STSZ","HDLR_VIDEO","HDLR_AUDIO","DREF","SMHD","VMHD","datas","arrayCount","box","trackId","xmhd","mp3","sampleRate","configSize","baseMediaDecodeTime","sampleCount","flags","isLeading","dependsOn","isDependedOn","hasRedundancy","isNonSync","init","_mp4Generator","_aacSilent","MP4Remuxer","_isLive","_dtsBase","_dtsBaseInited","_audioDtsBase","Infinity","_videoDtsBase","_audioNextDts","_videoNextDts","_audioMeta","_videoMeta","_audioSegmentInfoList","_videoSegmentInfoList","_forceFirstIDR","_fillSilentAfterSeek","_mp3UseMpegAudio","firefox","_fillAudioTimestampGap","producer","onDataAvailable","remux","onTrackMetadata","_onTrackMetadataReceived","audioTrack","videoTrack","_calculateDtsBase","_remuxVideo","_remuxAudio","metabox","_mp4Generator2","generateInitSegment","dtsCorrection","firstDts","lastDts","mpegRawTrack","firstSegmentAfterSeek","insertPrefixSilentFrame","mdatbox","mdatBytes","firstSampleOriginalDts","isEmpty","getLastSampleBefore","distance","expectedDts","firstSampleDts","videoSegment","silentUnit","_aacSilent2","getSilentFrame","silentFrameDuration","mp4Samples","sample","sampleDuration","needFillSilentFrames","silentFrames","frameCount","currentDts","round","_silentUnit","intDts","previousFrame","frame","lastFrame","_unit","latest","moofbox","_mergeBoxes","firstPts","lastPts","syncPoint","appendSyncPoint","_i2","Browser","ua","exec","platform_match","matched","majorVersion","platform","versionArray","string","opr","webkit","rv","iemobile","edge","android","_message","Log","tag","FORCE_GLOBAL_TAG","GLOBAL_TAG","ENABLE_CALLBACK","ENABLE_ERROR","warn","log","ENABLE_INFO","ENABLE_WARN","ENABLE_DEBUG","debug","ENABLE_VERBOSE","globalTag","forceGlobalTag","enableVerbose","enableDebug","enableInfo","enableWarn","enableError","_notifyChange","enable","Polyfill","proto","output","source","checkContinuation","checkLength","decodeUTF8","out","String","fromCharCode","ucs4","_ucs","_ucs2"],"mappings":"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","file":"flv.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o postsJSON\n values[1] // => commentsJSON\n\n return values;\n });\n ```\n\n @class Promise\n @param {function} resolver\n Useful for tooling.\n @constructor\n*/\nfunction Promise(resolver) {\n this[PROMISE_ID] = nextId();\n this._result = this._state = undefined;\n this._subscribers = [];\n\n if (noop !== resolver) {\n typeof resolver !== 'function' && needsResolver();\n this instanceof Promise ? initializePromise(this, resolver) : needsNew();\n }\n}\n\nPromise.all = all;\nPromise.race = race;\nPromise.resolve = resolve;\nPromise.reject = reject;\nPromise._setScheduler = setScheduler;\nPromise._setAsap = setAsap;\nPromise._asap = asap;\n\nPromise.prototype = {\n constructor: Promise,\n\n /**\n The primary way of interacting with a promise is through its `then` method,\n which registers callbacks to receive either a promise's eventual value or the\n reason why the promise cannot be fulfilled.\n \n ```js\n findUser().then(function(user){\n // user is available\n }, function(reason){\n // user is unavailable, and you are given the reason why\n });\n ```\n \n Chaining\n --------\n \n The return value of `then` is itself a promise. This second, 'downstream'\n promise is resolved with the return value of the first promise's fulfillment\n or rejection handler, or rejected if the handler throws an exception.\n \n ```js\n findUser().then(function (user) {\n return user.name;\n }, function (reason) {\n return 'default name';\n }).then(function (userName) {\n // If `findUser` fulfilled, `userName` will be the user's name, otherwise it\n // will be `'default name'`\n });\n \n findUser().then(function (user) {\n throw new Error('Found user, but still unhappy');\n }, function (reason) {\n throw new Error('`findUser` rejected and we're unhappy');\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.\n // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.\n });\n ```\n If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.\n \n ```js\n findUser().then(function (user) {\n throw new PedagogicalException('Upstream error');\n }).then(function (value) {\n // never reached\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // The `PedgagocialException` is propagated all the way down to here\n });\n ```\n \n Assimilation\n ------------\n \n Sometimes the value you want to propagate to a downstream promise can only be\n retrieved asynchronously. This can be achieved by returning a promise in the\n fulfillment or rejection handler. The downstream promise will then be pending\n until the returned promise is settled. This is called *assimilation*.\n \n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // The user's comments are now available\n });\n ```\n \n If the assimliated promise rejects, then the downstream promise will also reject.\n \n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // If `findCommentsByAuthor` fulfills, we'll have the value here\n }, function (reason) {\n // If `findCommentsByAuthor` rejects, we'll have the reason here\n });\n ```\n \n Simple Example\n --------------\n \n Synchronous Example\n \n ```javascript\n let result;\n \n try {\n result = findResult();\n // success\n } catch(reason) {\n // failure\n }\n ```\n \n Errback Example\n \n ```js\n findResult(function(result, err){\n if (err) {\n // failure\n } else {\n // success\n }\n });\n ```\n \n Promise Example;\n \n ```javascript\n findResult().then(function(result){\n // success\n }, function(reason){\n // failure\n });\n ```\n \n Advanced Example\n --------------\n \n Synchronous Example\n \n ```javascript\n let author, books;\n \n try {\n author = findAuthor();\n books = findBooksByAuthor(author);\n // success\n } catch(reason) {\n // failure\n }\n ```\n \n Errback Example\n \n ```js\n \n function foundBooks(books) {\n \n }\n \n function failure(reason) {\n \n }\n \n findAuthor(function(author, err){\n if (err) {\n failure(err);\n // failure\n } else {\n try {\n findBoooksByAuthor(author, function(books, err) {\n if (err) {\n failure(err);\n } else {\n try {\n foundBooks(books);\n } catch(reason) {\n failure(reason);\n }\n }\n });\n } catch(error) {\n failure(err);\n }\n // success\n }\n });\n ```\n \n Promise Example;\n \n ```javascript\n findAuthor().\n then(findBooksByAuthor).\n then(function(books){\n // found books\n }).catch(function(reason){\n // something went wrong\n });\n ```\n \n @method then\n @param {Function} onFulfilled\n @param {Function} onRejected\n Useful for tooling.\n @return {Promise}\n */\n then: then,\n\n /**\n `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same\n as the catch block of a try/catch statement.\n \n ```js\n function findAuthor(){\n throw new Error('couldn't find that author');\n }\n \n // synchronous\n try {\n findAuthor();\n } catch(reason) {\n // something went wrong\n }\n \n // async with promises\n findAuthor().catch(function(reason){\n // something went wrong\n });\n ```\n \n @method catch\n @param {Function} onRejection\n Useful for tooling.\n @return {Promise}\n */\n 'catch': function _catch(onRejection) {\n return this.then(null, onRejection);\n }\n};\n\nfunction polyfill() {\n var local = undefined;\n\n if (typeof global !== 'undefined') {\n local = global;\n } else if (typeof self !== 'undefined') {\n local = self;\n } else {\n try {\n local = Function('return this')();\n } catch (e) {\n throw new Error('polyfill failed because global object is unavailable in this environment');\n }\n }\n\n var P = local.Promise;\n\n if (P) {\n var promiseToString = null;\n try {\n promiseToString = Object.prototype.toString.call(P.resolve());\n } catch (e) {\n // silently ignored\n }\n\n if (promiseToString === '[object Promise]' && !P.cast) {\n return;\n }\n }\n\n local.Promise = Promise;\n}\n\n// Strange compat..\nPromise.polyfill = polyfill;\nPromise.Promise = Promise;\n\nreturn Promise;\n\n})));\n//# sourceMappingURL=es6-promise.map\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n args = Array.prototype.slice.call(arguments, 1);\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n args = Array.prototype.slice.call(arguments, 1);\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","var bundleFn = arguments[3];\nvar sources = arguments[4];\nvar cache = arguments[5];\n\nvar stringify = JSON.stringify;\n\nmodule.exports = function (fn, options) {\n var wkey;\n var cacheKeys = Object.keys(cache);\n\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n var exp = cache[key].exports;\n // Using babel as a transpiler to use esmodule, the export will always\n // be an object with the default export as a property of it. To ensure\n // the existing api and babel esmodule exports are both supported we\n // check for both\n if (exp === fn || exp && exp.default === fn) {\n wkey = key;\n break;\n }\n }\n\n if (!wkey) {\n wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n var wcache = {};\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n wcache[key] = key;\n }\n sources[wkey] = [\n Function(['require','module','exports'], '(' + fn + ')(self)'),\n wcache\n ];\n }\n var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n\n var scache = {}; scache[wkey] = wkey;\n sources[skey] = [\n Function(['require'], (\n // try to call default if defined to also support babel esmodule\n // exports\n 'var f = require(' + stringify(wkey) + ');' +\n '(f.default ? f.default : f)(self);'\n )),\n scache\n ];\n\n var workerSources = {};\n resolveSources(skey);\n\n function resolveSources(key) {\n workerSources[key] = true;\n\n for (var depPath in sources[key][1]) {\n var depKey = sources[key][1][depPath];\n if (!workerSources[depKey]) {\n resolveSources(depKey);\n }\n }\n }\n\n var src = '(' + bundleFn + ')({'\n + Object.keys(workerSources).map(function (key) {\n return stringify(key) + ':['\n + sources[key][0]\n + ',' + stringify(sources[key][1]) + ']'\n ;\n }).join(',')\n + '},{},[' + stringify(skey) + '])'\n ;\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n var blob = new Blob([src], { type: 'text/javascript' });\n if (options && options.bare) { return blob; }\n var workerUrl = URL.createObjectURL(blob);\n var worker = new Worker(workerUrl);\n worker.objectURL = workerUrl;\n return worker;\n};\n","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const defaultConfig = {\n enableWorker: false,\n enableStashBuffer: true,\n stashInitialSize: undefined,\n\n isLive: false,\n\n lazyLoad: true,\n lazyLoadMaxDuration: 3 * 60,\n lazyLoadRecoverDuration: 30,\n deferLoadAfterSourceOpen: true,\n\n // autoCleanupSourceBuffer: default as false, leave unspecified\n autoCleanupMaxBackwardDuration: 3 * 60,\n autoCleanupMinBackwardDuration: 2 * 60,\n\n statisticsInfoReportInterval: 600,\n\n fixAudioTimestampGap: true,\n\n accurateSeek: false,\n seekType: 'range', // [range, param, custom]\n seekParamStart: 'bstart',\n seekParamEnd: 'bend',\n rangeLoadZeroStart: false,\n customSeekHandler: undefined,\n reuseRedirectedURL: false\n // referrerPolicy: leave as unspecified\n};\n\nexport function createDefaultConfig() {\n return Object.assign({}, defaultConfig);\n}","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport IOController from '../io/io-controller.js';\nimport {createDefaultConfig} from '../config.js';\n\nclass Features {\n\n static supportMSEH264Playback() {\n return window.MediaSource &&\n window.MediaSource.isTypeSupported('video/mp4; codecs=\"avc1.42E01E,mp4a.40.2\"');\n }\n\n static supportNetworkStreamIO() {\n let ioctl = new IOController({}, createDefaultConfig());\n let loaderType = ioctl.loaderType;\n ioctl.destroy();\n return loaderType == 'fetch-stream-loader' || loaderType == 'xhr-moz-chunked-loader';\n }\n\n static getNetworkLoaderTypeName() {\n let ioctl = new IOController({}, createDefaultConfig());\n let loaderType = ioctl.loaderType;\n ioctl.destroy();\n return loaderType;\n }\n\n static supportNativeMediaPlayback(mimeType) {\n if (Features.videoElement == undefined) {\n Features.videoElement = window.document.createElement('video');\n }\n let canPlay = Features.videoElement.canPlayType(mimeType);\n return canPlay === 'probably' || canPlay == 'maybe';\n }\n\n static getFeatureList() {\n let features = {\n mseFlvPlayback: false,\n mseLiveFlvPlayback: false,\n networkStreamIO: false,\n networkLoaderName: '',\n nativeMP4H264Playback: false,\n nativeWebmVP8Playback: false,\n nativeWebmVP9Playback: false\n };\n\n features.mseFlvPlayback = Features.supportMSEH264Playback();\n features.networkStreamIO = Features.supportNetworkStreamIO();\n features.networkLoaderName = Features.getNetworkLoaderTypeName();\n features.mseLiveFlvPlayback = features.mseFlvPlayback && features.networkStreamIO;\n features.nativeMP4H264Playback = Features.supportNativeMediaPlayback('video/mp4; codecs=\"avc1.42001E, mp4a.40.2\"');\n features.nativeWebmVP8Playback = Features.supportNativeMediaPlayback('video/webm; codecs=\"vp8.0, vorbis\"');\n features.nativeWebmVP9Playback = Features.supportNativeMediaPlayback('video/webm; codecs=\"vp9\"');\n\n return features;\n }\n\n}\n\nexport default Features;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass MediaInfo {\n\n constructor() {\n this.mimeType = null;\n this.duration = null;\n\n this.hasAudio = null;\n this.hasVideo = null;\n this.audioCodec = null;\n this.videoCodec = null;\n this.audioDataRate = null;\n this.videoDataRate = null;\n\n this.audioSampleRate = null;\n this.audioChannelCount = null;\n\n this.width = null;\n this.height = null;\n this.fps = null;\n this.profile = null;\n this.level = null;\n this.chromaFormat = null;\n this.sarNum = null;\n this.sarDen = null;\n\n this.metadata = null;\n this.segments = null; // MediaInfo[]\n this.segmentCount = null;\n this.hasKeyframesIndex = null;\n this.keyframesIndex = null;\n }\n\n isComplete() {\n let audioInfoComplete = (this.hasAudio === false) ||\n (this.hasAudio === true &&\n this.audioCodec != null &&\n this.audioSampleRate != null &&\n this.audioChannelCount != null);\n\n let videoInfoComplete = (this.hasVideo === false) ||\n (this.hasVideo === true &&\n this.videoCodec != null &&\n this.width != null &&\n this.height != null &&\n this.fps != null &&\n this.profile != null &&\n this.level != null &&\n this.chromaFormat != null &&\n this.sarNum != null &&\n this.sarDen != null);\n\n // keyframesIndex may not be present\n return this.mimeType != null &&\n this.duration != null &&\n this.metadata != null &&\n this.hasKeyframesIndex != null &&\n audioInfoComplete &&\n videoInfoComplete;\n }\n\n isSeekable() {\n return this.hasKeyframesIndex === true;\n }\n\n getNearestKeyframe(milliseconds) {\n if (this.keyframesIndex == null) {\n return null;\n }\n\n let table = this.keyframesIndex;\n let keyframeIdx = this._search(table.times, milliseconds);\n\n return {\n index: keyframeIdx,\n milliseconds: table.times[keyframeIdx],\n fileposition: table.filepositions[keyframeIdx]\n };\n }\n\n _search(list, value) {\n let idx = 0;\n\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (value < list[0]) {\n idx = 0;\n lbound = ubound + 1; // skip search\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (value >= list[mid] && value < list[mid + 1])) {\n idx = mid;\n break;\n } else if (list[mid] < value) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n\n return idx;\n }\n\n}\n\nexport default MediaInfo;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Represents an media sample (audio / video)\nexport class SampleInfo {\n\n constructor(dts, pts, duration, originalDts, isSync) {\n this.dts = dts;\n this.pts = pts;\n this.duration = duration;\n this.originalDts = originalDts;\n this.isSyncPoint = isSync;\n this.fileposition = null;\n }\n\n}\n\n// Media Segment concept is defined in Media Source Extensions spec.\n// Particularly in ISO BMFF format, an Media Segment contains a moof box followed by a mdat box.\nexport class MediaSegmentInfo {\n\n constructor() {\n this.beginDts = 0;\n this.endDts = 0;\n this.beginPts = 0;\n this.endPts = 0;\n this.originalBeginDts = 0;\n this.originalEndDts = 0;\n this.syncPoints = []; // SampleInfo[n], for video IDR frames only\n this.firstSample = null; // SampleInfo\n this.lastSample = null; // SampleInfo\n }\n\n appendSyncPoint(sampleInfo) { // also called Random Access Point\n sampleInfo.isSyncPoint = true;\n this.syncPoints.push(sampleInfo);\n }\n\n}\n\n// Ordered list for recording video IDR frames, sorted by originalDts\nexport class IDRSampleList {\n\n constructor() {\n this._list = [];\n }\n\n clear() {\n this._list = [];\n }\n\n appendArray(syncPoints) {\n let list = this._list;\n\n if (syncPoints.length === 0) {\n return;\n }\n\n if (list.length > 0 && syncPoints[0].originalDts < list[list.length - 1].originalDts) {\n this.clear();\n }\n\n Array.prototype.push.apply(list, syncPoints);\n }\n\n getLastSyncPointBeforeDts(dts) {\n if (this._list.length == 0) {\n return null;\n }\n\n let list = this._list;\n let idx = 0;\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (dts < list[0].dts) {\n idx = 0;\n lbound = ubound + 1;\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (dts >= list[mid].dts && dts < list[mid + 1].dts)) {\n idx = mid;\n break;\n } else if (list[mid].dts < dts) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n return this._list[idx];\n }\n\n}\n\n// Data structure for recording information of media segments in single track.\nexport class MediaSegmentInfoList {\n\n constructor(type) {\n this._type = type;\n this._list = [];\n this._lastAppendLocation = -1; // cached last insert location\n }\n\n get type() {\n return this._type;\n }\n\n get length() {\n return this._list.length;\n }\n\n isEmpty() {\n return this._list.length === 0;\n }\n\n clear() {\n this._list = [];\n this._lastAppendLocation = -1;\n }\n\n _searchNearestSegmentBefore(originalBeginDts) {\n let list = this._list;\n if (list.length === 0) {\n return -2;\n }\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n let idx = 0;\n\n if (originalBeginDts < list[0].originalBeginDts) {\n idx = -1;\n return idx;\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (originalBeginDts > list[mid].lastSample.originalDts &&\n (originalBeginDts < list[mid + 1].originalBeginDts))) {\n idx = mid;\n break;\n } else if (list[mid].originalBeginDts < originalBeginDts) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n return idx;\n }\n\n _searchNearestSegmentAfter(originalBeginDts) {\n return this._searchNearestSegmentBefore(originalBeginDts) + 1;\n }\n\n append(mediaSegmentInfo) {\n let list = this._list;\n let msi = mediaSegmentInfo;\n let lastAppendIdx = this._lastAppendLocation;\n let insertIdx = 0;\n\n if (lastAppendIdx !== -1 && lastAppendIdx < list.length &&\n msi.originalBeginDts >= list[lastAppendIdx].lastSample.originalDts &&\n ((lastAppendIdx === list.length - 1) ||\n (lastAppendIdx < list.length - 1 &&\n msi.originalBeginDts < list[lastAppendIdx + 1].originalBeginDts))) {\n insertIdx = lastAppendIdx + 1; // use cached location idx\n } else {\n if (list.length > 0) {\n insertIdx = this._searchNearestSegmentBefore(msi.originalBeginDts) + 1;\n }\n }\n\n this._lastAppendLocation = insertIdx;\n this._list.splice(insertIdx, 0, msi);\n }\n\n getLastSegmentBefore(originalBeginDts) {\n let idx = this._searchNearestSegmentBefore(originalBeginDts);\n if (idx >= 0) {\n return this._list[idx];\n } else { // -1\n return null;\n }\n }\n\n getLastSampleBefore(originalBeginDts) {\n let segment = this.getLastSegmentBefore(originalBeginDts);\n if (segment != null) {\n return segment.lastSample;\n } else {\n return null;\n }\n }\n\n getLastSyncPointBefore(originalBeginDts) {\n let segmentIdx = this._searchNearestSegmentBefore(originalBeginDts);\n let syncPoints = this._list[segmentIdx].syncPoints;\n while (syncPoints.length === 0 && segmentIdx > 0) {\n segmentIdx--;\n syncPoints = this._list[segmentIdx].syncPoints;\n }\n if (syncPoints.length > 0) {\n return syncPoints[syncPoints.length - 1];\n } else {\n return null;\n }\n }\n\n}","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport MSEEvents from './mse-events.js';\nimport {SampleInfo, IDRSampleList} from './media-segment-info.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\n// Media Source Extensions controller\nclass MSEController {\n\n constructor(config) {\n this.TAG = 'MSEController';\n\n this._config = config;\n this._emitter = new EventEmitter();\n\n if (this._config.isLive && this._config.autoCleanupSourceBuffer == undefined) {\n // For live stream, do auto cleanup by default\n this._config.autoCleanupSourceBuffer = true;\n }\n\n this.e = {\n onSourceOpen: this._onSourceOpen.bind(this),\n onSourceEnded: this._onSourceEnded.bind(this),\n onSourceClose: this._onSourceClose.bind(this),\n onSourceBufferError: this._onSourceBufferError.bind(this),\n onSourceBufferUpdateEnd: this._onSourceBufferUpdateEnd.bind(this)\n };\n\n this._mediaSource = null;\n this._mediaSourceObjectURL = null;\n this._mediaElement = null;\n\n this._isBufferFull = false;\n this._hasPendingEos = false;\n\n this._requireSetMediaDuration = false;\n this._pendingMediaDuration = 0;\n\n this._pendingSourceBufferInit = [];\n this._mimeTypes = {\n video: null,\n audio: null\n };\n this._sourceBuffers = {\n video: null,\n audio: null\n };\n this._lastInitSegments = {\n video: null,\n audio: null\n };\n this._pendingSegments = {\n video: [],\n audio: []\n };\n this._pendingRemoveRanges = {\n video: [],\n audio: []\n };\n this._idrList = new IDRSampleList();\n }\n\n destroy() {\n if (this._mediaElement || this._mediaSource) {\n this.detachMediaElement();\n }\n this.e = null;\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n attachMediaElement(mediaElement) {\n if (this._mediaSource) {\n throw new IllegalStateException('MediaSource has been attached to an HTMLMediaElement!');\n }\n let ms = this._mediaSource = new window.MediaSource();\n ms.addEventListener('sourceopen', this.e.onSourceOpen);\n ms.addEventListener('sourceended', this.e.onSourceEnded);\n ms.addEventListener('sourceclose', this.e.onSourceClose);\n\n this._mediaElement = mediaElement;\n this._mediaSourceObjectURL = window.URL.createObjectURL(this._mediaSource);\n mediaElement.src = this._mediaSourceObjectURL;\n }\n\n detachMediaElement() {\n if (this._mediaSource) {\n let ms = this._mediaSource;\n for (let type in this._sourceBuffers) {\n // pending segments should be discard\n let ps = this._pendingSegments[type];\n ps.splice(0, ps.length);\n this._pendingSegments[type] = null;\n this._pendingRemoveRanges[type] = null;\n this._lastInitSegments[type] = null;\n\n // remove all sourcebuffers\n let sb = this._sourceBuffers[type];\n if (sb) {\n if (ms.readyState !== 'closed') {\n ms.removeSourceBuffer(sb);\n sb.removeEventListener('error', this.e.onSourceBufferError);\n sb.removeEventListener('updateend', this.e.onSourceBufferUpdateEnd);\n }\n this._mimeTypes[type] = null;\n this._sourceBuffers[type] = null;\n }\n }\n if (ms.readyState === 'open') {\n try {\n ms.endOfStream();\n } catch (error) {\n Log.e(this.TAG, error.message);\n }\n }\n ms.removeEventListener('sourceopen', this.e.onSourceOpen);\n ms.removeEventListener('sourceended', this.e.onSourceEnded);\n ms.removeEventListener('sourceclose', this.e.onSourceClose);\n this._pendingSourceBufferInit = [];\n this._isBufferFull = false;\n this._idrList.clear();\n this._mediaSource = null;\n }\n\n if (this._mediaElement) {\n this._mediaElement.src = '';\n this._mediaElement.removeAttribute('src');\n this._mediaElement = null;\n }\n if (this._mediaSourceObjectURL) {\n window.URL.revokeObjectURL(this._mediaSourceObjectURL);\n this._mediaSourceObjectURL = null;\n }\n }\n\n appendInitSegment(initSegment, deferred) {\n if (!this._mediaSource || this._mediaSource.readyState !== 'open') {\n // sourcebuffer creation requires mediaSource.readyState === 'open'\n // so we defer the sourcebuffer creation, until sourceopen event triggered\n this._pendingSourceBufferInit.push(initSegment);\n // make sure that this InitSegment is in the front of pending segments queue\n this._pendingSegments[initSegment.type].push(initSegment);\n return;\n }\n\n let is = initSegment;\n let mimeType = `${is.container}`;\n if (is.codec && is.codec.length > 0) {\n mimeType += `;codecs=${is.codec}`;\n }\n\n let firstInitSegment = false;\n\n Log.v(this.TAG, 'Received Initialization Segment, mimeType: ' + mimeType);\n this._lastInitSegments[is.type] = is;\n\n if (mimeType !== this._mimeTypes[is.type]) {\n if (!this._mimeTypes[is.type]) { // empty, first chance create sourcebuffer\n firstInitSegment = true;\n try {\n let sb = this._sourceBuffers[is.type] = this._mediaSource.addSourceBuffer(mimeType);\n sb.addEventListener('error', this.e.onSourceBufferError);\n sb.addEventListener('updateend', this.e.onSourceBufferUpdateEnd);\n } catch (error) {\n Log.e(this.TAG, error.message);\n this._emitter.emit(MSEEvents.ERROR, {code: error.code, msg: error.message});\n return;\n }\n } else {\n Log.v(this.TAG, `Notice: ${is.type} mimeType changed, origin: ${this._mimeTypes[is.type]}, target: ${mimeType}`);\n }\n this._mimeTypes[is.type] = mimeType;\n }\n\n if (!deferred) {\n // deferred means this InitSegment has been pushed to pendingSegments queue\n this._pendingSegments[is.type].push(is);\n }\n if (!firstInitSegment) { // append immediately only if init segment in subsequence\n if (this._sourceBuffers[is.type] && !this._sourceBuffers[is.type].updating) {\n this._doAppendSegments();\n }\n }\n if (Browser.safari && is.container === 'audio/mpeg' && is.mediaDuration > 0) {\n // 'audio/mpeg' track under Safari may cause MediaElement's duration to be NaN\n // Manually correct MediaSource.duration to make progress bar seekable, and report right duration\n this._requireSetMediaDuration = true;\n this._pendingMediaDuration = is.mediaDuration / 1000; // in seconds\n this._updateMediaSourceDuration();\n }\n }\n\n appendMediaSegment(mediaSegment) {\n let ms = mediaSegment;\n this._pendingSegments[ms.type].push(ms);\n\n if (this._config.autoCleanupSourceBuffer && this._needCleanupSourceBuffer()) {\n this._doCleanupSourceBuffer();\n }\n\n let sb = this._sourceBuffers[ms.type];\n if (sb && !sb.updating && !this._hasPendingRemoveRanges()) {\n this._doAppendSegments();\n }\n }\n\n seek(seconds) {\n // remove all appended buffers\n for (let type in this._sourceBuffers) {\n if (!this._sourceBuffers[type]) {\n continue;\n }\n\n // abort current buffer append algorithm\n let sb = this._sourceBuffers[type];\n if (this._mediaSource.readyState === 'open') {\n try {\n // If range removal algorithm is running, InvalidStateError will be throwed\n // Ignore it.\n sb.abort();\n } catch (error) {\n Log.e(this.TAG, error.message);\n }\n }\n\n // IDRList should be clear\n this._idrList.clear();\n\n // pending segments should be discard\n let ps = this._pendingSegments[type];\n ps.splice(0, ps.length);\n\n if (this._mediaSource.readyState === 'closed') {\n // Parent MediaSource object has been detached from HTMLMediaElement\n continue;\n }\n\n // record ranges to be remove from SourceBuffer\n for (let i = 0; i < sb.buffered.length; i++) {\n let start = sb.buffered.start(i);\n let end = sb.buffered.end(i);\n this._pendingRemoveRanges[type].push({start, end});\n }\n\n // if sb is not updating, let's remove ranges now!\n if (!sb.updating) {\n this._doRemoveRanges();\n }\n\n // Safari 10 may get InvalidStateError in the later appendBuffer() after SourceBuffer.remove() call\n // Internal parser's state may be invalid at this time. Re-append last InitSegment to workaround.\n // Related issue: https://bugs.webkit.org/show_bug.cgi?id=159230\n if (Browser.safari) {\n let lastInitSegment = this._lastInitSegments[type];\n if (lastInitSegment) {\n this._pendingSegments[type].push(lastInitSegment);\n if (!sb.updating) {\n this._doAppendSegments();\n }\n }\n }\n }\n }\n\n endOfStream() {\n let ms = this._mediaSource;\n let sb = this._sourceBuffers;\n if (!ms || ms.readyState !== 'open') {\n if (ms && ms.readyState === 'closed' && this._hasPendingSegments()) {\n // If MediaSource hasn't turned into open state, and there're pending segments\n // Mark pending endOfStream, defer call until all pending segments appended complete\n this._hasPendingEos = true;\n }\n return;\n }\n if (sb.video && sb.video.updating || sb.audio && sb.audio.updating) {\n // If any sourcebuffer is updating, defer endOfStream operation\n // See _onSourceBufferUpdateEnd()\n this._hasPendingEos = true;\n } else {\n this._hasPendingEos = false;\n // Notify media data loading complete\n // This is helpful for correcting total duration to match last media segment\n // Otherwise MediaElement's ended event may not be triggered\n ms.endOfStream();\n }\n }\n\n getNearestKeyframe(dts) {\n return this._idrList.getLastSyncPointBeforeDts(dts);\n }\n\n _needCleanupSourceBuffer() {\n if (!this._config.autoCleanupSourceBuffer) {\n return false;\n }\n\n let currentTime = this._mediaElement.currentTime;\n\n for (let type in this._sourceBuffers) {\n let sb = this._sourceBuffers[type];\n if (sb) {\n let buffered = sb.buffered;\n if (buffered.length >= 1) {\n if (currentTime - buffered.start(0) >= this._config.autoCleanupMaxBackwardDuration) {\n return true;\n }\n }\n }\n }\n\n return false;\n }\n\n _doCleanupSourceBuffer() {\n let currentTime = this._mediaElement.currentTime;\n\n for (let type in this._sourceBuffers) {\n let sb = this._sourceBuffers[type];\n if (sb) {\n let buffered = sb.buffered;\n let doRemove = false;\n\n for (let i = 0; i < buffered.length; i++) {\n let start = buffered.start(i);\n let end = buffered.end(i);\n\n if (start <= currentTime && currentTime < end + 3) { // padding 3 seconds\n if (currentTime - start >= this._config.autoCleanupMaxBackwardDuration) {\n doRemove = true;\n let removeEnd = currentTime - this._config.autoCleanupMinBackwardDuration;\n this._pendingRemoveRanges[type].push({start: start, end: removeEnd});\n }\n } else if (end < currentTime) {\n doRemove = true;\n this._pendingRemoveRanges[type].push({start: start, end: end});\n }\n }\n\n if (doRemove && !sb.updating) {\n this._doRemoveRanges();\n }\n }\n }\n }\n\n _updateMediaSourceDuration() {\n let sb = this._sourceBuffers;\n if (this._mediaElement.readyState === 0 || this._mediaSource.readyState !== 'open') {\n return;\n }\n if ((sb.video && sb.video.updating) || (sb.audio && sb.audio.updating)) {\n return;\n }\n\n let current = this._mediaSource.duration;\n let target = this._pendingMediaDuration;\n\n if (target > 0 && (isNaN(current) || target > current)) {\n Log.v(this.TAG, `Update MediaSource duration from ${current} to ${target}`);\n this._mediaSource.duration = target;\n }\n\n this._requireSetMediaDuration = false;\n this._pendingMediaDuration = 0;\n }\n\n _doRemoveRanges() {\n for (let type in this._pendingRemoveRanges) {\n if (!this._sourceBuffers[type] || this._sourceBuffers[type].updating) {\n continue;\n }\n let sb = this._sourceBuffers[type];\n let ranges = this._pendingRemoveRanges[type];\n while (ranges.length && !sb.updating) {\n let range = ranges.shift();\n sb.remove(range.start, range.end);\n }\n }\n }\n\n _doAppendSegments() {\n let pendingSegments = this._pendingSegments;\n\n for (let type in pendingSegments) {\n if (!this._sourceBuffers[type] || this._sourceBuffers[type].updating) {\n continue;\n }\n\n if (pendingSegments[type].length > 0) {\n let segment = pendingSegments[type].shift();\n\n if (segment.timestampOffset) {\n // For MPEG audio stream in MSE, if unbuffered-seeking occurred\n // We need explicitly set timestampOffset to the desired point in timeline for mpeg SourceBuffer.\n let currentOffset = this._sourceBuffers[type].timestampOffset;\n let targetOffset = segment.timestampOffset / 1000; // in seconds\n\n let delta = Math.abs(currentOffset - targetOffset);\n if (delta > 0.1) { // If time delta > 100ms\n Log.v(this.TAG, `Update MPEG audio timestampOffset from ${currentOffset} to ${targetOffset}`);\n this._sourceBuffers[type].timestampOffset = targetOffset;\n }\n delete segment.timestampOffset;\n }\n\n if (!segment.data || segment.data.byteLength === 0) {\n // Ignore empty buffer\n continue;\n }\n\n try {\n this._sourceBuffers[type].appendBuffer(segment.data);\n this._isBufferFull = false;\n if (type === 'video' && segment.hasOwnProperty('info')) {\n this._idrList.appendArray(segment.info.syncPoints);\n }\n } catch (error) {\n this._pendingSegments[type].unshift(segment);\n if (error.code === 22) { // QuotaExceededError\n /* Notice that FireFox may not throw QuotaExceededError if SourceBuffer is full\n * Currently we can only do lazy-load to avoid SourceBuffer become scattered.\n * SourceBuffer eviction policy may be changed in future version of FireFox.\n *\n * Related issues:\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1279885\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1280023\n */\n\n // report buffer full, abort network IO\n if (!this._isBufferFull) {\n this._emitter.emit(MSEEvents.BUFFER_FULL);\n }\n this._isBufferFull = true;\n } else {\n Log.e(this.TAG, error.message);\n this._emitter.emit(MSEEvents.ERROR, {code: error.code, msg: error.message});\n }\n }\n }\n }\n }\n\n _onSourceOpen() {\n Log.v(this.TAG, 'MediaSource onSourceOpen');\n this._mediaSource.removeEventListener('sourceopen', this.e.onSourceOpen);\n // deferred sourcebuffer creation / initialization\n if (this._pendingSourceBufferInit.length > 0) {\n let pendings = this._pendingSourceBufferInit;\n while (pendings.length) {\n let segment = pendings.shift();\n this.appendInitSegment(segment, true);\n }\n }\n // there may be some pending media segments, append them\n if (this._hasPendingSegments()) {\n this._doAppendSegments();\n }\n this._emitter.emit(MSEEvents.SOURCE_OPEN);\n }\n\n _onSourceEnded() {\n // fired on endOfStream\n Log.v(this.TAG, 'MediaSource onSourceEnded');\n }\n\n _onSourceClose() {\n // fired on detaching from media element\n Log.v(this.TAG, 'MediaSource onSourceClose');\n if (this._mediaSource && this.e != null) {\n this._mediaSource.removeEventListener('sourceopen', this.e.onSourceOpen);\n this._mediaSource.removeEventListener('sourceended', this.e.onSourceEnded);\n this._mediaSource.removeEventListener('sourceclose', this.e.onSourceClose);\n }\n }\n\n _hasPendingSegments() {\n let ps = this._pendingSegments;\n return ps.video.length > 0 || ps.audio.length > 0;\n }\n\n _hasPendingRemoveRanges() {\n let prr = this._pendingRemoveRanges;\n return prr.video.length > 0 || prr.audio.length > 0;\n }\n\n _onSourceBufferUpdateEnd() {\n if (this._requireSetMediaDuration) {\n this._updateMediaSourceDuration();\n } else if (this._hasPendingRemoveRanges()) {\n this._doRemoveRanges();\n } else if (this._hasPendingSegments()) {\n this._doAppendSegments();\n } else if (this._hasPendingEos) {\n this.endOfStream();\n }\n this._emitter.emit(MSEEvents.UPDATE_END);\n }\n\n _onSourceBufferError(e) {\n Log.e(this.TAG, `SourceBuffer Error: ${e}`);\n // this error might not always be fatal, just ignore it\n }\n\n}\n\nexport default MSEController;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst MSEEvents = {\n ERROR: 'error',\n SOURCE_OPEN: 'source_open',\n UPDATE_END: 'update_end',\n BUFFER_FULL: 'buffer_full'\n};\n\nexport default MSEEvents;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport LoggingControl from '../utils/logging-control.js';\nimport TransmuxingController from './transmuxing-controller.js';\nimport TransmuxingEvents from './transmuxing-events.js';\nimport TransmuxingWorker from './transmuxing-worker.js';\nimport MediaInfo from './media-info.js';\n\nclass Transmuxer {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'Transmuxer';\n this._emitter = new EventEmitter();\n\n if (config.enableWorker && typeof (Worker) !== 'undefined') {\n try {\n let work = require('webworkify');\n this._worker = work(TransmuxingWorker);\n this._workerDestroying = false;\n this._worker.addEventListener('message', this._onWorkerMessage.bind(this));\n this._worker.postMessage({cmd: 'init', param: [mediaDataSource, config]});\n this.e = {\n onLoggingConfigChanged: this._onLoggingConfigChanged.bind(this)\n };\n LoggingControl.registerListener(this.e.onLoggingConfigChanged);\n this._worker.postMessage({cmd: 'logging_config', param: LoggingControl.getConfig()});\n } catch (error) {\n Log.e(this.TAG, 'Error while initialize transmuxing worker, fallback to inline transmuxing');\n this._worker = null;\n this._controller = new TransmuxingController(mediaDataSource, config);\n }\n } else {\n this._controller = new TransmuxingController(mediaDataSource, config);\n }\n\n if (this._controller) {\n let ctl = this._controller;\n ctl.on(TransmuxingEvents.IO_ERROR, this._onIOError.bind(this));\n ctl.on(TransmuxingEvents.DEMUX_ERROR, this._onDemuxError.bind(this));\n ctl.on(TransmuxingEvents.INIT_SEGMENT, this._onInitSegment.bind(this));\n ctl.on(TransmuxingEvents.MEDIA_SEGMENT, this._onMediaSegment.bind(this));\n ctl.on(TransmuxingEvents.LOADING_COMPLETE, this._onLoadingComplete.bind(this));\n ctl.on(TransmuxingEvents.RECOVERED_EARLY_EOF, this._onRecoveredEarlyEof.bind(this));\n ctl.on(TransmuxingEvents.MEDIA_INFO, this._onMediaInfo.bind(this));\n ctl.on(TransmuxingEvents.STATISTICS_INFO, this._onStatisticsInfo.bind(this));\n ctl.on(TransmuxingEvents.RECOMMEND_SEEKPOINT, this._onRecommendSeekpoint.bind(this));\n }\n }\n\n destroy() {\n if (this._worker) {\n if (!this._workerDestroying) {\n this._workerDestroying = true;\n this._worker.postMessage({cmd: 'destroy'});\n LoggingControl.removeListener(this.e.onLoggingConfigChanged);\n this.e = null;\n }\n } else {\n this._controller.destroy();\n this._controller = null;\n }\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n hasWorker() {\n return this._worker != null;\n }\n\n open() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'start'});\n } else {\n this._controller.start();\n }\n }\n\n close() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'stop'});\n } else {\n this._controller.stop();\n }\n }\n\n seek(milliseconds) {\n if (this._worker) {\n this._worker.postMessage({cmd: 'seek', param: milliseconds});\n } else {\n this._controller.seek(milliseconds);\n }\n }\n\n pause() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'pause'});\n } else {\n this._controller.pause();\n }\n }\n\n resume() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'resume'});\n } else {\n this._controller.resume();\n }\n }\n\n _onInitSegment(type, initSegment) {\n // do async invoke\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.INIT_SEGMENT, type, initSegment);\n });\n }\n\n _onMediaSegment(type, mediaSegment) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.MEDIA_SEGMENT, type, mediaSegment);\n });\n }\n\n _onLoadingComplete() {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.LOADING_COMPLETE);\n });\n }\n\n _onRecoveredEarlyEof() {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.RECOVERED_EARLY_EOF);\n });\n }\n\n _onMediaInfo(mediaInfo) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.MEDIA_INFO, mediaInfo);\n });\n }\n\n _onStatisticsInfo(statisticsInfo) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.STATISTICS_INFO, statisticsInfo);\n });\n }\n\n _onIOError(type, info) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.IO_ERROR, type, info);\n });\n }\n\n _onDemuxError(type, info) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.DEMUX_ERROR, type, info);\n });\n }\n\n _onRecommendSeekpoint(milliseconds) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.RECOMMEND_SEEKPOINT, milliseconds);\n });\n }\n\n _onLoggingConfigChanged(config) {\n if (this._worker) {\n this._worker.postMessage({cmd: 'logging_config', param: config});\n }\n }\n\n _onWorkerMessage(e) {\n let message = e.data;\n let data = message.data;\n\n if (message.msg === 'destroyed' || this._workerDestroying) {\n this._workerDestroying = false;\n this._worker.terminate();\n this._worker = null;\n return;\n }\n\n switch (message.msg) {\n case TransmuxingEvents.INIT_SEGMENT:\n case TransmuxingEvents.MEDIA_SEGMENT:\n this._emitter.emit(message.msg, data.type, data.data);\n break;\n case TransmuxingEvents.LOADING_COMPLETE:\n case TransmuxingEvents.RECOVERED_EARLY_EOF:\n this._emitter.emit(message.msg);\n break;\n case TransmuxingEvents.MEDIA_INFO:\n Object.setPrototypeOf(data, MediaInfo.prototype);\n this._emitter.emit(message.msg, data);\n break;\n case TransmuxingEvents.STATISTICS_INFO:\n this._emitter.emit(message.msg, data);\n break;\n case TransmuxingEvents.IO_ERROR:\n case TransmuxingEvents.DEMUX_ERROR:\n this._emitter.emit(message.msg, data.type, data.info);\n break;\n case TransmuxingEvents.RECOMMEND_SEEKPOINT:\n this._emitter.emit(message.msg, data);\n break;\n case 'logcat_callback':\n Log.emitter.emit('log', data.type, data.logcat);\n break;\n default:\n break;\n }\n }\n\n}\n\nexport default Transmuxer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport MediaInfo from './media-info.js';\nimport FLVDemuxer from '../demux/flv-demuxer.js';\nimport MP4Remuxer from '../remux/mp4-remuxer.js';\nimport DemuxErrors from '../demux/demux-errors.js';\nimport IOController from '../io/io-controller.js';\nimport TransmuxingEvents from './transmuxing-events.js';\nimport {LoaderStatus, LoaderErrors} from '../io/loader.js';\n\n// Transmuxing (IO, Demuxing, Remuxing) controller, with multipart support\nclass TransmuxingController {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'TransmuxingController';\n this._emitter = new EventEmitter();\n\n this._config = config;\n\n // treat single part media as multipart media, which has only one segment\n if (!mediaDataSource.segments) {\n mediaDataSource.segments = [{\n duration: mediaDataSource.duration,\n filesize: mediaDataSource.filesize,\n url: mediaDataSource.url\n }];\n }\n\n // fill in default IO params if not exists\n if (typeof mediaDataSource.cors !== 'boolean') {\n mediaDataSource.cors = true;\n }\n if (typeof mediaDataSource.withCredentials !== 'boolean') {\n mediaDataSource.withCredentials = false;\n }\n\n this._mediaDataSource = mediaDataSource;\n this._currentSegmentIndex = 0;\n let totalDuration = 0;\n\n this._mediaDataSource.segments.forEach((segment) => {\n // timestampBase for each segment, and calculate total duration\n segment.timestampBase = totalDuration;\n totalDuration += segment.duration;\n // params needed by IOController\n segment.cors = mediaDataSource.cors;\n segment.withCredentials = mediaDataSource.withCredentials;\n // referrer policy control, if exist\n if (config.referrerPolicy) {\n segment.referrerPolicy = config.referrerPolicy;\n }\n });\n\n if (!isNaN(totalDuration) && this._mediaDataSource.duration !== totalDuration) {\n this._mediaDataSource.duration = totalDuration;\n }\n\n this._mediaInfo = null;\n this._demuxer = null;\n this._remuxer = null;\n this._ioctl = null;\n\n this._pendingSeekTime = null;\n this._pendingResolveSeekPoint = null;\n\n this._statisticsReporter = null;\n }\n\n destroy() {\n this._mediaInfo = null;\n this._mediaDataSource = null;\n\n if (this._statisticsReporter) {\n this._disableStatisticsReporter();\n }\n if (this._ioctl) {\n this._ioctl.destroy();\n this._ioctl = null;\n }\n if (this._demuxer) {\n this._demuxer.destroy();\n this._demuxer = null;\n }\n if (this._remuxer) {\n this._remuxer.destroy();\n this._remuxer = null;\n }\n\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n start() {\n this._loadSegment(0);\n this._enableStatisticsReporter();\n }\n\n _loadSegment(segmentIndex, optionalFrom) {\n this._currentSegmentIndex = segmentIndex;\n let dataSource = this._mediaDataSource.segments[segmentIndex];\n\n let ioctl = this._ioctl = new IOController(dataSource, this._config, segmentIndex);\n ioctl.onError = this._onIOException.bind(this);\n ioctl.onSeeked = this._onIOSeeked.bind(this);\n ioctl.onComplete = this._onIOComplete.bind(this);\n ioctl.onRedirect = this._onIORedirect.bind(this);\n ioctl.onRecoveredEarlyEof = this._onIORecoveredEarlyEof.bind(this);\n\n if (optionalFrom) {\n this._demuxer.bindDataSource(this._ioctl);\n } else {\n ioctl.onDataArrival = this._onInitChunkArrival.bind(this);\n }\n\n ioctl.open(optionalFrom);\n }\n\n stop() {\n this._internalAbort();\n this._disableStatisticsReporter();\n }\n\n _internalAbort() {\n if (this._ioctl) {\n this._ioctl.destroy();\n this._ioctl = null;\n }\n }\n\n pause() { // take a rest\n if (this._ioctl && this._ioctl.isWorking()) {\n this._ioctl.pause();\n this._disableStatisticsReporter();\n }\n }\n\n resume() {\n if (this._ioctl && this._ioctl.isPaused()) {\n this._ioctl.resume();\n this._enableStatisticsReporter();\n }\n }\n\n seek(milliseconds) {\n if (this._mediaInfo == null || !this._mediaInfo.isSeekable()) {\n return;\n }\n\n let targetSegmentIndex = this._searchSegmentIndexContains(milliseconds);\n\n if (targetSegmentIndex === this._currentSegmentIndex) {\n // intra-segment seeking\n let segmentInfo = this._mediaInfo.segments[targetSegmentIndex];\n\n if (segmentInfo == undefined) {\n // current segment loading started, but mediainfo hasn't received yet\n // wait for the metadata loaded, then seek to expected position\n this._pendingSeekTime = milliseconds;\n } else {\n let keyframe = segmentInfo.getNearestKeyframe(milliseconds);\n this._remuxer.seek(keyframe.milliseconds);\n this._ioctl.seek(keyframe.fileposition);\n // Will be resolved in _onRemuxerMediaSegmentArrival()\n this._pendingResolveSeekPoint = keyframe.milliseconds;\n }\n } else {\n // cross-segment seeking\n let targetSegmentInfo = this._mediaInfo.segments[targetSegmentIndex];\n\n if (targetSegmentInfo == undefined) {\n // target segment hasn't been loaded. We need metadata then seek to expected time\n this._pendingSeekTime = milliseconds;\n this._internalAbort();\n this._remuxer.seek();\n this._remuxer.insertDiscontinuity();\n this._loadSegment(targetSegmentIndex);\n // Here we wait for the metadata loaded, then seek to expected position\n } else {\n // We have target segment's metadata, direct seek to target position\n let keyframe = targetSegmentInfo.getNearestKeyframe(milliseconds);\n this._internalAbort();\n this._remuxer.seek(milliseconds);\n this._remuxer.insertDiscontinuity();\n this._demuxer.resetMediaInfo();\n this._demuxer.timestampBase = this._mediaDataSource.segments[targetSegmentIndex].timestampBase;\n this._loadSegment(targetSegmentIndex, keyframe.fileposition);\n this._pendingResolveSeekPoint = keyframe.milliseconds;\n this._reportSegmentMediaInfo(targetSegmentIndex);\n }\n }\n\n this._enableStatisticsReporter();\n }\n\n _searchSegmentIndexContains(milliseconds) {\n let segments = this._mediaDataSource.segments;\n let idx = segments.length - 1;\n\n for (let i = 0; i < segments.length; i++) {\n if (milliseconds < segments[i].timestampBase) {\n idx = i - 1;\n break;\n }\n }\n return idx;\n }\n\n _onInitChunkArrival(data, byteStart) {\n let probeData = null;\n let consumed = 0;\n\n if (byteStart > 0) {\n // IOController seeked immediately after opened, byteStart > 0 callback may received\n this._demuxer.bindDataSource(this._ioctl);\n this._demuxer.timestampBase = this._mediaDataSource.segments[this._currentSegmentIndex].timestampBase;\n\n consumed = this._demuxer.parseChunks(data, byteStart);\n } else if ((probeData = FLVDemuxer.probe(data)).match) {\n // Always create new FLVDemuxer\n this._demuxer = new FLVDemuxer(probeData, this._config);\n\n if (!this._remuxer) {\n this._remuxer = new MP4Remuxer(this._config);\n }\n\n let mds = this._mediaDataSource;\n if (mds.duration != undefined && !isNaN(mds.duration)) {\n this._demuxer.overridedDuration = mds.duration;\n }\n if (typeof mds.hasAudio === 'boolean') {\n this._demuxer.overridedHasAudio = mds.hasAudio;\n }\n if (typeof mds.hasVideo === 'boolean') {\n this._demuxer.overridedHasVideo = mds.hasVideo;\n }\n\n this._demuxer.timestampBase = mds.segments[this._currentSegmentIndex].timestampBase;\n\n this._demuxer.onError = this._onDemuxException.bind(this);\n this._demuxer.onMediaInfo = this._onMediaInfo.bind(this);\n\n this._remuxer.bindDataSource(this._demuxer\n .bindDataSource(this._ioctl\n ));\n\n this._remuxer.onInitSegment = this._onRemuxerInitSegmentArrival.bind(this);\n this._remuxer.onMediaSegment = this._onRemuxerMediaSegmentArrival.bind(this);\n\n consumed = this._demuxer.parseChunks(data, byteStart);\n } else {\n probeData = null;\n Log.e(this.TAG, 'Non-FLV, Unsupported media type!');\n Promise.resolve().then(() => {\n this._internalAbort();\n });\n this._emitter.emit(TransmuxingEvents.DEMUX_ERROR, DemuxErrors.FORMAT_UNSUPPORTED, 'Non-FLV, Unsupported media type');\n\n consumed = 0;\n }\n\n return consumed;\n }\n\n _onMediaInfo(mediaInfo) {\n if (this._mediaInfo == null) {\n // Store first segment's mediainfo as global mediaInfo\n this._mediaInfo = Object.assign({}, mediaInfo);\n this._mediaInfo.keyframesIndex = null;\n this._mediaInfo.segments = [];\n this._mediaInfo.segmentCount = this._mediaDataSource.segments.length;\n Object.setPrototypeOf(this._mediaInfo, MediaInfo.prototype);\n }\n\n let segmentInfo = Object.assign({}, mediaInfo);\n Object.setPrototypeOf(segmentInfo, MediaInfo.prototype);\n this._mediaInfo.segments[this._currentSegmentIndex] = segmentInfo;\n\n // notify mediaInfo update\n this._reportSegmentMediaInfo(this._currentSegmentIndex);\n\n if (this._pendingSeekTime != null) {\n Promise.resolve().then(() => {\n let target = this._pendingSeekTime;\n this._pendingSeekTime = null;\n this.seek(target);\n });\n }\n }\n\n _onIOSeeked() {\n this._remuxer.insertDiscontinuity();\n }\n\n _onIOComplete(extraData) {\n let segmentIndex = extraData;\n let nextSegmentIndex = segmentIndex + 1;\n\n if (nextSegmentIndex < this._mediaDataSource.segments.length) {\n this._internalAbort();\n this._loadSegment(nextSegmentIndex);\n } else {\n this._emitter.emit(TransmuxingEvents.LOADING_COMPLETE);\n this._disableStatisticsReporter();\n }\n }\n\n _onIORedirect(redirectedURL) {\n let segmentIndex = this._ioctl.extraData;\n this._mediaDataSource.segments[segmentIndex].redirectedURL = redirectedURL;\n }\n\n _onIORecoveredEarlyEof() {\n this._emitter.emit(TransmuxingEvents.RECOVERED_EARLY_EOF);\n }\n\n _onIOException(type, info) {\n Log.e(this.TAG, `IOException: type = ${type}, code = ${info.code}, msg = ${info.msg}`);\n this._emitter.emit(TransmuxingEvents.IO_ERROR, type, info);\n this._disableStatisticsReporter();\n }\n\n _onDemuxException(type, info) {\n Log.e(this.TAG, `DemuxException: type = ${type}, info = ${info}`);\n this._emitter.emit(TransmuxingEvents.DEMUX_ERROR, type, info);\n }\n\n _onRemuxerInitSegmentArrival(type, initSegment) {\n this._emitter.emit(TransmuxingEvents.INIT_SEGMENT, type, initSegment);\n }\n\n _onRemuxerMediaSegmentArrival(type, mediaSegment) {\n if (this._pendingSeekTime != null) {\n // Media segments after new-segment cross-seeking should be dropped.\n return;\n }\n this._emitter.emit(TransmuxingEvents.MEDIA_SEGMENT, type, mediaSegment);\n\n // Resolve pending seekPoint\n if (this._pendingResolveSeekPoint != null && type === 'video') {\n let syncPoints = mediaSegment.info.syncPoints;\n let seekpoint = this._pendingResolveSeekPoint;\n this._pendingResolveSeekPoint = null;\n\n // Safari: Pass PTS for recommend_seekpoint\n if (Browser.safari && syncPoints.length > 0 && syncPoints[0].originalDts === seekpoint) {\n seekpoint = syncPoints[0].pts;\n }\n // else: use original DTS (keyframe.milliseconds)\n\n this._emitter.emit(TransmuxingEvents.RECOMMEND_SEEKPOINT, seekpoint);\n }\n }\n\n _enableStatisticsReporter() {\n if (this._statisticsReporter == null) {\n this._statisticsReporter = self.setInterval(\n this._reportStatisticsInfo.bind(this),\n this._config.statisticsInfoReportInterval);\n }\n }\n\n _disableStatisticsReporter() {\n if (this._statisticsReporter) {\n self.clearInterval(this._statisticsReporter);\n this._statisticsReporter = null;\n }\n }\n\n _reportSegmentMediaInfo(segmentIndex) {\n let segmentInfo = this._mediaInfo.segments[segmentIndex];\n let exportInfo = Object.assign({}, segmentInfo);\n\n exportInfo.duration = this._mediaInfo.duration;\n exportInfo.segmentCount = this._mediaInfo.segmentCount;\n delete exportInfo.segments;\n delete exportInfo.keyframesIndex;\n\n this._emitter.emit(TransmuxingEvents.MEDIA_INFO, exportInfo);\n }\n\n _reportStatisticsInfo() {\n let info = {};\n\n info.url = this._ioctl.currentURL;\n info.hasRedirect = this._ioctl.hasRedirect;\n if (info.hasRedirect) {\n info.redirectedURL = this._ioctl.currentRedirectedURL;\n }\n\n info.speed = this._ioctl.currentSpeed;\n info.loaderType = this._ioctl.loaderType;\n info.currentSegmentIndex = this._currentSegmentIndex;\n info.totalSegmentCount = this._mediaDataSource.segments.length;\n\n this._emitter.emit(TransmuxingEvents.STATISTICS_INFO, info);\n }\n\n}\n\nexport default TransmuxingController;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst TransmuxingEvents = {\n IO_ERROR: 'io_error',\n DEMUX_ERROR: 'demux_error',\n INIT_SEGMENT: 'init_segment',\n MEDIA_SEGMENT: 'media_segment',\n LOADING_COMPLETE: 'loading_complete',\n RECOVERED_EARLY_EOF: 'recovered_early_eof',\n MEDIA_INFO: 'media_info',\n STATISTICS_INFO: 'statistics_info',\n RECOMMEND_SEEKPOINT: 'recommend_seekpoint'\n};\n\nexport default TransmuxingEvents;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport LoggingControl from '../utils/logging-control.js';\nimport Polyfill from '../utils/polyfill.js';\nimport TransmuxingController from './transmuxing-controller.js';\nimport TransmuxingEvents from './transmuxing-events.js';\n\n/* post message to worker:\n data: {\n cmd: string\n param: any\n }\n\n receive message from worker:\n data: {\n msg: string,\n data: any\n }\n */\n\nlet TransmuxingWorker = function (self) {\n\n let TAG = 'TransmuxingWorker';\n let controller = null;\n let logcatListener = onLogcatCallback.bind(this);\n\n Polyfill.install();\n\n self.addEventListener('message', function (e) {\n switch (e.data.cmd) {\n case 'init':\n controller = new TransmuxingController(e.data.param[0], e.data.param[1]);\n controller.on(TransmuxingEvents.IO_ERROR, onIOError.bind(this));\n controller.on(TransmuxingEvents.DEMUX_ERROR, onDemuxError.bind(this));\n controller.on(TransmuxingEvents.INIT_SEGMENT, onInitSegment.bind(this));\n controller.on(TransmuxingEvents.MEDIA_SEGMENT, onMediaSegment.bind(this));\n controller.on(TransmuxingEvents.LOADING_COMPLETE, onLoadingComplete.bind(this));\n controller.on(TransmuxingEvents.RECOVERED_EARLY_EOF, onRecoveredEarlyEof.bind(this));\n controller.on(TransmuxingEvents.MEDIA_INFO, onMediaInfo.bind(this));\n controller.on(TransmuxingEvents.STATISTICS_INFO, onStatisticsInfo.bind(this));\n controller.on(TransmuxingEvents.RECOMMEND_SEEKPOINT, onRecommendSeekpoint.bind(this));\n break;\n case 'destroy':\n if (controller) {\n controller.destroy();\n controller = null;\n }\n self.postMessage({msg: 'destroyed'});\n break;\n case 'start':\n controller.start();\n break;\n case 'stop':\n controller.stop();\n break;\n case 'seek':\n controller.seek(e.data.param);\n break;\n case 'pause':\n controller.pause();\n break;\n case 'resume':\n controller.resume();\n break;\n case 'logging_config': {\n let config = e.data.param;\n LoggingControl.applyConfig(config);\n\n if (config.enableCallback === true) {\n LoggingControl.addLogListener(logcatListener);\n } else {\n LoggingControl.removeLogListener(logcatListener);\n }\n break;\n }\n }\n });\n\n function onInitSegment(type, initSegment) {\n let obj = {\n msg: TransmuxingEvents.INIT_SEGMENT,\n data: {\n type: type,\n data: initSegment\n }\n };\n self.postMessage(obj, [initSegment.data]); // data: ArrayBuffer\n }\n\n function onMediaSegment(type, mediaSegment) {\n let obj = {\n msg: TransmuxingEvents.MEDIA_SEGMENT,\n data: {\n type: type,\n data: mediaSegment\n }\n };\n self.postMessage(obj, [mediaSegment.data]); // data: ArrayBuffer\n }\n\n function onLoadingComplete() {\n let obj = {\n msg: TransmuxingEvents.LOADING_COMPLETE\n };\n self.postMessage(obj);\n }\n\n function onRecoveredEarlyEof() {\n let obj = {\n msg: TransmuxingEvents.RECOVERED_EARLY_EOF\n };\n self.postMessage(obj);\n }\n\n function onMediaInfo(mediaInfo) {\n let obj = {\n msg: TransmuxingEvents.MEDIA_INFO,\n data: mediaInfo\n };\n self.postMessage(obj);\n }\n\n function onStatisticsInfo(statInfo) {\n let obj = {\n msg: TransmuxingEvents.STATISTICS_INFO,\n data: statInfo\n };\n self.postMessage(obj);\n }\n\n function onIOError(type, info) {\n self.postMessage({\n msg: TransmuxingEvents.IO_ERROR,\n data: {\n type: type,\n info: info\n }\n });\n }\n\n function onDemuxError(type, info) {\n self.postMessage({\n msg: TransmuxingEvents.DEMUX_ERROR,\n data: {\n type: type,\n info: info\n }\n });\n }\n\n function onRecommendSeekpoint(milliseconds) {\n self.postMessage({\n msg: TransmuxingEvents.RECOMMEND_SEEKPOINT,\n data: milliseconds\n });\n }\n\n function onLogcatCallback(type, str) {\n self.postMessage({\n msg: 'logcat_callback',\n data: {\n type: type,\n logcat: str\n }\n });\n }\n\n};\n\nexport default TransmuxingWorker;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport decodeUTF8 from '../utils/utf8-conv.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\nlet le = (function () {\n let buf = new ArrayBuffer(2);\n (new DataView(buf)).setInt16(0, 256, true); // little-endian write\n return (new Int16Array(buf))[0] === 256; // platform-spec read, if equal then LE\n})();\n\nclass AMF {\n\n static parseScriptData(arrayBuffer, dataOffset, dataSize) {\n let data = {};\n\n try {\n let name = AMF.parseValue(arrayBuffer, dataOffset, dataSize);\n let value = AMF.parseValue(arrayBuffer, dataOffset + name.size, dataSize - name.size);\n\n data[name.data] = value.data;\n } catch (e) {\n Log.e('AMF', e.toString());\n }\n\n return data;\n }\n\n static parseObject(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 3) {\n throw new IllegalStateException('Data not enough when parse ScriptDataObject');\n }\n let name = AMF.parseString(arrayBuffer, dataOffset, dataSize);\n let value = AMF.parseValue(arrayBuffer, dataOffset + name.size, dataSize - name.size);\n let isObjectEnd = value.objectEnd;\n\n return {\n data: {\n name: name.data,\n value: value.data\n },\n size: name.size + value.size,\n objectEnd: isObjectEnd\n };\n }\n\n static parseVariable(arrayBuffer, dataOffset, dataSize) {\n return AMF.parseObject(arrayBuffer, dataOffset, dataSize);\n }\n\n static parseString(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 2) {\n throw new IllegalStateException('Data not enough when parse String');\n }\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n let length = v.getUint16(0, !le);\n\n let str;\n if (length > 0) {\n str = decodeUTF8(new Uint8Array(arrayBuffer, dataOffset + 2, length));\n } else {\n str = '';\n }\n\n return {\n data: str,\n size: 2 + length\n };\n }\n\n static parseLongString(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 4) {\n throw new IllegalStateException('Data not enough when parse LongString');\n }\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n let length = v.getUint32(0, !le);\n\n let str;\n if (length > 0) {\n str = decodeUTF8(new Uint8Array(arrayBuffer, dataOffset + 4, length));\n } else {\n str = '';\n }\n\n return {\n data: str,\n size: 4 + length\n };\n }\n\n static parseDate(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 10) {\n throw new IllegalStateException('Data size invalid when parse Date');\n }\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n let timestamp = v.getFloat64(0, !le);\n let localTimeOffset = v.getInt16(8, !le);\n timestamp += localTimeOffset * 60 * 1000; // get UTC time\n\n return {\n data: new Date(timestamp),\n size: 8 + 2\n };\n }\n\n static parseValue(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 1) {\n throw new IllegalStateException('Data not enough when parse Value');\n }\n\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let offset = 1;\n let type = v.getUint8(0);\n let value;\n let objectEnd = false;\n\n try {\n switch (type) {\n case 0: // Number(Double) type\n value = v.getFloat64(1, !le);\n offset += 8;\n break;\n case 1: { // Boolean type\n let b = v.getUint8(1);\n value = b ? true : false;\n offset += 1;\n break;\n }\n case 2: { // String type\n let amfstr = AMF.parseString(arrayBuffer, dataOffset + 1, dataSize - 1);\n value = amfstr.data;\n offset += amfstr.size;\n break;\n }\n case 3: { // Object(s) type\n value = {};\n let terminal = 0; // workaround for malformed Objects which has missing ScriptDataObjectEnd\n if ((v.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {\n terminal = 3;\n }\n while (offset < dataSize - 4) { // 4 === type(UI8) + ScriptDataObjectEnd(UI24)\n let amfobj = AMF.parseObject(arrayBuffer, dataOffset + offset, dataSize - offset - terminal);\n if (amfobj.objectEnd)\n break;\n value[amfobj.data.name] = amfobj.data.value;\n offset += amfobj.size;\n }\n if (offset <= dataSize - 3) {\n let marker = v.getUint32(offset - 1, !le) & 0x00FFFFFF;\n if (marker === 9) {\n offset += 3;\n }\n }\n break;\n }\n case 8: { // ECMA array type (Mixed array)\n value = {};\n offset += 4; // ECMAArrayLength(UI32)\n let terminal = 0; // workaround for malformed MixedArrays which has missing ScriptDataObjectEnd\n if ((v.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {\n terminal = 3;\n }\n while (offset < dataSize - 8) { // 8 === type(UI8) + ECMAArrayLength(UI32) + ScriptDataVariableEnd(UI24)\n let amfvar = AMF.parseVariable(arrayBuffer, dataOffset + offset, dataSize - offset - terminal);\n if (amfvar.objectEnd)\n break;\n value[amfvar.data.name] = amfvar.data.value;\n offset += amfvar.size;\n }\n if (offset <= dataSize - 3) {\n let marker = v.getUint32(offset - 1, !le) & 0x00FFFFFF;\n if (marker === 9) {\n offset += 3;\n }\n }\n break;\n }\n case 9: // ScriptDataObjectEnd\n value = undefined;\n offset = 1;\n objectEnd = true;\n break;\n case 10: { // Strict array type\n // ScriptDataValue[n]. NOTE: according to video_file_format_spec_v10_1.pdf\n value = [];\n let strictArrayLength = v.getUint32(1, !le);\n offset += 4;\n for (let i = 0; i < strictArrayLength; i++) {\n let val = AMF.parseValue(arrayBuffer, dataOffset + offset, dataSize - offset);\n value.push(val.data);\n offset += val.size;\n }\n break;\n }\n case 11: { // Date type\n let date = AMF.parseDate(arrayBuffer, dataOffset + 1, dataSize - 1);\n value = date.data;\n offset += date.size;\n break;\n }\n case 12: { // Long string type\n let amfLongStr = AMF.parseString(arrayBuffer, dataOffset + 1, dataSize - 1);\n value = amfLongStr.data;\n offset += amfLongStr.size;\n break;\n }\n default:\n // ignore and skip\n offset = dataSize;\n Log.w('AMF', 'Unsupported AMF value type ' + type);\n }\n } catch (e) {\n Log.e('AMF', e.toString());\n }\n\n return {\n data: value,\n size: offset,\n objectEnd: objectEnd\n };\n }\n\n}\n\nexport default AMF;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst DemuxErrors = {\n OK: 'OK',\n FORMAT_ERROR: 'FormatError',\n FORMAT_UNSUPPORTED: 'FormatUnsupported',\n CODEC_UNSUPPORTED: 'CodecUnsupported'\n};\n\nexport default DemuxErrors;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {IllegalStateException, InvalidArgumentException} from '../utils/exception.js';\n\n// Exponential-Golomb buffer decoder\nclass ExpGolomb {\n\n constructor(uint8array) {\n this.TAG = 'ExpGolomb';\n\n this._buffer = uint8array;\n this._buffer_index = 0;\n this._total_bytes = uint8array.byteLength;\n this._total_bits = uint8array.byteLength * 8;\n this._current_word = 0;\n this._current_word_bits_left = 0;\n }\n\n destroy() {\n this._buffer = null;\n }\n\n _fillCurrentWord() {\n let buffer_bytes_left = this._total_bytes - this._buffer_index;\n if (buffer_bytes_left <= 0)\n throw new IllegalStateException('ExpGolomb: _fillCurrentWord() but no bytes available');\n\n let bytes_read = Math.min(4, buffer_bytes_left);\n let word = new Uint8Array(4);\n word.set(this._buffer.subarray(this._buffer_index, this._buffer_index + bytes_read));\n this._current_word = new DataView(word.buffer).getUint32(0, false);\n\n this._buffer_index += bytes_read;\n this._current_word_bits_left = bytes_read * 8;\n }\n\n readBits(bits) {\n if (bits > 32)\n throw new InvalidArgumentException('ExpGolomb: readBits() bits exceeded max 32bits!');\n\n if (bits <= this._current_word_bits_left) {\n let result = this._current_word >>> (32 - bits);\n this._current_word <<= bits;\n this._current_word_bits_left -= bits;\n return result;\n }\n\n let result = this._current_word_bits_left ? this._current_word : 0;\n result = result >>> (32 - this._current_word_bits_left);\n let bits_need_left = bits - this._current_word_bits_left;\n\n this._fillCurrentWord();\n let bits_read_next = Math.min(bits_need_left, this._current_word_bits_left);\n\n let result2 = this._current_word >>> (32 - bits_read_next);\n this._current_word <<= bits_read_next;\n this._current_word_bits_left -= bits_read_next;\n\n result = (result << bits_read_next) | result2;\n return result;\n }\n\n readBool() {\n return this.readBits(1) === 1;\n }\n\n readByte() {\n return this.readBits(8);\n }\n\n _skipLeadingZero() {\n let zero_count;\n for (zero_count = 0; zero_count < this._current_word_bits_left; zero_count++) {\n if (0 !== (this._current_word & (0x80000000 >>> zero_count))) {\n this._current_word <<= zero_count;\n this._current_word_bits_left -= zero_count;\n return zero_count;\n }\n }\n this._fillCurrentWord();\n return zero_count + this._skipLeadingZero();\n }\n\n readUEG() { // unsigned exponential golomb\n let leading_zeros = this._skipLeadingZero();\n return this.readBits(leading_zeros + 1) - 1;\n }\n\n readSEG() { // signed exponential golomb\n let value = this.readUEG();\n if (value & 0x01) {\n return (value + 1) >>> 1;\n } else {\n return -1 * (value >>> 1);\n }\n }\n\n}\n\nexport default ExpGolomb;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport AMF from './amf-parser.js';\nimport SPSParser from './sps-parser.js';\nimport DemuxErrors from './demux-errors.js';\nimport MediaInfo from '../core/media-info.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\nfunction Swap16(src) {\n return (((src >>> 8) & 0xFF) |\n ((src & 0xFF) << 8));\n}\n\nfunction Swap32(src) {\n return (((src & 0xFF000000) >>> 24) |\n ((src & 0x00FF0000) >>> 8) |\n ((src & 0x0000FF00) << 8) |\n ((src & 0x000000FF) << 24));\n}\n\nfunction ReadBig32(array, index) {\n return ((array[index] << 24) |\n (array[index + 1] << 16) |\n (array[index + 2] << 8) |\n (array[index + 3]));\n}\n\n\nclass FLVDemuxer {\n\n constructor(probeData, config) {\n this.TAG = 'FLVDemuxer';\n\n this._config = config;\n\n this._onError = null;\n this._onMediaInfo = null;\n this._onTrackMetadata = null;\n this._onDataAvailable = null;\n\n this._dataOffset = probeData.dataOffset;\n this._firstParse = true;\n this._dispatch = false;\n\n this._hasAudio = probeData.hasAudioTrack;\n this._hasVideo = probeData.hasVideoTrack;\n\n this._hasAudioFlagOverrided = false;\n this._hasVideoFlagOverrided = false;\n\n this._audioInitialMetadataDispatched = false;\n this._videoInitialMetadataDispatched = false;\n\n this._mediaInfo = new MediaInfo();\n this._mediaInfo.hasAudio = this._hasAudio;\n this._mediaInfo.hasVideo = this._hasVideo;\n this._metadata = null;\n this._audioMetadata = null;\n this._videoMetadata = null;\n\n this._naluLengthSize = 4;\n this._timestampBase = 0; // int32, in milliseconds\n this._timescale = 1000;\n this._duration = 0; // int32, in milliseconds\n this._durationOverrided = false;\n this._referenceFrameRate = {\n fixed: true,\n fps: 23.976,\n fps_num: 23976,\n fps_den: 1000\n };\n\n this._flvSoundRateTable = [5500, 11025, 22050, 44100, 48000];\n\n this._mpegSamplingRates = [\n 96000, 88200, 64000, 48000, 44100, 32000,\n 24000, 22050, 16000, 12000, 11025, 8000, 7350\n ];\n\n this._mpegAudioV10SampleRateTable = [44100, 48000, 32000, 0];\n this._mpegAudioV20SampleRateTable = [22050, 24000, 16000, 0];\n this._mpegAudioV25SampleRateTable = [11025, 12000, 8000, 0];\n\n this._mpegAudioL1BitRateTable = [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1];\n this._mpegAudioL2BitRateTable = [0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1];\n this._mpegAudioL3BitRateTable = [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1];\n\n this._videoTrack = {type: 'video', id: 1, sequenceNumber: 0, samples: [], length: 0};\n this._audioTrack = {type: 'audio', id: 2, sequenceNumber: 0, samples: [], length: 0};\n\n this._littleEndian = (function () {\n let buf = new ArrayBuffer(2);\n (new DataView(buf)).setInt16(0, 256, true); // little-endian write\n return (new Int16Array(buf))[0] === 256; // platform-spec read, if equal then LE\n })();\n }\n\n destroy() {\n this._mediaInfo = null;\n this._metadata = null;\n this._audioMetadata = null;\n this._videoMetadata = null;\n this._videoTrack = null;\n this._audioTrack = null;\n\n this._onError = null;\n this._onMediaInfo = null;\n this._onTrackMetadata = null;\n this._onDataAvailable = null;\n }\n\n static probe(buffer) {\n let data = new Uint8Array(buffer);\n let mismatch = {match: false};\n\n if (data[0] !== 0x46 || data[1] !== 0x4C || data[2] !== 0x56 || data[3] !== 0x01) {\n return mismatch;\n }\n\n let hasAudio = ((data[4] & 4) >>> 2) !== 0;\n let hasVideo = (data[4] & 1) !== 0;\n\n let offset = ReadBig32(data, 5);\n\n if (offset < 9) {\n return mismatch;\n }\n\n return {\n match: true,\n consumed: offset,\n dataOffset: offset,\n hasAudioTrack: hasAudio,\n hasVideoTrack: hasVideo\n };\n }\n\n bindDataSource(loader) {\n loader.onDataArrival = this.parseChunks.bind(this);\n return this;\n }\n\n // prototype: function(type: string, metadata: any): void\n get onTrackMetadata() {\n return this._onTrackMetadata;\n }\n\n set onTrackMetadata(callback) {\n this._onTrackMetadata = callback;\n }\n\n // prototype: function(mediaInfo: MediaInfo): void\n get onMediaInfo() {\n return this._onMediaInfo;\n }\n\n set onMediaInfo(callback) {\n this._onMediaInfo = callback;\n }\n\n // prototype: function(type: number, info: string): void\n get onError() {\n return this._onError;\n }\n\n set onError(callback) {\n this._onError = callback;\n }\n\n // prototype: function(videoTrack: any, audioTrack: any): void\n get onDataAvailable() {\n return this._onDataAvailable;\n }\n\n set onDataAvailable(callback) {\n this._onDataAvailable = callback;\n }\n\n // timestamp base for output samples, must be in milliseconds\n get timestampBase() {\n return this._timestampBase;\n }\n\n set timestampBase(base) {\n this._timestampBase = base;\n }\n\n get overridedDuration() {\n return this._duration;\n }\n\n // Force-override media duration. Must be in milliseconds, int32\n set overridedDuration(duration) {\n this._durationOverrided = true;\n this._duration = duration;\n this._mediaInfo.duration = duration;\n }\n\n // Force-override audio track present flag, boolean\n set overridedHasAudio(hasAudio) {\n this._hasAudioFlagOverrided = true;\n this._hasAudio = hasAudio;\n this._mediaInfo.hasAudio = hasAudio;\n }\n\n // Force-override video track present flag, boolean\n set overridedHasVideo(hasVideo) {\n this._hasVideoFlagOverrided = true;\n this._hasVideo = hasVideo;\n this._mediaInfo.hasVideo = hasVideo;\n }\n\n resetMediaInfo() {\n this._mediaInfo = new MediaInfo();\n }\n\n _isInitialMetadataDispatched() {\n if (this._hasAudio && this._hasVideo) { // both audio & video\n return this._audioInitialMetadataDispatched && this._videoInitialMetadataDispatched;\n }\n if (this._hasAudio && !this._hasVideo) { // audio only\n return this._audioInitialMetadataDispatched;\n }\n if (!this._hasAudio && this._hasVideo) { // video only\n return this._videoInitialMetadataDispatched;\n }\n return false;\n }\n\n // function parseChunks(chunk: ArrayBuffer, byteStart: number): number;\n parseChunks(chunk, byteStart) {\n if (!this._onError || !this._onMediaInfo || !this._onTrackMetadata || !this._onDataAvailable) {\n throw new IllegalStateException('Flv: onError & onMediaInfo & onTrackMetadata & onDataAvailable callback must be specified');\n }\n\n let offset = 0;\n let le = this._littleEndian;\n\n if (byteStart === 0) { // buffer with FLV header\n if (chunk.byteLength > 13) {\n let probeData = FLVDemuxer.probe(chunk);\n offset = probeData.dataOffset;\n } else {\n return 0;\n }\n }\n\n if (this._firstParse) { // handle PreviousTagSize0 before Tag1\n this._firstParse = false;\n if (byteStart + offset !== this._dataOffset) {\n Log.w(this.TAG, 'First time parsing but chunk byteStart invalid!');\n }\n\n let v = new DataView(chunk, offset);\n let prevTagSize0 = v.getUint32(0, !le);\n if (prevTagSize0 !== 0) {\n Log.w(this.TAG, 'PrevTagSize0 !== 0 !!!');\n }\n offset += 4;\n }\n\n while (offset < chunk.byteLength) {\n this._dispatch = true;\n\n let v = new DataView(chunk, offset);\n\n if (offset + 11 + 4 > chunk.byteLength) {\n // data not enough for parsing an flv tag\n break;\n }\n\n let tagType = v.getUint8(0);\n let dataSize = v.getUint32(0, !le) & 0x00FFFFFF;\n\n if (offset + 11 + dataSize + 4 > chunk.byteLength) {\n // data not enough for parsing actual data body\n break;\n }\n\n if (tagType !== 8 && tagType !== 9 && tagType !== 18) {\n Log.w(this.TAG, `Unsupported tag type ${tagType}, skipped`);\n // consume the whole tag (skip it)\n offset += 11 + dataSize + 4;\n continue;\n }\n\n let ts2 = v.getUint8(4);\n let ts1 = v.getUint8(5);\n let ts0 = v.getUint8(6);\n let ts3 = v.getUint8(7);\n\n let timestamp = ts0 | (ts1 << 8) | (ts2 << 16) | (ts3 << 24);\n\n let streamId = v.getUint32(7, !le) & 0x00FFFFFF;\n if (streamId !== 0) {\n Log.w(this.TAG, 'Meet tag which has StreamID != 0!');\n }\n\n let dataOffset = offset + 11;\n\n switch (tagType) {\n case 8: // Audio\n this._parseAudioData(chunk, dataOffset, dataSize, timestamp);\n break;\n case 9: // Video\n this._parseVideoData(chunk, dataOffset, dataSize, timestamp, byteStart + offset);\n break;\n case 18: // ScriptDataObject\n this._parseScriptData(chunk, dataOffset, dataSize);\n break;\n }\n\n let prevTagSize = v.getUint32(11 + dataSize, !le);\n if (prevTagSize !== 11 + dataSize) {\n Log.w(this.TAG, `Invalid PrevTagSize ${prevTagSize}`);\n }\n\n offset += 11 + dataSize + 4; // tagBody + dataSize + prevTagSize\n }\n\n // dispatch parsed frames to consumer (typically, the remuxer)\n if (this._isInitialMetadataDispatched()) {\n if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {\n this._onDataAvailable(this._audioTrack, this._videoTrack);\n }\n }\n\n return offset; // consumed bytes, just equals latest offset index\n }\n\n _parseScriptData(arrayBuffer, dataOffset, dataSize) {\n let scriptData = AMF.parseScriptData(arrayBuffer, dataOffset, dataSize);\n\n if (scriptData.hasOwnProperty('onMetaData')) {\n if (scriptData.onMetaData == null || typeof scriptData.onMetaData !== 'object') {\n Log.w(this.TAG, 'Invalid onMetaData structure!');\n return;\n }\n if (this._metadata) {\n Log.w(this.TAG, 'Found another onMetaData tag!');\n }\n this._metadata = scriptData;\n let onMetaData = this._metadata.onMetaData;\n\n if (typeof onMetaData.hasAudio === 'boolean') { // hasAudio\n if (this._hasAudioFlagOverrided === false) {\n this._hasAudio = onMetaData.hasAudio;\n this._mediaInfo.hasAudio = this._hasAudio;\n }\n }\n if (typeof onMetaData.hasVideo === 'boolean') { // hasVideo\n if (this._hasVideoFlagOverrided === false) {\n this._hasVideo = onMetaData.hasVideo;\n this._mediaInfo.hasVideo = this._hasVideo;\n }\n }\n if (typeof onMetaData.audiodatarate === 'number') { // audiodatarate\n this._mediaInfo.audioDataRate = onMetaData.audiodatarate;\n }\n if (typeof onMetaData.videodatarate === 'number') { // videodatarate\n this._mediaInfo.videoDataRate = onMetaData.videodatarate;\n }\n if (typeof onMetaData.width === 'number') { // width\n this._mediaInfo.width = onMetaData.width;\n }\n if (typeof onMetaData.height === 'number') { // height\n this._mediaInfo.height = onMetaData.height;\n }\n if (typeof onMetaData.duration === 'number') { // duration\n if (!this._durationOverrided) {\n let duration = Math.floor(onMetaData.duration * this._timescale);\n this._duration = duration;\n this._mediaInfo.duration = duration;\n }\n } else {\n this._mediaInfo.duration = 0;\n }\n if (typeof onMetaData.framerate === 'number') { // framerate\n let fps_num = Math.floor(onMetaData.framerate * 1000);\n if (fps_num > 0) {\n let fps = fps_num / 1000;\n this._referenceFrameRate.fixed = true;\n this._referenceFrameRate.fps = fps;\n this._referenceFrameRate.fps_num = fps_num;\n this._referenceFrameRate.fps_den = 1000;\n this._mediaInfo.fps = fps;\n }\n }\n if (typeof onMetaData.keyframes === 'object') { // keyframes\n this._mediaInfo.hasKeyframesIndex = true;\n let keyframes = onMetaData.keyframes;\n this._mediaInfo.keyframesIndex = this._parseKeyframesIndex(keyframes);\n onMetaData.keyframes = null; // keyframes has been extracted, remove it\n } else {\n this._mediaInfo.hasKeyframesIndex = false;\n }\n this._dispatch = false;\n this._mediaInfo.metadata = onMetaData;\n Log.v(this.TAG, 'Parsed onMetaData');\n if (this._mediaInfo.isComplete()) {\n this._onMediaInfo(this._mediaInfo);\n }\n }\n }\n\n _parseKeyframesIndex(keyframes) {\n let times = [];\n let filepositions = [];\n\n // ignore first keyframe which is actually AVC Sequence Header (AVCDecoderConfigurationRecord)\n for (let i = 1; i < keyframes.times.length; i++) {\n let time = this._timestampBase + Math.floor(keyframes.times[i] * 1000);\n times.push(time);\n filepositions.push(keyframes.filepositions[i]);\n }\n\n return {\n times: times,\n filepositions: filepositions\n };\n }\n\n _parseAudioData(arrayBuffer, dataOffset, dataSize, tagTimestamp) {\n if (dataSize <= 1) {\n Log.w(this.TAG, 'Flv: Invalid audio packet, missing SoundData payload!');\n return;\n }\n\n if (this._hasAudioFlagOverrided === true && this._hasAudio === false) {\n // If hasAudio: false indicated explicitly in MediaDataSource,\n // Ignore all the audio packets\n return;\n }\n\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let soundSpec = v.getUint8(0);\n\n let soundFormat = soundSpec >>> 4;\n if (soundFormat !== 2 && soundFormat !== 10) { // MP3 or AAC\n this._onError(DemuxErrors.CODEC_UNSUPPORTED, 'Flv: Unsupported audio codec idx: ' + soundFormat);\n return;\n }\n\n let soundRate = 0;\n let soundRateIndex = (soundSpec & 12) >>> 2;\n if (soundRateIndex >= 0 && soundRateIndex <= 4) {\n soundRate = this._flvSoundRateTable[soundRateIndex];\n } else {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid audio sample rate idx: ' + soundRateIndex);\n return;\n }\n\n let soundSize = (soundSpec & 2) >>> 1; // unused\n let soundType = (soundSpec & 1);\n\n\n let meta = this._audioMetadata;\n let track = this._audioTrack;\n\n if (!meta) {\n if (this._hasAudio === false && this._hasAudioFlagOverrided === false) {\n this._hasAudio = true;\n this._mediaInfo.hasAudio = true;\n }\n\n // initial metadata\n meta = this._audioMetadata = {};\n meta.type = 'audio';\n meta.id = track.id;\n meta.timescale = this._timescale;\n meta.duration = this._duration;\n meta.audioSampleRate = soundRate;\n meta.channelCount = (soundType === 0 ? 1 : 2);\n }\n\n if (soundFormat === 10) { // AAC\n let aacData = this._parseAACAudioData(arrayBuffer, dataOffset + 1, dataSize - 1);\n if (aacData == undefined) {\n return;\n }\n\n if (aacData.packetType === 0) { // AAC sequence header (AudioSpecificConfig)\n if (meta.config) {\n Log.w(this.TAG, 'Found another AudioSpecificConfig!');\n }\n let misc = aacData.data;\n meta.audioSampleRate = misc.samplingRate;\n meta.channelCount = misc.channelCount;\n meta.codec = misc.codec;\n meta.originalCodec = misc.originalCodec;\n meta.config = misc.config;\n // The decode result of an aac sample is 1024 PCM samples\n meta.refSampleDuration = 1024 / meta.audioSampleRate * meta.timescale;\n Log.v(this.TAG, 'Parsed AudioSpecificConfig');\n\n if (this._isInitialMetadataDispatched()) {\n // Non-initial metadata, force dispatch (or flush) parsed frames to remuxer\n if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {\n this._onDataAvailable(this._audioTrack, this._videoTrack);\n }\n } else {\n this._audioInitialMetadataDispatched = true;\n }\n // then notify new metadata\n this._dispatch = false;\n this._onTrackMetadata('audio', meta);\n\n let mi = this._mediaInfo;\n mi.audioCodec = meta.originalCodec;\n mi.audioSampleRate = meta.audioSampleRate;\n mi.audioChannelCount = meta.channelCount;\n if (mi.hasVideo) {\n if (mi.videoCodec != null) {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + ',' + mi.audioCodec + '\"';\n }\n } else {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.audioCodec + '\"';\n }\n if (mi.isComplete()) {\n this._onMediaInfo(mi);\n }\n } else if (aacData.packetType === 1) { // AAC raw frame data\n let dts = this._timestampBase + tagTimestamp;\n let aacSample = {unit: aacData.data, dts: dts, pts: dts};\n track.samples.push(aacSample);\n track.length += aacData.data.length;\n } else {\n Log.e(this.TAG, `Flv: Unsupported AAC data type ${aacData.packetType}`);\n }\n } else if (soundFormat === 2) { // MP3\n if (!meta.codec) {\n // We need metadata for mp3 audio track, extract info from frame header\n let misc = this._parseMP3AudioData(arrayBuffer, dataOffset + 1, dataSize - 1, true);\n if (misc == undefined) {\n return;\n }\n meta.audioSampleRate = misc.samplingRate;\n meta.channelCount = misc.channelCount;\n meta.codec = misc.codec;\n meta.originalCodec = misc.originalCodec;\n // The decode result of an mp3 sample is 1152 PCM samples\n meta.refSampleDuration = 1152 / meta.audioSampleRate * meta.timescale;\n Log.v(this.TAG, 'Parsed MPEG Audio Frame Header');\n\n this._audioInitialMetadataDispatched = true;\n this._onTrackMetadata('audio', meta);\n\n let mi = this._mediaInfo;\n mi.audioCodec = meta.codec;\n mi.audioSampleRate = meta.audioSampleRate;\n mi.audioChannelCount = meta.channelCount;\n mi.audioDataRate = misc.bitRate;\n if (mi.hasVideo) {\n if (mi.videoCodec != null) {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + ',' + mi.audioCodec + '\"';\n }\n } else {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.audioCodec + '\"';\n }\n if (mi.isComplete()) {\n this._onMediaInfo(mi);\n }\n }\n\n // This packet is always a valid audio packet, extract it\n let data = this._parseMP3AudioData(arrayBuffer, dataOffset + 1, dataSize - 1, false);\n if (data == undefined) {\n return;\n }\n let dts = this._timestampBase + tagTimestamp;\n let mp3Sample = {unit: data, dts: dts, pts: dts};\n track.samples.push(mp3Sample);\n track.length += data.length;\n }\n }\n\n _parseAACAudioData(arrayBuffer, dataOffset, dataSize) {\n if (dataSize <= 1) {\n Log.w(this.TAG, 'Flv: Invalid AAC packet, missing AACPacketType or/and Data!');\n return;\n }\n\n let result = {};\n let array = new Uint8Array(arrayBuffer, dataOffset, dataSize);\n\n result.packetType = array[0];\n\n if (array[0] === 0) {\n result.data = this._parseAACAudioSpecificConfig(arrayBuffer, dataOffset + 1, dataSize - 1);\n } else {\n result.data = array.subarray(1);\n }\n\n return result;\n }\n\n _parseAACAudioSpecificConfig(arrayBuffer, dataOffset, dataSize) {\n let array = new Uint8Array(arrayBuffer, dataOffset, dataSize);\n let config = null;\n\n /* Audio Object Type:\n 0: Null\n 1: AAC Main\n 2: AAC LC\n 3: AAC SSR (Scalable Sample Rate)\n 4: AAC LTP (Long Term Prediction)\n 5: HE-AAC / SBR (Spectral Band Replication)\n 6: AAC Scalable\n */\n\n let audioObjectType = 0;\n let originalAudioObjectType = 0;\n let audioExtensionObjectType = null;\n let samplingIndex = 0;\n let extensionSamplingIndex = null;\n\n // 5 bits\n audioObjectType = originalAudioObjectType = array[0] >>> 3;\n // 4 bits\n samplingIndex = ((array[0] & 0x07) << 1) | (array[1] >>> 7);\n if (samplingIndex < 0 || samplingIndex >= this._mpegSamplingRates.length) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: AAC invalid sampling frequency index!');\n return;\n }\n\n let samplingFrequence = this._mpegSamplingRates[samplingIndex];\n\n // 4 bits\n let channelConfig = (array[1] & 0x78) >>> 3;\n if (channelConfig < 0 || channelConfig >= 8) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: AAC invalid channel configuration');\n return;\n }\n\n if (audioObjectType === 5) { // HE-AAC?\n // 4 bits\n extensionSamplingIndex = ((array[1] & 0x07) << 1) | (array[2] >>> 7);\n // 5 bits\n audioExtensionObjectType = (array[2] & 0x7C) >>> 2;\n }\n\n // workarounds for various browsers\n let userAgent = self.navigator.userAgent.toLowerCase();\n\n if (userAgent.indexOf('firefox') !== -1) {\n // firefox: use SBR (HE-AAC) if freq less than 24kHz\n if (samplingIndex >= 6) {\n audioObjectType = 5;\n config = new Array(4);\n extensionSamplingIndex = samplingIndex - 3;\n } else { // use LC-AAC\n audioObjectType = 2;\n config = new Array(2);\n extensionSamplingIndex = samplingIndex;\n }\n } else if (userAgent.indexOf('android') !== -1) {\n // android: always use LC-AAC\n audioObjectType = 2;\n config = new Array(2);\n extensionSamplingIndex = samplingIndex;\n } else {\n // for other browsers, e.g. chrome...\n // Always use HE-AAC to make it easier to switch aac codec profile\n audioObjectType = 5;\n extensionSamplingIndex = samplingIndex;\n config = new Array(4);\n\n if (samplingIndex >= 6) {\n extensionSamplingIndex = samplingIndex - 3;\n } else if (channelConfig === 1) { // Mono channel\n audioObjectType = 2;\n config = new Array(2);\n extensionSamplingIndex = samplingIndex;\n }\n }\n\n config[0] = audioObjectType << 3;\n config[0] |= (samplingIndex & 0x0F) >>> 1;\n config[1] = (samplingIndex & 0x0F) << 7;\n config[1] |= (channelConfig & 0x0F) << 3;\n if (audioObjectType === 5) {\n config[1] |= ((extensionSamplingIndex & 0x0F) >>> 1);\n config[2] = (extensionSamplingIndex & 0x01) << 7;\n // extended audio object type: force to 2 (LC-AAC)\n config[2] |= (2 << 2);\n config[3] = 0;\n }\n\n return {\n config: config,\n samplingRate: samplingFrequence,\n channelCount: channelConfig,\n codec: 'mp4a.40.' + audioObjectType,\n originalCodec: 'mp4a.40.' + originalAudioObjectType\n };\n }\n\n _parseMP3AudioData(arrayBuffer, dataOffset, dataSize, requestHeader) {\n if (dataSize < 4) {\n Log.w(this.TAG, 'Flv: Invalid MP3 packet, header missing!');\n return;\n }\n\n let le = this._littleEndian;\n let array = new Uint8Array(arrayBuffer, dataOffset, dataSize);\n let result = null;\n\n if (requestHeader) {\n if (array[0] !== 0xFF) {\n return;\n }\n let ver = (array[1] >>> 3) & 0x03;\n let layer = (array[1] & 0x06) >> 1;\n\n let bitrate_index = (array[2] & 0xF0) >>> 4;\n let sampling_freq_index = (array[2] & 0x0C) >>> 2;\n\n let channel_mode = (array[3] >>> 6) & 0x03;\n let channel_count = channel_mode !== 3 ? 2 : 1;\n\n let sample_rate = 0;\n let bit_rate = 0;\n let object_type = 34; // Layer-3, listed in MPEG-4 Audio Object Types\n\n let codec = 'mp3';\n\n switch (ver) {\n case 0: // MPEG 2.5\n sample_rate = this._mpegAudioV25SampleRateTable[sampling_freq_index];\n break;\n case 2: // MPEG 2\n sample_rate = this._mpegAudioV20SampleRateTable[sampling_freq_index];\n break;\n case 3: // MPEG 1\n sample_rate = this._mpegAudioV10SampleRateTable[sampling_freq_index];\n break;\n }\n\n switch (layer) {\n case 1: // Layer 3\n object_type = 34;\n if (bitrate_index < this._mpegAudioL3BitRateTable.length) {\n bit_rate = this._mpegAudioL3BitRateTable[bitrate_index];\n }\n break;\n case 2: // Layer 2\n object_type = 33;\n if (bitrate_index < this._mpegAudioL2BitRateTable.length) {\n bit_rate = this._mpegAudioL2BitRateTable[bitrate_index];\n }\n break;\n case 3: // Layer 1\n object_type = 32;\n if (bitrate_index < this._mpegAudioL1BitRateTable.length) {\n bit_rate = this._mpegAudioL1BitRateTable[bitrate_index];\n }\n break;\n }\n\n result = {\n bitRate: bit_rate,\n samplingRate: sample_rate,\n channelCount: channel_count,\n codec: codec,\n originalCodec: codec\n };\n } else {\n result = array;\n }\n\n return result;\n }\n\n _parseVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition) {\n if (dataSize <= 1) {\n Log.w(this.TAG, 'Flv: Invalid video packet, missing VideoData payload!');\n return;\n }\n\n if (this._hasVideoFlagOverrided === true && this._hasVideo === false) {\n // If hasVideo: false indicated explicitly in MediaDataSource,\n // Ignore all the video packets\n return;\n }\n\n let spec = (new Uint8Array(arrayBuffer, dataOffset, dataSize))[0];\n\n let frameType = (spec & 240) >>> 4;\n let codecId = spec & 15;\n\n if (codecId !== 7) {\n this._onError(DemuxErrors.CODEC_UNSUPPORTED, `Flv: Unsupported codec in video frame: ${codecId}`);\n return;\n }\n\n this._parseAVCVideoPacket(arrayBuffer, dataOffset + 1, dataSize - 1, tagTimestamp, tagPosition, frameType);\n }\n\n _parseAVCVideoPacket(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType) {\n if (dataSize < 4) {\n Log.w(this.TAG, 'Flv: Invalid AVC packet, missing AVCPacketType or/and CompositionTime');\n return;\n }\n\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let packetType = v.getUint8(0);\n let cts = v.getUint32(0, !le) & 0x00FFFFFF;\n\n if (packetType === 0) { // AVCDecoderConfigurationRecord\n this._parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset + 4, dataSize - 4);\n } else if (packetType === 1) { // One or more Nalus\n this._parseAVCVideoData(arrayBuffer, dataOffset + 4, dataSize - 4, tagTimestamp, tagPosition, frameType, cts);\n } else if (packetType === 2) {\n // empty, AVC end of sequence\n } else {\n this._onError(DemuxErrors.FORMAT_ERROR, `Flv: Invalid video packet type ${packetType}`);\n return;\n }\n }\n\n _parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 7) {\n Log.w(this.TAG, 'Flv: Invalid AVCDecoderConfigurationRecord, lack of data!');\n return;\n }\n\n let meta = this._videoMetadata;\n let track = this._videoTrack;\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n if (!meta) {\n if (this._hasVideo === false && this._hasVideoFlagOverrided === false) {\n this._hasVideo = true;\n this._mediaInfo.hasVideo = true;\n }\n\n meta = this._videoMetadata = {};\n meta.type = 'video';\n meta.id = track.id;\n meta.timescale = this._timescale;\n meta.duration = this._duration;\n } else {\n if (typeof meta.avcc !== 'undefined') {\n Log.w(this.TAG, 'Found another AVCDecoderConfigurationRecord!');\n }\n }\n\n let version = v.getUint8(0); // configurationVersion\n let avcProfile = v.getUint8(1); // avcProfileIndication\n let profileCompatibility = v.getUint8(2); // profile_compatibility\n let avcLevel = v.getUint8(3); // AVCLevelIndication\n\n if (version !== 1 || avcProfile === 0) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord');\n return;\n }\n\n this._naluLengthSize = (v.getUint8(4) & 3) + 1; // lengthSizeMinusOne\n if (this._naluLengthSize !== 3 && this._naluLengthSize !== 4) { // holy shit!!!\n this._onError(DemuxErrors.FORMAT_ERROR, `Flv: Strange NaluLengthSizeMinusOne: ${this._naluLengthSize - 1}`);\n return;\n }\n\n let spsCount = v.getUint8(5) & 31; // numOfSequenceParameterSets\n if (spsCount === 0) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord: No SPS');\n return;\n } else if (spsCount > 1) {\n Log.w(this.TAG, `Flv: Strange AVCDecoderConfigurationRecord: SPS Count = ${spsCount}`);\n }\n\n let offset = 6;\n\n for (let i = 0; i < spsCount; i++) {\n let len = v.getUint16(offset, !le); // sequenceParameterSetLength\n offset += 2;\n\n if (len === 0) {\n continue;\n }\n\n // Notice: Nalu without startcode header (00 00 00 01)\n let sps = new Uint8Array(arrayBuffer, dataOffset + offset, len);\n offset += len;\n\n let config = SPSParser.parseSPS(sps);\n if (i !== 0) {\n // ignore other sps's config\n continue;\n }\n\n meta.codecWidth = config.codec_size.width;\n meta.codecHeight = config.codec_size.height;\n meta.presentWidth = config.present_size.width;\n meta.presentHeight = config.present_size.height;\n\n meta.profile = config.profile_string;\n meta.level = config.level_string;\n meta.bitDepth = config.bit_depth;\n meta.chromaFormat = config.chroma_format;\n meta.sarRatio = config.sar_ratio;\n meta.frameRate = config.frame_rate;\n\n if (config.frame_rate.fixed === false ||\n config.frame_rate.fps_num === 0 ||\n config.frame_rate.fps_den === 0) {\n meta.frameRate = this._referenceFrameRate;\n }\n\n let fps_den = meta.frameRate.fps_den;\n let fps_num = meta.frameRate.fps_num;\n meta.refSampleDuration = meta.timescale * (fps_den / fps_num);\n\n let codecArray = sps.subarray(1, 4);\n let codecString = 'avc1.';\n for (let j = 0; j < 3; j++) {\n let h = codecArray[j].toString(16);\n if (h.length < 2) {\n h = '0' + h;\n }\n codecString += h;\n }\n meta.codec = codecString;\n\n let mi = this._mediaInfo;\n mi.width = meta.codecWidth;\n mi.height = meta.codecHeight;\n mi.fps = meta.frameRate.fps;\n mi.profile = meta.profile;\n mi.level = meta.level;\n mi.chromaFormat = config.chroma_format_string;\n mi.sarNum = meta.sarRatio.width;\n mi.sarDen = meta.sarRatio.height;\n mi.videoCodec = codecString;\n\n if (mi.hasAudio) {\n if (mi.audioCodec != null) {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + ',' + mi.audioCodec + '\"';\n }\n } else {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + '\"';\n }\n if (mi.isComplete()) {\n this._onMediaInfo(mi);\n }\n }\n\n let ppsCount = v.getUint8(offset); // numOfPictureParameterSets\n if (ppsCount === 0) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord: No PPS');\n return;\n } else if (ppsCount > 1) {\n Log.w(this.TAG, `Flv: Strange AVCDecoderConfigurationRecord: PPS Count = ${ppsCount}`);\n }\n\n offset++;\n\n for (let i = 0; i < ppsCount; i++) {\n let len = v.getUint16(offset, !le); // pictureParameterSetLength\n offset += 2;\n\n if (len === 0) {\n continue;\n }\n\n // pps is useless for extracting video information\n offset += len;\n }\n\n meta.avcc = new Uint8Array(dataSize);\n meta.avcc.set(new Uint8Array(arrayBuffer, dataOffset, dataSize), 0);\n Log.v(this.TAG, 'Parsed AVCDecoderConfigurationRecord');\n\n if (this._isInitialMetadataDispatched()) {\n // flush parsed frames\n if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {\n this._onDataAvailable(this._audioTrack, this._videoTrack);\n }\n } else {\n this._videoInitialMetadataDispatched = true;\n }\n // notify new metadata\n this._dispatch = false;\n this._onTrackMetadata('video', meta);\n }\n\n _parseAVCVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType, cts) {\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let units = [], length = 0;\n\n let offset = 0;\n const lengthSize = this._naluLengthSize;\n let dts = this._timestampBase + tagTimestamp;\n let keyframe = (frameType === 1); // from FLV Frame Type constants\n\n while (offset < dataSize) {\n if (offset + 4 >= dataSize) {\n Log.w(this.TAG, `Malformed Nalu near timestamp ${dts}, offset = ${offset}, dataSize = ${dataSize}`);\n break; // data not enough for next Nalu\n }\n // Nalu with length-header (AVC1)\n let naluSize = v.getUint32(offset, !le); // Big-Endian read\n if (lengthSize === 3) {\n naluSize >>>= 8;\n }\n if (naluSize > dataSize - lengthSize) {\n Log.w(this.TAG, `Malformed Nalus near timestamp ${dts}, NaluSize > DataSize!`);\n return;\n }\n\n let unitType = v.getUint8(offset + lengthSize) & 0x1F;\n\n if (unitType === 5) { // IDR\n keyframe = true;\n }\n\n let data = new Uint8Array(arrayBuffer, dataOffset + offset, lengthSize + naluSize);\n let unit = {type: unitType, data: data};\n units.push(unit);\n length += data.byteLength;\n\n offset += lengthSize + naluSize;\n }\n\n if (units.length) {\n let track = this._videoTrack;\n let avcSample = {\n units: units,\n length: length,\n isKeyframe: keyframe,\n dts: dts,\n cts: cts,\n pts: (dts + cts)\n };\n if (keyframe) {\n avcSample.fileposition = tagPosition;\n }\n track.samples.push(avcSample);\n track.length += length;\n }\n }\n\n}\n\nexport default FLVDemuxer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport ExpGolomb from './exp-golomb.js';\n\nclass SPSParser {\n\n static _ebsp2rbsp(uint8array) {\n let src = uint8array;\n let src_length = src.byteLength;\n let dst = new Uint8Array(src_length);\n let dst_idx = 0;\n\n for (let i = 0; i < src_length; i++) {\n if (i >= 2) {\n // Unescape: Skip 0x03 after 00 00\n if (src[i] === 0x03 && src[i - 1] === 0x00 && src[i - 2] === 0x00) {\n continue;\n }\n }\n dst[dst_idx] = src[i];\n dst_idx++;\n }\n\n return new Uint8Array(dst.buffer, 0, dst_idx);\n }\n\n static parseSPS(uint8array) {\n let rbsp = SPSParser._ebsp2rbsp(uint8array);\n let gb = new ExpGolomb(rbsp);\n\n gb.readByte();\n let profile_idc = gb.readByte(); // profile_idc\n gb.readByte(); // constraint_set_flags[5] + reserved_zero[3]\n let level_idc = gb.readByte(); // level_idc\n gb.readUEG(); // seq_parameter_set_id\n\n let profile_string = SPSParser.getProfileString(profile_idc);\n let level_string = SPSParser.getLevelString(level_idc);\n let chroma_format_idc = 1;\n let chroma_format = 420;\n let chroma_format_table = [0, 420, 422, 444];\n let bit_depth = 8;\n\n if (profile_idc === 100 || profile_idc === 110 || profile_idc === 122 ||\n profile_idc === 244 || profile_idc === 44 || profile_idc === 83 ||\n profile_idc === 86 || profile_idc === 118 || profile_idc === 128 ||\n profile_idc === 138 || profile_idc === 144) {\n\n chroma_format_idc = gb.readUEG();\n if (chroma_format_idc === 3) {\n gb.readBits(1); // separate_colour_plane_flag\n }\n if (chroma_format_idc <= 3) {\n chroma_format = chroma_format_table[chroma_format_idc];\n }\n\n bit_depth = gb.readUEG() + 8; // bit_depth_luma_minus8\n gb.readUEG(); // bit_depth_chroma_minus8\n gb.readBits(1); // qpprime_y_zero_transform_bypass_flag\n if (gb.readBool()) { // seq_scaling_matrix_present_flag\n let scaling_list_count = (chroma_format_idc !== 3) ? 8 : 12;\n for (let i = 0; i < scaling_list_count; i++) {\n if (gb.readBool()) { // seq_scaling_list_present_flag\n if (i < 6) {\n SPSParser._skipScalingList(gb, 16);\n } else {\n SPSParser._skipScalingList(gb, 64);\n }\n }\n }\n }\n }\n gb.readUEG(); // log2_max_frame_num_minus4\n let pic_order_cnt_type = gb.readUEG();\n if (pic_order_cnt_type === 0) {\n gb.readUEG(); // log2_max_pic_order_cnt_lsb_minus_4\n } else if (pic_order_cnt_type === 1) {\n gb.readBits(1); // delta_pic_order_always_zero_flag\n gb.readSEG(); // offset_for_non_ref_pic\n gb.readSEG(); // offset_for_top_to_bottom_field\n let num_ref_frames_in_pic_order_cnt_cycle = gb.readUEG();\n for (let i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) {\n gb.readSEG(); // offset_for_ref_frame\n }\n }\n gb.readUEG(); // max_num_ref_frames\n gb.readBits(1); // gaps_in_frame_num_value_allowed_flag\n\n let pic_width_in_mbs_minus1 = gb.readUEG();\n let pic_height_in_map_units_minus1 = gb.readUEG();\n\n let frame_mbs_only_flag = gb.readBits(1);\n if (frame_mbs_only_flag === 0) {\n gb.readBits(1); // mb_adaptive_frame_field_flag\n }\n gb.readBits(1); // direct_8x8_inference_flag\n\n let frame_crop_left_offset = 0;\n let frame_crop_right_offset = 0;\n let frame_crop_top_offset = 0;\n let frame_crop_bottom_offset = 0;\n\n let frame_cropping_flag = gb.readBool();\n if (frame_cropping_flag) {\n frame_crop_left_offset = gb.readUEG();\n frame_crop_right_offset = gb.readUEG();\n frame_crop_top_offset = gb.readUEG();\n frame_crop_bottom_offset = gb.readUEG();\n }\n\n let sar_width = 1, sar_height = 1;\n let fps = 0, fps_fixed = true, fps_num = 0, fps_den = 0;\n\n let vui_parameters_present_flag = gb.readBool();\n if (vui_parameters_present_flag) {\n if (gb.readBool()) { // aspect_ratio_info_present_flag\n let aspect_ratio_idc = gb.readByte();\n let sar_w_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2];\n let sar_h_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1];\n\n if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {\n sar_width = sar_w_table[aspect_ratio_idc - 1];\n sar_height = sar_h_table[aspect_ratio_idc - 1];\n } else if (aspect_ratio_idc === 255) {\n sar_width = gb.readByte() << 8 | gb.readByte();\n sar_height = gb.readByte() << 8 | gb.readByte();\n }\n }\n\n if (gb.readBool()) { // overscan_info_present_flag\n gb.readBool(); // overscan_appropriate_flag\n }\n if (gb.readBool()) { // video_signal_type_present_flag\n gb.readBits(4); // video_format & video_full_range_flag\n if (gb.readBool()) { // colour_description_present_flag\n gb.readBits(24); // colour_primaries & transfer_characteristics & matrix_coefficients\n }\n }\n if (gb.readBool()) { // chroma_loc_info_present_flag\n gb.readUEG(); // chroma_sample_loc_type_top_field\n gb.readUEG(); // chroma_sample_loc_type_bottom_field\n }\n if (gb.readBool()) { // timing_info_present_flag\n let num_units_in_tick = gb.readBits(32);\n let time_scale = gb.readBits(32);\n fps_fixed = gb.readBool(); // fixed_frame_rate_flag\n\n fps_num = time_scale;\n fps_den = num_units_in_tick * 2;\n fps = fps_num / fps_den;\n }\n }\n\n let sarScale = 1;\n if (sar_width !== 1 || sar_height !== 1) {\n sarScale = sar_width / sar_height;\n }\n\n let crop_unit_x = 0, crop_unit_y = 0;\n if (chroma_format_idc === 0) {\n crop_unit_x = 1;\n crop_unit_y = 2 - frame_mbs_only_flag;\n } else {\n let sub_wc = (chroma_format_idc === 3) ? 1 : 2;\n let sub_hc = (chroma_format_idc === 1) ? 2 : 1;\n crop_unit_x = sub_wc;\n crop_unit_y = sub_hc * (2 - frame_mbs_only_flag);\n }\n\n let codec_width = (pic_width_in_mbs_minus1 + 1) * 16;\n let codec_height = (2 - frame_mbs_only_flag) * ((pic_height_in_map_units_minus1 + 1) * 16);\n\n codec_width -= (frame_crop_left_offset + frame_crop_right_offset) * crop_unit_x;\n codec_height -= (frame_crop_top_offset + frame_crop_bottom_offset) * crop_unit_y;\n\n let present_width = Math.ceil(codec_width * sarScale);\n\n gb.destroy();\n gb = null;\n\n return {\n profile_string: profile_string, // baseline, high, high10, ...\n level_string: level_string, // 3, 3.1, 4, 4.1, 5, 5.1, ...\n bit_depth: bit_depth, // 8bit, 10bit, ...\n chroma_format: chroma_format, // 4:2:0, 4:2:2, ...\n chroma_format_string: SPSParser.getChromaFormatString(chroma_format),\n\n frame_rate: {\n fixed: fps_fixed,\n fps: fps,\n fps_den: fps_den,\n fps_num: fps_num\n },\n\n sar_ratio: {\n width: sar_width,\n height: sar_height\n },\n\n codec_size: {\n width: codec_width,\n height: codec_height\n },\n\n present_size: {\n width: present_width,\n height: codec_height\n }\n };\n }\n\n static _skipScalingList(gb, count) {\n let last_scale = 8, next_scale = 8;\n let delta_scale = 0;\n for (let i = 0; i < count; i++) {\n if (next_scale !== 0) {\n delta_scale = gb.readSEG();\n next_scale = (last_scale + delta_scale + 256) % 256;\n }\n last_scale = (next_scale === 0) ? last_scale : next_scale;\n }\n }\n\n static getProfileString(profile_idc) {\n switch (profile_idc) {\n case 66:\n return 'Baseline';\n case 77:\n return 'Main';\n case 88:\n return 'Extended';\n case 100:\n return 'High';\n case 110:\n return 'High10';\n case 122:\n return 'High422';\n case 244:\n return 'High444';\n default:\n return 'Unknown';\n }\n }\n\n static getLevelString(level_idc) {\n return (level_idc / 10).toFixed(1);\n }\n\n static getChromaFormatString(chroma) {\n switch (chroma) {\n case 420:\n return '4:2:0';\n case 422:\n return '4:2:2';\n case 444:\n return '4:4:4';\n default:\n return 'Unknown';\n }\n }\n\n}\n\nexport default SPSParser;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Polyfill from './utils/polyfill.js';\nimport Features from './core/features.js';\nimport FlvPlayer from './player/flv-player.js';\nimport NativePlayer from './player/native-player.js';\nimport PlayerEvents from './player/player-events.js';\nimport {ErrorTypes, ErrorDetails} from './player/player-errors.js';\nimport LoggingControl from './utils/logging-control.js';\nimport {InvalidArgumentException} from './utils/exception.js';\n\n// here are all the interfaces\n\n// install polyfills\nPolyfill.install();\n\n\n// factory method\nfunction createPlayer(mediaDataSource, optionalConfig) {\n let mds = mediaDataSource;\n if (mds == null || typeof mds !== 'object') {\n throw new InvalidArgumentException('MediaDataSource must be an javascript object!');\n }\n\n if (!mds.hasOwnProperty('type')) {\n throw new InvalidArgumentException('MediaDataSource must has type field to indicate video file type!');\n }\n\n switch (mds.type) {\n case 'flv':\n return new FlvPlayer(mds, optionalConfig);\n default:\n return new NativePlayer(mds, optionalConfig);\n }\n}\n\n\n// feature detection\nfunction isSupported() {\n return Features.supportMSEH264Playback();\n}\n\nfunction getFeatureList() {\n return Features.getFeatureList();\n}\n\n\n// interfaces\nlet flvjs = {};\n\nflvjs.createPlayer = createPlayer;\nflvjs.isSupported = isSupported;\nflvjs.getFeatureList = getFeatureList;\n\nflvjs.Events = PlayerEvents;\nflvjs.ErrorTypes = ErrorTypes;\nflvjs.ErrorDetails = ErrorDetails;\n\nflvjs.FlvPlayer = FlvPlayer;\nflvjs.NativePlayer = NativePlayer;\nflvjs.LoggingControl = LoggingControl;\n\nObject.defineProperty(flvjs, 'version', {\n enumerable: true,\n get: function () {\n // replaced by browserify-versionify transform\n return '__VERSION__';\n }\n});\n\nexport default flvjs;","// entry/index file\n\n// make it compatible with browserify's umd wrapper\nmodule.exports = require('./flv.js').default;\n","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n/* fetch + stream IO loader. Currently working on chrome 43+.\n * fetch provides a better alternative http API to XMLHttpRequest\n *\n * fetch spec https://fetch.spec.whatwg.org/\n * stream spec https://streams.spec.whatwg.org/\n */\nclass FetchStreamLoader extends BaseLoader {\n\n static isSupported() {\n try {\n // fetch + stream is broken on Microsoft Edge. Disable before build 15048.\n // see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8196907/\n // Fixed in Jan 10, 2017. Build 15048+ removed from blacklist.\n let isWorkWellEdge = Browser.msedge && Browser.version.minor >= 15048;\n let browserNotBlacklisted = Browser.msedge ? isWorkWellEdge : true;\n return (self.fetch && self.ReadableStream && browserNotBlacklisted);\n } catch (e) {\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('fetch-stream-loader');\n this.TAG = 'FetchStreamLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = true;\n\n this._requestAbort = false;\n this._contentLength = null;\n this._receivedLength = 0;\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n super.destroy();\n }\n\n open(dataSource, range) {\n this._dataSource = dataSource;\n this._range = range;\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n\n let headers = new self.Headers();\n\n if (typeof seekConfig.headers === 'object') {\n let configHeaders = seekConfig.headers;\n for (let key in configHeaders) {\n if (configHeaders.hasOwnProperty(key)) {\n headers.append(key, configHeaders[key]);\n }\n }\n }\n\n let params = {\n method: 'GET',\n headers: headers,\n mode: 'cors',\n cache: 'default',\n // The default policy of Fetch API in the whatwg standard\n // Safari incorrectly indicates 'no-referrer' as default policy, fuck it\n referrerPolicy: 'no-referrer-when-downgrade'\n };\n\n // cors is enabled by default\n if (dataSource.cors === false) {\n // no-cors means 'disregard cors policy', which can only be used in ServiceWorker\n params.mode = 'same-origin';\n }\n\n // withCredentials is disabled by default\n if (dataSource.withCredentials) {\n params.credentials = 'include';\n }\n\n // referrerPolicy from config\n if (dataSource.referrerPolicy) {\n params.referrerPolicy = dataSource.referrerPolicy;\n }\n\n this._status = LoaderStatus.kConnecting;\n self.fetch(seekConfig.url, params).then((res) => {\n if (this._requestAbort) {\n this._requestAbort = false;\n this._status = LoaderStatus.kIdle;\n return;\n }\n if (res.ok && (res.status >= 200 && res.status <= 299)) {\n if (res.url !== seekConfig.url) {\n if (this._onURLRedirect) {\n let redirectedURL = this._seekHandler.removeURLParameters(res.url);\n this._onURLRedirect(redirectedURL);\n }\n }\n\n let lengthHeader = res.headers.get('Content-Length');\n if (lengthHeader != null) {\n this._contentLength = parseInt(lengthHeader);\n if (this._contentLength !== 0) {\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n }\n\n return this._pump.call(this, res.body.getReader());\n } else {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: res.status, msg: res.statusText});\n } else {\n throw new RuntimeException('FetchStreamLoader: Http code invalid, ' + res.status + ' ' + res.statusText);\n }\n }\n }).catch((e) => {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, {code: -1, msg: e.message});\n } else {\n throw e;\n }\n });\n }\n\n abort() {\n this._requestAbort = true;\n }\n\n _pump(reader) { // ReadableStreamReader\n return reader.read().then((result) => {\n if (result.done) {\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);\n }\n } else {\n if (this._requestAbort === true) {\n this._requestAbort = false;\n this._status = LoaderStatus.kComplete;\n return reader.cancel();\n }\n\n this._status = LoaderStatus.kBuffering;\n\n let chunk = result.value.buffer;\n let byteStart = this._range.from + this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n\n this._pump(reader);\n }\n }).catch((e) => {\n if (e.code === 11 && Browser.msedge) { // InvalidStateError on Microsoft Edge\n // Workaround: Edge may throw InvalidStateError after ReadableStreamReader.cancel() call\n // Ignore the unknown exception.\n // Related issue: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11265202/\n return;\n }\n\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if ((e.code === 19 || e.message === 'network error') && // NETWORK_ERR\n (this._contentLength === null ||\n (this._contentLength !== null && this._receivedLength < this._contentLength))) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: e.code, msg: 'Fetch stream meet Early-EOF'};\n } else {\n type = LoaderErrors.EXCEPTION;\n info = {code: e.code, msg: e.message};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n });\n }\n\n}\n\nexport default FetchStreamLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport SpeedSampler from './speed-sampler.js';\nimport {LoaderStatus, LoaderErrors} from './loader.js';\nimport FetchStreamLoader from './fetch-stream-loader.js';\nimport MozChunkedLoader from './xhr-moz-chunked-loader.js';\nimport MSStreamLoader from './xhr-msstream-loader.js';\nimport RangeLoader from './xhr-range-loader.js';\nimport WebSocketLoader from './websocket-loader.js';\nimport RangeSeekHandler from './range-seek-handler.js';\nimport ParamSeekHandler from './param-seek-handler.js';\nimport {RuntimeException, IllegalStateException, InvalidArgumentException} from '../utils/exception.js';\n\n/**\n * DataSource: {\n * url: string,\n * filesize: number,\n * cors: boolean,\n * withCredentials: boolean\n * }\n * \n */\n\n// Manage IO Loaders\nclass IOController {\n\n constructor(dataSource, config, extraData) {\n this.TAG = 'IOController';\n\n this._config = config;\n this._extraData = extraData;\n\n this._stashInitialSize = 1024 * 384; // default initial size: 384KB\n if (config.stashInitialSize != undefined && config.stashInitialSize > 0) {\n // apply from config\n this._stashInitialSize = config.stashInitialSize;\n }\n\n this._stashUsed = 0;\n this._stashSize = this._stashInitialSize;\n this._bufferSize = 1024 * 1024 * 3; // initial size: 3MB\n this._stashBuffer = new ArrayBuffer(this._bufferSize);\n this._stashByteStart = 0;\n this._enableStash = true;\n if (config.enableStashBuffer === false) {\n this._enableStash = false;\n }\n\n this._loader = null;\n this._loaderClass = null;\n this._seekHandler = null;\n\n this._dataSource = dataSource;\n this._isWebSocketURL = /wss?:\\/\\/(.+?)/.test(dataSource.url);\n this._refTotalLength = dataSource.filesize ? dataSource.filesize : null;\n this._totalLength = this._refTotalLength;\n this._fullRequestFlag = false;\n this._currentRange = null;\n this._redirectedURL = null;\n\n this._speedNormalized = 0;\n this._speedSampler = new SpeedSampler();\n this._speedNormalizeList = [64, 128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096];\n\n this._isEarlyEofReconnecting = false;\n\n this._paused = false;\n this._resumeFrom = 0;\n\n this._onDataArrival = null;\n this._onSeeked = null;\n this._onError = null;\n this._onComplete = null;\n this._onRedirect = null;\n this._onRecoveredEarlyEof = null;\n\n this._selectSeekHandler();\n this._selectLoader();\n this._createLoader();\n }\n\n destroy() {\n if (this._loader.isWorking()) {\n this._loader.abort();\n }\n this._loader.destroy();\n this._loader = null;\n this._loaderClass = null;\n this._dataSource = null;\n this._stashBuffer = null;\n this._stashUsed = this._stashSize = this._bufferSize = this._stashByteStart = 0;\n this._currentRange = null;\n this._speedSampler = null;\n\n this._isEarlyEofReconnecting = false;\n\n this._onDataArrival = null;\n this._onSeeked = null;\n this._onError = null;\n this._onComplete = null;\n this._onRedirect = null;\n this._onRecoveredEarlyEof = null;\n\n this._extraData = null;\n }\n\n isWorking() {\n return this._loader && this._loader.isWorking() && !this._paused;\n }\n\n isPaused() {\n return this._paused;\n }\n\n get status() {\n return this._loader.status;\n }\n\n get extraData() {\n return this._extraData;\n }\n\n set extraData(data) {\n this._extraData = data;\n }\n\n // prototype: function onDataArrival(chunks: ArrayBuffer, byteStart: number): number\n get onDataArrival() {\n return this._onDataArrival;\n }\n\n set onDataArrival(callback) {\n this._onDataArrival = callback;\n }\n\n get onSeeked() {\n return this._onSeeked;\n }\n\n set onSeeked(callback) {\n this._onSeeked = callback;\n }\n\n // prototype: function onError(type: number, info: {code: number, msg: string}): void\n get onError() {\n return this._onError;\n }\n\n set onError(callback) {\n this._onError = callback;\n }\n\n get onComplete() {\n return this._onComplete;\n }\n\n set onComplete(callback) {\n this._onComplete = callback;\n }\n\n get onRedirect() {\n return this._onRedirect;\n }\n\n set onRedirect(callback) {\n this._onRedirect = callback;\n }\n\n get onRecoveredEarlyEof() {\n return this._onRecoveredEarlyEof;\n }\n\n set onRecoveredEarlyEof(callback) {\n this._onRecoveredEarlyEof = callback;\n }\n\n get currentURL() {\n return this._dataSource.url;\n }\n\n get hasRedirect() {\n return (this._redirectedURL != null || this._dataSource.redirectedURL != undefined);\n }\n\n get currentRedirectedURL() {\n return this._redirectedURL || this._dataSource.redirectedURL;\n }\n\n // in KB/s\n get currentSpeed() {\n if (this._loaderClass === RangeLoader) {\n // SpeedSampler is inaccuracy if loader is RangeLoader\n return this._loader.currentSpeed;\n }\n return this._speedSampler.lastSecondKBps;\n }\n\n get loaderType() {\n return this._loader.type;\n }\n\n _selectSeekHandler() {\n let config = this._config;\n\n if (config.seekType === 'range') {\n this._seekHandler = new RangeSeekHandler(this._config.rangeLoadZeroStart);\n } else if (config.seekType === 'param') {\n let paramStart = config.seekParamStart || 'bstart';\n let paramEnd = config.seekParamEnd || 'bend';\n\n this._seekHandler = new ParamSeekHandler(paramStart, paramEnd);\n } else if (config.seekType === 'custom') {\n if (typeof config.customSeekHandler !== 'function') {\n throw new InvalidArgumentException('Custom seekType specified in config but invalid customSeekHandler!');\n }\n this._seekHandler = new config.customSeekHandler();\n } else {\n throw new InvalidArgumentException(`Invalid seekType in config: ${config.seekType}`);\n }\n }\n\n _selectLoader() {\n if (this._isWebSocketURL) {\n this._loaderClass = WebSocketLoader;\n } else if (FetchStreamLoader.isSupported()) {\n this._loaderClass = FetchStreamLoader;\n } else if (MozChunkedLoader.isSupported()) {\n this._loaderClass = MozChunkedLoader;\n } else if (RangeLoader.isSupported()) {\n this._loaderClass = RangeLoader;\n } else {\n throw new RuntimeException('Your browser doesn\\'t support xhr with arraybuffer responseType!');\n }\n }\n\n _createLoader() {\n this._loader = new this._loaderClass(this._seekHandler, this._config);\n if (this._loader.needStashBuffer === false) {\n this._enableStash = false;\n }\n this._loader.onContentLengthKnown = this._onContentLengthKnown.bind(this);\n this._loader.onURLRedirect = this._onURLRedirect.bind(this);\n this._loader.onDataArrival = this._onLoaderChunkArrival.bind(this);\n this._loader.onComplete = this._onLoaderComplete.bind(this);\n this._loader.onError = this._onLoaderError.bind(this);\n }\n\n open(optionalFrom) {\n this._currentRange = {from: 0, to: -1};\n if (optionalFrom) {\n this._currentRange.from = optionalFrom;\n }\n\n this._speedSampler.reset();\n if (!optionalFrom) {\n this._fullRequestFlag = true;\n }\n\n this._loader.open(this._dataSource, Object.assign({}, this._currentRange));\n }\n\n abort() {\n this._loader.abort();\n\n if (this._paused) {\n this._paused = false;\n this._resumeFrom = 0;\n }\n }\n\n pause() {\n if (this.isWorking()) {\n this._loader.abort();\n\n if (this._stashUsed !== 0) {\n this._resumeFrom = this._stashByteStart;\n this._currentRange.to = this._stashByteStart - 1;\n } else {\n this._resumeFrom = this._currentRange.to + 1;\n }\n this._stashUsed = 0;\n this._stashByteStart = 0;\n this._paused = true;\n }\n }\n\n resume() {\n if (this._paused) {\n this._paused = false;\n let bytes = this._resumeFrom;\n this._resumeFrom = 0;\n this._internalSeek(bytes, true);\n }\n }\n\n seek(bytes) {\n this._paused = false;\n this._stashUsed = 0;\n this._stashByteStart = 0;\n this._internalSeek(bytes, true);\n }\n\n /**\n * When seeking request is from media seeking, unconsumed stash data should be dropped\n * However, stash data shouldn't be dropped if seeking requested from http reconnection\n *\n * @dropUnconsumed: Ignore and discard all unconsumed data in stash buffer\n */\n _internalSeek(bytes, dropUnconsumed) {\n if (this._loader.isWorking()) {\n this._loader.abort();\n }\n\n // dispatch & flush stash buffer before seek\n this._flushStashBuffer(dropUnconsumed);\n\n this._loader.destroy();\n this._loader = null;\n\n let requestRange = {from: bytes, to: -1};\n this._currentRange = {from: requestRange.from, to: -1};\n\n this._speedSampler.reset();\n this._stashSize = this._stashInitialSize;\n this._createLoader();\n this._loader.open(this._dataSource, requestRange);\n\n if (this._onSeeked) {\n this._onSeeked();\n }\n }\n\n updateUrl(url) {\n if (!url || typeof url !== 'string' || url.length === 0) {\n throw new InvalidArgumentException('Url must be a non-empty string!');\n }\n\n this._dataSource.url = url;\n\n // TODO: replace with new url\n }\n\n _expandBuffer(expectedBytes) {\n let bufferNewSize = this._stashSize;\n while (bufferNewSize + 1024 * 1024 * 1 < expectedBytes) {\n bufferNewSize *= 2;\n }\n\n bufferNewSize += 1024 * 1024 * 1; // bufferSize = stashSize + 1MB\n if (bufferNewSize === this._bufferSize) {\n return;\n }\n\n let newBuffer = new ArrayBuffer(bufferNewSize);\n\n if (this._stashUsed > 0) { // copy existing data into new buffer\n let stashOldArray = new Uint8Array(this._stashBuffer, 0, this._stashUsed);\n let stashNewArray = new Uint8Array(newBuffer, 0, bufferNewSize);\n stashNewArray.set(stashOldArray, 0);\n }\n\n this._stashBuffer = newBuffer;\n this._bufferSize = bufferNewSize;\n }\n\n _normalizeSpeed(input) {\n let list = this._speedNormalizeList;\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (input < list[0]) {\n return list[0];\n }\n\n // binary search\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (input >= list[mid] && input < list[mid + 1])) {\n return list[mid];\n } else if (list[mid] < input) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n }\n\n _adjustStashSize(normalized) {\n let stashSizeKB = 0;\n\n if (this._config.isLive) {\n // live stream: always use single normalized speed for size of stashSizeKB\n stashSizeKB = normalized;\n } else {\n if (normalized < 512) {\n stashSizeKB = normalized;\n } else if (normalized >= 512 && normalized <= 1024) {\n stashSizeKB = Math.floor(normalized * 1.5);\n } else {\n stashSizeKB = normalized * 2;\n }\n }\n\n if (stashSizeKB > 8192) {\n stashSizeKB = 8192;\n }\n\n let bufferSize = stashSizeKB * 1024 + 1024 * 1024 * 1; // stashSize + 1MB\n if (this._bufferSize < bufferSize) {\n this._expandBuffer(bufferSize);\n }\n this._stashSize = stashSizeKB * 1024;\n }\n\n _dispatchChunks(chunks, byteStart) {\n this._currentRange.to = byteStart + chunks.byteLength - 1;\n return this._onDataArrival(chunks, byteStart);\n }\n\n _onURLRedirect(redirectedURL) {\n this._redirectedURL = redirectedURL;\n if (this._onRedirect) {\n this._onRedirect(redirectedURL);\n }\n }\n\n _onContentLengthKnown(contentLength) {\n if (contentLength && this._fullRequestFlag) {\n this._totalLength = contentLength;\n this._fullRequestFlag = false;\n }\n }\n\n _onLoaderChunkArrival(chunk, byteStart, receivedLength) {\n if (!this._onDataArrival) {\n throw new IllegalStateException('IOController: No existing consumer (onDataArrival) callback!');\n }\n if (this._paused) {\n return;\n }\n if (this._isEarlyEofReconnecting) {\n // Auto-reconnect for EarlyEof succeed, notify to upper-layer by callback\n this._isEarlyEofReconnecting = false;\n if (this._onRecoveredEarlyEof) {\n this._onRecoveredEarlyEof();\n }\n }\n\n this._speedSampler.addBytes(chunk.byteLength);\n\n // adjust stash buffer size according to network speed dynamically\n let KBps = this._speedSampler.lastSecondKBps;\n if (KBps !== 0) {\n let normalized = this._normalizeSpeed(KBps);\n if (this._speedNormalized !== normalized) {\n this._speedNormalized = normalized;\n this._adjustStashSize(normalized);\n }\n }\n\n if (!this._enableStash) { // disable stash\n if (this._stashUsed === 0) {\n // dispatch chunk directly to consumer;\n // check ret value (consumed bytes) and stash unconsumed to stashBuffer\n let consumed = this._dispatchChunks(chunk, byteStart);\n if (consumed < chunk.byteLength) { // unconsumed data remain.\n let remain = chunk.byteLength - consumed;\n if (remain > this._bufferSize) {\n this._expandBuffer(remain);\n }\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n stashArray.set(new Uint8Array(chunk, consumed), 0);\n this._stashUsed += remain;\n this._stashByteStart = byteStart + consumed;\n }\n } else {\n // else: Merge chunk into stashBuffer, and dispatch stashBuffer to consumer.\n if (this._stashUsed + chunk.byteLength > this._bufferSize) {\n this._expandBuffer(this._stashUsed + chunk.byteLength);\n }\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n stashArray.set(new Uint8Array(chunk), this._stashUsed);\n this._stashUsed += chunk.byteLength;\n let consumed = this._dispatchChunks(this._stashBuffer.slice(0, this._stashUsed), this._stashByteStart);\n if (consumed < this._stashUsed && consumed > 0) { // unconsumed data remain\n let remainArray = new Uint8Array(this._stashBuffer, consumed);\n stashArray.set(remainArray, 0);\n }\n this._stashUsed -= consumed;\n this._stashByteStart += consumed;\n }\n } else { // enable stash\n if (this._stashUsed === 0 && this._stashByteStart === 0) { // seeked? or init chunk?\n // This is the first chunk after seek action\n this._stashByteStart = byteStart;\n }\n if (this._stashUsed + chunk.byteLength <= this._stashSize) {\n // just stash\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._stashSize);\n stashArray.set(new Uint8Array(chunk), this._stashUsed);\n this._stashUsed += chunk.byteLength;\n } else { // stashUsed + chunkSize > stashSize, size limit exceeded\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n if (this._stashUsed > 0) { // There're stash datas in buffer\n // dispatch the whole stashBuffer, and stash remain data\n // then append chunk to stashBuffer (stash)\n let buffer = this._stashBuffer.slice(0, this._stashUsed);\n let consumed = this._dispatchChunks(buffer, this._stashByteStart);\n if (consumed < buffer.byteLength) {\n if (consumed > 0) {\n let remainArray = new Uint8Array(buffer, consumed);\n stashArray.set(remainArray, 0);\n this._stashUsed = remainArray.byteLength;\n this._stashByteStart += consumed;\n }\n } else {\n this._stashUsed = 0;\n this._stashByteStart += consumed;\n }\n if (this._stashUsed + chunk.byteLength > this._bufferSize) {\n this._expandBuffer(this._stashUsed + chunk.byteLength);\n stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n }\n stashArray.set(new Uint8Array(chunk), this._stashUsed);\n this._stashUsed += chunk.byteLength;\n } else { // stash buffer empty, but chunkSize > stashSize (oh, holy shit)\n // dispatch chunk directly and stash remain data\n let consumed = this._dispatchChunks(chunk, byteStart);\n if (consumed < chunk.byteLength) {\n let remain = chunk.byteLength - consumed;\n if (remain > this._bufferSize) {\n this._expandBuffer(remain);\n stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n }\n stashArray.set(new Uint8Array(chunk, consumed), 0);\n this._stashUsed += remain;\n this._stashByteStart = byteStart + consumed;\n }\n }\n }\n }\n }\n\n _flushStashBuffer(dropUnconsumed) {\n if (this._stashUsed > 0) {\n let buffer = this._stashBuffer.slice(0, this._stashUsed);\n let consumed = this._dispatchChunks(buffer, this._stashByteStart);\n let remain = buffer.byteLength - consumed;\n\n if (consumed < buffer.byteLength) {\n if (dropUnconsumed) {\n Log.w(this.TAG, `${remain} bytes unconsumed data remain when flush buffer, dropped`);\n } else {\n if (consumed > 0) {\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n let remainArray = new Uint8Array(buffer, consumed);\n stashArray.set(remainArray, 0);\n this._stashUsed = remainArray.byteLength;\n this._stashByteStart += consumed;\n }\n return 0;\n }\n }\n this._stashUsed = 0;\n this._stashByteStart = 0;\n return remain;\n }\n return 0;\n }\n\n _onLoaderComplete(from, to) {\n // Force-flush stash buffer, and drop unconsumed data\n this._flushStashBuffer(true);\n\n if (this._onComplete) {\n this._onComplete(this._extraData);\n }\n }\n\n _onLoaderError(type, data) {\n Log.e(this.TAG, `Loader error, code = ${data.code}, msg = ${data.msg}`);\n\n this._flushStashBuffer(false);\n\n if (this._isEarlyEofReconnecting) {\n // Auto-reconnect for EarlyEof failed, throw UnrecoverableEarlyEof error to upper-layer\n this._isEarlyEofReconnecting = false;\n type = LoaderErrors.UNRECOVERABLE_EARLY_EOF;\n }\n\n switch (type) {\n case LoaderErrors.EARLY_EOF: {\n if (!this._config.isLive) {\n // Do internal http reconnect if not live stream\n if (this._totalLength) {\n let nextFrom = this._currentRange.to + 1;\n if (nextFrom < this._totalLength) {\n Log.w(this.TAG, 'Connection lost, trying reconnect...');\n this._isEarlyEofReconnecting = true;\n this._internalSeek(nextFrom, false);\n }\n return;\n }\n // else: We don't know totalLength, throw UnrecoverableEarlyEof\n }\n // live stream: throw UnrecoverableEarlyEof error to upper-layer\n type = LoaderErrors.UNRECOVERABLE_EARLY_EOF;\n break;\n }\n case LoaderErrors.UNRECOVERABLE_EARLY_EOF:\n case LoaderErrors.CONNECTING_TIMEOUT:\n case LoaderErrors.HTTP_STATUS_CODE_INVALID:\n case LoaderErrors.EXCEPTION:\n break;\n }\n\n if (this._onError) {\n this._onError(type, data);\n } else {\n throw new RuntimeException('IOException: ' + data.msg);\n }\n }\n\n}\n\nexport default IOController;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {NotImplementedException} from '../utils/exception.js';\n\nexport const LoaderStatus = {\n kIdle: 0,\n kConnecting: 1,\n kBuffering: 2,\n kError: 3,\n kComplete: 4\n};\n\nexport const LoaderErrors = {\n OK: 'OK',\n EXCEPTION: 'Exception',\n HTTP_STATUS_CODE_INVALID: 'HttpStatusCodeInvalid',\n CONNECTING_TIMEOUT: 'ConnectingTimeout',\n EARLY_EOF: 'EarlyEof',\n UNRECOVERABLE_EARLY_EOF: 'UnrecoverableEarlyEof'\n};\n\n/* Loader has callbacks which have following prototypes:\n * function onContentLengthKnown(contentLength: number): void\n * function onURLRedirect(url: string): void\n * function onDataArrival(chunk: ArrayBuffer, byteStart: number, receivedLength: number): void\n * function onError(errorType: number, errorInfo: {code: number, msg: string}): void\n * function onComplete(rangeFrom: number, rangeTo: number): void\n */\nexport class BaseLoader {\n\n constructor(typeName) {\n this._type = typeName || 'undefined';\n this._status = LoaderStatus.kIdle;\n this._needStash = false;\n // callbacks\n this._onContentLengthKnown = null;\n this._onURLRedirect = null;\n this._onDataArrival = null;\n this._onError = null;\n this._onComplete = null;\n }\n\n destroy() {\n this._status = LoaderStatus.kIdle;\n this._onContentLengthKnown = null;\n this._onURLRedirect = null;\n this._onDataArrival = null;\n this._onError = null;\n this._onComplete = null;\n }\n\n isWorking() {\n return this._status === LoaderStatus.kConnecting || this._status === LoaderStatus.kBuffering;\n }\n\n get type() {\n return this._type;\n }\n\n get status() {\n return this._status;\n }\n\n get needStashBuffer() {\n return this._needStash;\n }\n\n get onContentLengthKnown() {\n return this._onContentLengthKnown;\n }\n\n set onContentLengthKnown(callback) {\n this._onContentLengthKnown = callback;\n }\n\n get onURLRedirect() {\n return this._onURLRedirect;\n }\n\n set onURLRedirect(callback) {\n this._onURLRedirect = callback;\n }\n\n get onDataArrival() {\n return this._onDataArrival;\n }\n\n set onDataArrival(callback) {\n this._onDataArrival = callback;\n }\n\n get onError() {\n return this._onError;\n }\n\n set onError(callback) {\n this._onError = callback;\n }\n\n get onComplete() {\n return this._onComplete;\n }\n\n set onComplete(callback) {\n this._onComplete = callback;\n }\n\n // pure virtual\n open(dataSource, range) {\n throw new NotImplementedException('Unimplemented abstract function!');\n }\n\n abort() {\n throw new NotImplementedException('Unimplemented abstract function!');\n }\n\n\n}","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass ParamSeekHandler {\n\n constructor(paramStart, paramEnd) {\n this._startName = paramStart;\n this._endName = paramEnd;\n }\n\n getConfig(baseUrl, range) {\n let url = baseUrl;\n\n if (range.from !== 0 || range.to !== -1) {\n let needAnd = true;\n if (url.indexOf('?') === -1) {\n url += '?';\n needAnd = false;\n }\n\n if (needAnd) {\n url += '&';\n }\n\n url += `${this._startName}=${range.from.toString()}`;\n\n if (range.to !== -1) {\n url += `&${this._endName}=${range.to.toString()}`;\n }\n }\n\n return {\n url: url,\n headers: {}\n };\n }\n\n removeURLParameters(seekedURL) {\n let baseURL = seekedURL.split('?')[0];\n let params = undefined;\n\n let queryIndex = seekedURL.indexOf('?');\n if (queryIndex !== -1) {\n params = seekedURL.substring(queryIndex + 1);\n }\n\n let resultParams = '';\n\n if (params != undefined && params.length > 0) {\n let pairs = params.split('&');\n\n for (let i = 0; i < pairs.length; i++) {\n let pair = pairs[i].split('=');\n let requireAnd = (i > 0);\n\n if (pair[0] !== this._startName && pair[0] !== this._endName) {\n if (requireAnd) {\n resultParams += '&';\n }\n resultParams += pairs[i];\n }\n }\n }\n\n return (resultParams.length === 0) ? baseURL : baseURL + '?' + resultParams;\n }\n\n}\n\nexport default ParamSeekHandler;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass RangeSeekHandler {\n\n constructor(zeroStart) {\n this._zeroStart = zeroStart || false;\n }\n\n getConfig(url, range) {\n let headers = {};\n\n if (range.from !== 0 || range.to !== -1) {\n let param;\n if (range.to !== -1) {\n param = `bytes=${range.from.toString()}-${range.to.toString()}`;\n } else {\n param = `bytes=${range.from.toString()}-`;\n }\n headers['Range'] = param;\n } else if (this._zeroStart) {\n headers['Range'] = 'bytes=0-';\n }\n\n return {\n url: url,\n headers: headers\n };\n }\n\n removeURLParameters(seekedURL) {\n return seekedURL;\n }\n\n}\n\nexport default RangeSeekHandler;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Utility class to calculate realtime network I/O speed\nclass SpeedSampler {\n\n constructor() {\n // milliseconds\n this._firstCheckpoint = 0;\n this._lastCheckpoint = 0;\n this._intervalBytes = 0;\n this._totalBytes = 0;\n this._lastSecondBytes = 0;\n\n // compatibility detection\n if (self.performance && self.performance.now) {\n this._now = self.performance.now.bind(self.performance);\n } else {\n this._now = Date.now;\n }\n }\n\n reset() {\n this._firstCheckpoint = this._lastCheckpoint = 0;\n this._totalBytes = this._intervalBytes = 0;\n this._lastSecondBytes = 0;\n }\n\n addBytes(bytes) {\n if (this._firstCheckpoint === 0) {\n this._firstCheckpoint = this._now();\n this._lastCheckpoint = this._firstCheckpoint;\n this._intervalBytes += bytes;\n this._totalBytes += bytes;\n } else if (this._now() - this._lastCheckpoint < 1000) {\n this._intervalBytes += bytes;\n this._totalBytes += bytes;\n } else { // duration >= 1000\n this._lastSecondBytes = this._intervalBytes;\n this._intervalBytes = bytes;\n this._totalBytes += bytes;\n this._lastCheckpoint = this._now();\n }\n }\n\n get currentKBps() {\n this.addBytes(0);\n\n let durationSeconds = (this._now() - this._lastCheckpoint) / 1000;\n if (durationSeconds == 0) durationSeconds = 1;\n return (this._intervalBytes / durationSeconds) / 1024;\n }\n\n get lastSecondKBps() {\n this.addBytes(0);\n\n if (this._lastSecondBytes !== 0) {\n return this._lastSecondBytes / 1024;\n } else { // lastSecondBytes === 0\n if (this._now() - this._lastCheckpoint >= 500) {\n // if time interval since last checkpoint has exceeded 500ms\n // the speed is nearly accurate\n return this.currentKBps;\n } else {\n // We don't know\n return 0;\n }\n }\n }\n\n get averageKBps() {\n let durationSeconds = (this._now() - this._firstCheckpoint) / 1000;\n return (this._totalBytes / durationSeconds) / 1024;\n }\n\n}\n\nexport default SpeedSampler;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n// For FLV over WebSocket live stream\nclass WebSocketLoader extends BaseLoader {\n\n static isSupported() {\n try {\n return (typeof self.WebSocket !== 'undefined');\n } catch (e) {\n return false;\n }\n }\n\n constructor() {\n super('websocket-loader');\n this.TAG = 'WebSocketLoader';\n\n this._needStash = true;\n\n this._ws = null;\n this._requestAbort = false;\n this._receivedLength = 0;\n }\n\n destroy() {\n if (this._ws) {\n this.abort();\n }\n super.destroy();\n }\n\n open(dataSource) {\n try {\n let ws = this._ws = new self.WebSocket(dataSource.url);\n ws.binaryType = 'arraybuffer';\n ws.onopen = this._onWebSocketOpen.bind(this);\n ws.onclose = this._onWebSocketClose.bind(this);\n ws.onmessage = this._onWebSocketMessage.bind(this);\n ws.onerror = this._onWebSocketError.bind(this);\n\n this._status = LoaderStatus.kConnecting;\n } catch (e) {\n this._status = LoaderStatus.kError;\n\n let info = {code: e.code, msg: e.message};\n\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n }\n\n abort() {\n let ws = this._ws;\n if (ws && (ws.readyState === 0 || ws.readyState === 1)) { // CONNECTING || OPEN\n this._requestAbort = true;\n ws.close();\n }\n\n this._ws = null;\n this._status = LoaderStatus.kComplete;\n }\n\n _onWebSocketOpen(e) {\n this._status = LoaderStatus.kBuffering;\n }\n\n _onWebSocketClose(e) {\n if (this._requestAbort === true) {\n this._requestAbort = false;\n return;\n }\n\n this._status = LoaderStatus.kComplete;\n\n if (this._onComplete) {\n this._onComplete(0, this._receivedLength - 1);\n }\n }\n\n _onWebSocketMessage(e) {\n if (e.data instanceof ArrayBuffer) {\n this._dispatchArrayBuffer(e.data);\n } else if (e.data instanceof Blob) {\n let reader = new FileReader();\n reader.onload = () => {\n this._dispatchArrayBuffer(reader.result);\n };\n reader.readAsArrayBuffer(e.data);\n } else {\n this._status = LoaderStatus.kError;\n let info = {code: -1, msg: 'Unsupported WebSocket message type: ' + e.data.constructor.name};\n\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n }\n\n _dispatchArrayBuffer(arraybuffer) {\n let chunk = arraybuffer;\n let byteStart = this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n }\n\n _onWebSocketError(e) {\n this._status = LoaderStatus.kError;\n\n let info = {\n code: e.code,\n msg: e.message\n };\n\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n}\n\nexport default WebSocketLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n// For FireFox browser which supports `xhr.responseType = 'moz-chunked-arraybuffer'`\nclass MozChunkedLoader extends BaseLoader {\n\n static isSupported() {\n try {\n let xhr = new XMLHttpRequest();\n // Firefox 37- requires .open() to be called before setting responseType\n xhr.open('GET', 'https://example.com', true);\n xhr.responseType = 'moz-chunked-arraybuffer';\n return (xhr.responseType === 'moz-chunked-arraybuffer');\n } catch (e) {\n Log.w('MozChunkedLoader', e.message);\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('xhr-moz-chunked-loader');\n this.TAG = 'MozChunkedLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = true;\n\n this._xhr = null;\n this._requestAbort = false;\n this._contentLength = null;\n this._receivedLength = 0;\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr.onprogress = null;\n this._xhr.onloadend = null;\n this._xhr.onerror = null;\n this._xhr = null;\n }\n super.destroy();\n }\n\n open(dataSource, range) {\n this._dataSource = dataSource;\n this._range = range;\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n this._requestURL = seekConfig.url;\n\n let xhr = this._xhr = new XMLHttpRequest();\n xhr.open('GET', seekConfig.url, true);\n xhr.responseType = 'moz-chunked-arraybuffer';\n xhr.onreadystatechange = this._onReadyStateChange.bind(this);\n xhr.onprogress = this._onProgress.bind(this);\n xhr.onloadend = this._onLoadEnd.bind(this);\n xhr.onerror = this._onXhrError.bind(this);\n\n // cors is auto detected and enabled by xhr\n\n // withCredentials is disabled by default\n if (dataSource.withCredentials && xhr['withCredentials']) {\n xhr.withCredentials = true;\n }\n\n if (typeof seekConfig.headers === 'object') {\n let headers = seekConfig.headers;\n\n for (let key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n }\n\n this._status = LoaderStatus.kConnecting;\n xhr.send();\n }\n\n abort() {\n this._requestAbort = true;\n if (this._xhr) {\n this._xhr.abort();\n }\n this._status = LoaderStatus.kComplete;\n }\n\n _onReadyStateChange(e) {\n let xhr = e.target;\n\n if (xhr.readyState === 2) { // HEADERS_RECEIVED\n if (xhr.responseURL != undefined && xhr.responseURL !== this._requestURL) {\n if (this._onURLRedirect) {\n let redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);\n this._onURLRedirect(redirectedURL);\n }\n }\n\n if (xhr.status !== 0 && (xhr.status < 200 || xhr.status > 299)) {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});\n } else {\n throw new RuntimeException('MozChunkedLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);\n }\n } else {\n this._status = LoaderStatus.kBuffering;\n }\n }\n }\n\n _onProgress(e) {\n if (this._status === LoaderStatus.kError) {\n // Ignore error response\n return;\n }\n\n if (this._contentLength === null) {\n if (e.total !== null && e.total !== 0) {\n this._contentLength = e.total;\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n }\n\n let chunk = e.target.response;\n let byteStart = this._range.from + this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n }\n\n _onLoadEnd(e) {\n if (this._requestAbort === true) {\n this._requestAbort = false;\n return;\n } else if (this._status === LoaderStatus.kError) {\n return;\n }\n\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);\n }\n }\n\n _onXhrError(e) {\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if (this._contentLength && e.loaded < this._contentLength) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: 'Moz-Chunked stream meet Early-Eof'};\n } else {\n type = LoaderErrors.EXCEPTION;\n info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n}\n\nexport default MozChunkedLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n/* Notice: ms-stream may cause IE/Edge browser crash if seek too frequently!!!\n * The browser may crash in wininet.dll. Disable for now.\n *\n * For IE11/Edge browser by microsoft which supports `xhr.responseType = 'ms-stream'`\n * Notice that ms-stream API sucks. The buffer is always expanding along with downloading.\n *\n * We need to abort the xhr if buffer size exceeded limit size (e.g. 16 MiB), then do reconnect.\n * in order to release previous ArrayBuffer to avoid memory leak\n *\n * Otherwise, the ArrayBuffer will increase to a terrible size that equals final file size.\n */\nclass MSStreamLoader extends BaseLoader {\n\n static isSupported() {\n try {\n if (typeof self.MSStream === 'undefined' || typeof self.MSStreamReader === 'undefined') {\n return false;\n }\n\n let xhr = new XMLHttpRequest();\n xhr.open('GET', 'https://example.com', true);\n xhr.responseType = 'ms-stream';\n return (xhr.responseType === 'ms-stream');\n } catch (e) {\n Log.w('MSStreamLoader', e.message);\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('xhr-msstream-loader');\n this.TAG = 'MSStreamLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = true;\n\n this._xhr = null;\n this._reader = null; // MSStreamReader\n\n this._totalRange = null;\n this._currentRange = null;\n\n this._currentRequestURL = null;\n this._currentRedirectedURL = null;\n\n this._contentLength = null;\n this._receivedLength = 0;\n\n this._bufferLimit = 16 * 1024 * 1024; // 16MB\n this._lastTimeBufferSize = 0;\n this._isReconnecting = false;\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n if (this._reader) {\n this._reader.onprogress = null;\n this._reader.onload = null;\n this._reader.onerror = null;\n this._reader = null;\n }\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr = null;\n }\n super.destroy();\n }\n\n open(dataSource, range) {\n this._internalOpen(dataSource, range, false);\n }\n\n _internalOpen(dataSource, range, isSubrange) {\n this._dataSource = dataSource;\n\n if (!isSubrange) {\n this._totalRange = range;\n } else {\n this._currentRange = range;\n }\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL) {\n if (this._currentRedirectedURL != undefined) {\n sourceURL = this._currentRedirectedURL;\n } else if (dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n this._currentRequestURL = seekConfig.url;\n\n let reader = this._reader = new self.MSStreamReader();\n reader.onprogress = this._msrOnProgress.bind(this);\n reader.onload = this._msrOnLoad.bind(this);\n reader.onerror = this._msrOnError.bind(this);\n\n let xhr = this._xhr = new XMLHttpRequest();\n xhr.open('GET', seekConfig.url, true);\n xhr.responseType = 'ms-stream';\n xhr.onreadystatechange = this._xhrOnReadyStateChange.bind(this);\n xhr.onerror = this._xhrOnError.bind(this);\n\n if (dataSource.withCredentials) {\n xhr.withCredentials = true;\n }\n\n if (typeof seekConfig.headers === 'object') {\n let headers = seekConfig.headers;\n\n for (let key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n }\n\n if (this._isReconnecting) {\n this._isReconnecting = false;\n } else {\n this._status = LoaderStatus.kConnecting;\n }\n xhr.send();\n }\n\n abort() {\n this._internalAbort();\n this._status = LoaderStatus.kComplete;\n }\n\n _internalAbort() {\n if (this._reader) {\n if (this._reader.readyState === 1) { // LOADING\n this._reader.abort();\n }\n this._reader.onprogress = null;\n this._reader.onload = null;\n this._reader.onerror = null;\n this._reader = null;\n }\n if (this._xhr) {\n this._xhr.abort();\n this._xhr.onreadystatechange = null;\n this._xhr = null;\n }\n }\n\n _xhrOnReadyStateChange(e) {\n let xhr = e.target;\n\n if (xhr.readyState === 2) { // HEADERS_RECEIVED\n if (xhr.status >= 200 && xhr.status <= 299) {\n this._status = LoaderStatus.kBuffering;\n\n if (xhr.responseURL != undefined) {\n let redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);\n if (xhr.responseURL !== this._currentRequestURL && redirectedURL !== this._currentRedirectedURL) {\n this._currentRedirectedURL = redirectedURL;\n if (this._onURLRedirect) {\n this._onURLRedirect(redirectedURL);\n }\n }\n }\n\n let lengthHeader = xhr.getResponseHeader('Content-Length');\n if (lengthHeader != null && this._contentLength == null) {\n let length = parseInt(lengthHeader);\n if (length > 0) {\n this._contentLength = length;\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n }\n } else {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});\n } else {\n throw new RuntimeException('MSStreamLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);\n }\n }\n } else if (xhr.readyState === 3) { // LOADING\n if (xhr.status >= 200 && xhr.status <= 299) {\n this._status = LoaderStatus.kBuffering;\n\n let msstream = xhr.response;\n this._reader.readAsArrayBuffer(msstream);\n }\n }\n }\n\n _xhrOnError(e) {\n this._status = LoaderStatus.kError;\n let type = LoaderErrors.EXCEPTION;\n let info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n _msrOnProgress(e) {\n let reader = e.target;\n let bigbuffer = reader.result;\n if (bigbuffer == null) { // result may be null, workaround for buggy M$\n this._doReconnectIfNeeded();\n return;\n }\n\n let slice = bigbuffer.slice(this._lastTimeBufferSize);\n this._lastTimeBufferSize = bigbuffer.byteLength;\n let byteStart = this._totalRange.from + this._receivedLength;\n this._receivedLength += slice.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(slice, byteStart, this._receivedLength);\n }\n\n if (bigbuffer.byteLength >= this._bufferLimit) {\n Log.v(this.TAG, `MSStream buffer exceeded max size near ${byteStart + slice.byteLength}, reconnecting...`);\n this._doReconnectIfNeeded();\n }\n }\n\n _doReconnectIfNeeded() {\n if (this._contentLength == null || this._receivedLength < this._contentLength) {\n this._isReconnecting = true;\n this._lastTimeBufferSize = 0;\n this._internalAbort();\n\n let range = {\n from: this._totalRange.from + this._receivedLength,\n to: -1\n };\n this._internalOpen(this._dataSource, range, true);\n }\n }\n\n _msrOnLoad(e) { // actually it is onComplete event\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._totalRange.from, this._totalRange.from + this._receivedLength - 1);\n }\n }\n\n _msrOnError(e) {\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if (this._contentLength && this._receivedLength < this._contentLength) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: 'MSStream meet Early-Eof'};\n } else {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n}\n\nexport default MSStreamLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport SpeedSampler from './speed-sampler.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n// Universal IO Loader, implemented by adding Range header in xhr's request header\nclass RangeLoader extends BaseLoader {\n\n static isSupported() {\n try {\n let xhr = new XMLHttpRequest();\n xhr.open('GET', 'https://example.com', true);\n xhr.responseType = 'arraybuffer';\n return (xhr.responseType === 'arraybuffer');\n } catch (e) {\n Log.w('RangeLoader', e.message);\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('xhr-range-loader');\n this.TAG = 'RangeLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = false;\n\n this._chunkSizeKBList = [\n 128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192\n ];\n this._currentChunkSizeKB = 384;\n this._currentSpeedNormalized = 0;\n this._zeroSpeedChunkCount = 0;\n\n this._xhr = null;\n this._speedSampler = new SpeedSampler();\n\n this._requestAbort = false;\n this._waitForTotalLength = false;\n this._totalLengthReceived = false;\n\n this._currentRequestURL = null;\n this._currentRedirectedURL = null;\n this._currentRequestRange = null;\n this._totalLength = null; // size of the entire file\n this._contentLength = null; // Content-Length of entire request range\n this._receivedLength = 0; // total received bytes\n this._lastTimeLoaded = 0; // received bytes of current request sub-range\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr.onprogress = null;\n this._xhr.onload = null;\n this._xhr.onerror = null;\n this._xhr = null;\n }\n super.destroy();\n }\n\n get currentSpeed() {\n return this._speedSampler.lastSecondKBps;\n }\n\n open(dataSource, range) {\n this._dataSource = dataSource;\n this._range = range;\n this._status = LoaderStatus.kConnecting;\n\n let useRefTotalLength = false;\n if (this._dataSource.filesize != undefined && this._dataSource.filesize !== 0) {\n useRefTotalLength = true;\n this._totalLength = this._dataSource.filesize;\n }\n\n if (!this._totalLengthReceived && !useRefTotalLength) {\n // We need total filesize\n this._waitForTotalLength = true;\n this._internalOpen(this._dataSource, {from: 0, to: -1});\n } else {\n // We have filesize, start loading\n this._openSubRange();\n }\n }\n\n _openSubRange() {\n let chunkSize = this._currentChunkSizeKB * 1024;\n\n let from = this._range.from + this._receivedLength;\n let to = from + chunkSize;\n\n if (this._contentLength != null) {\n if (to - this._range.from >= this._contentLength) {\n to = this._range.from + this._contentLength - 1;\n }\n }\n\n this._currentRequestRange = {from, to};\n this._internalOpen(this._dataSource, this._currentRequestRange);\n }\n\n _internalOpen(dataSource, range) {\n this._lastTimeLoaded = 0;\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL) {\n if (this._currentRedirectedURL != undefined) {\n sourceURL = this._currentRedirectedURL;\n } else if (dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n this._currentRequestURL = seekConfig.url;\n\n let xhr = this._xhr = new XMLHttpRequest();\n xhr.open('GET', seekConfig.url, true);\n xhr.responseType = 'arraybuffer';\n xhr.onreadystatechange = this._onReadyStateChange.bind(this);\n xhr.onprogress = this._onProgress.bind(this);\n xhr.onload = this._onLoad.bind(this);\n xhr.onerror = this._onXhrError.bind(this);\n\n if (dataSource.withCredentials && xhr['withCredentials']) {\n xhr.withCredentials = true;\n }\n\n if (typeof seekConfig.headers === 'object') {\n let headers = seekConfig.headers;\n\n for (let key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n }\n\n xhr.send();\n }\n\n abort() {\n this._requestAbort = true;\n this._internalAbort();\n this._status = LoaderStatus.kComplete;\n }\n\n _internalAbort() {\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr.onprogress = null;\n this._xhr.onload = null;\n this._xhr.onerror = null;\n this._xhr.abort();\n this._xhr = null;\n }\n }\n\n _onReadyStateChange(e) {\n let xhr = e.target;\n\n if (xhr.readyState === 2) { // HEADERS_RECEIVED\n if (xhr.responseURL != undefined) { // if the browser support this property\n let redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);\n if (xhr.responseURL !== this._currentRequestURL && redirectedURL !== this._currentRedirectedURL) {\n this._currentRedirectedURL = redirectedURL;\n if (this._onURLRedirect) {\n this._onURLRedirect(redirectedURL);\n }\n }\n }\n\n if ((xhr.status >= 200 && xhr.status <= 299)) {\n if (this._waitForTotalLength) {\n return;\n }\n this._status = LoaderStatus.kBuffering;\n } else {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});\n } else {\n throw new RuntimeException('RangeLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);\n }\n }\n }\n }\n\n _onProgress(e) {\n if (this._status === LoaderStatus.kError) {\n // Ignore error response\n return;\n }\n\n if (this._contentLength === null) {\n let openNextRange = false;\n\n if (this._waitForTotalLength) {\n this._waitForTotalLength = false;\n this._totalLengthReceived = true;\n openNextRange = true;\n\n let total = e.total;\n this._internalAbort();\n if (total != null & total !== 0) {\n this._totalLength = total;\n }\n }\n\n // calculate currrent request range's contentLength\n if (this._range.to === -1) {\n this._contentLength = this._totalLength - this._range.from;\n } else { // to !== -1\n this._contentLength = this._range.to - this._range.from + 1;\n }\n\n if (openNextRange) {\n this._openSubRange();\n return;\n }\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n\n let delta = e.loaded - this._lastTimeLoaded;\n this._lastTimeLoaded = e.loaded;\n this._speedSampler.addBytes(delta);\n }\n\n _normalizeSpeed(input) {\n let list = this._chunkSizeKBList;\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (input < list[0]) {\n return list[0];\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (input >= list[mid] && input < list[mid + 1])) {\n return list[mid];\n } else if (list[mid] < input) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n }\n\n _onLoad(e) {\n if (this._status === LoaderStatus.kError) {\n // Ignore error response\n return;\n }\n\n if (this._waitForTotalLength) {\n this._waitForTotalLength = false;\n return;\n }\n\n this._lastTimeLoaded = 0;\n let KBps = this._speedSampler.lastSecondKBps;\n if (KBps === 0) {\n this._zeroSpeedChunkCount++;\n if (this._zeroSpeedChunkCount >= 3) {\n // Try get currentKBps after 3 chunks\n KBps = this._speedSampler.currentKBps;\n }\n }\n\n if (KBps !== 0) {\n let normalized = this._normalizeSpeed(KBps);\n if (this._currentSpeedNormalized !== normalized) {\n this._currentSpeedNormalized = normalized;\n this._currentChunkSizeKB = normalized;\n }\n }\n\n let chunk = e.target.response;\n let byteStart = this._range.from + this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n let reportComplete = false;\n\n if (this._contentLength != null && this._receivedLength < this._contentLength) {\n // continue load next chunk\n this._openSubRange();\n } else {\n reportComplete = true;\n }\n\n // dispatch received chunk\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n\n if (reportComplete) {\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);\n }\n }\n }\n\n _onXhrError(e) {\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if (this._contentLength && this._receivedLength > 0\n && this._receivedLength < this._contentLength) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: 'RangeLoader meet Early-Eof'};\n } else {\n type = LoaderErrors.EXCEPTION;\n info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n}\n\nexport default RangeLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport PlayerEvents from './player-events.js';\nimport Transmuxer from '../core/transmuxer.js';\nimport TransmuxingEvents from '../core/transmuxing-events.js';\nimport MSEController from '../core/mse-controller.js';\nimport MSEEvents from '../core/mse-events.js';\nimport {ErrorTypes, ErrorDetails} from './player-errors.js';\nimport {createDefaultConfig} from '../config.js';\nimport {InvalidArgumentException, IllegalStateException} from '../utils/exception.js';\n\nclass FlvPlayer {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'FlvPlayer';\n this._type = 'FlvPlayer';\n this._emitter = new EventEmitter();\n\n this._config = createDefaultConfig();\n if (typeof config === 'object') {\n Object.assign(this._config, config);\n }\n\n if (mediaDataSource.type.toLowerCase() !== 'flv') {\n throw new InvalidArgumentException('FlvPlayer requires an flv MediaDataSource input!');\n }\n\n if (mediaDataSource.isLive === true) {\n this._config.isLive = true;\n }\n\n this.e = {\n onvLoadedMetadata: this._onvLoadedMetadata.bind(this),\n onvSeeking: this._onvSeeking.bind(this),\n onvCanPlay: this._onvCanPlay.bind(this),\n onvStalled: this._onvStalled.bind(this),\n onvProgress: this._onvProgress.bind(this)\n };\n\n if (self.performance && self.performance.now) {\n this._now = self.performance.now.bind(self.performance);\n } else {\n this._now = Date.now;\n }\n\n this._pendingSeekTime = null; // in seconds\n this._requestSetTime = false;\n this._seekpointRecord = null;\n this._progressChecker = null;\n\n this._mediaDataSource = mediaDataSource;\n this._mediaElement = null;\n this._msectl = null;\n this._transmuxer = null;\n\n this._mseSourceOpened = false;\n this._hasPendingLoad = false;\n this._receivedCanPlay = false;\n\n this._mediaInfo = null;\n this._statisticsInfo = null;\n\n let chromeNeedIDRFix = (Browser.chrome &&\n (Browser.version.major < 50 ||\n (Browser.version.major === 50 && Browser.version.build < 2661)));\n this._alwaysSeekKeyframe = (chromeNeedIDRFix || Browser.msedge || Browser.msie) ? true : false;\n\n if (this._alwaysSeekKeyframe) {\n this._config.accurateSeek = false;\n }\n }\n\n destroy() {\n if (this._progressChecker != null) {\n window.clearInterval(this._progressChecker);\n this._progressChecker = null;\n }\n if (this._transmuxer) {\n this.unload();\n }\n if (this._mediaElement) {\n this.detachMediaElement();\n }\n this.e = null;\n this._mediaDataSource = null;\n\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n if (event === PlayerEvents.MEDIA_INFO) {\n if (this._mediaInfo != null) {\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.MEDIA_INFO, this.mediaInfo);\n });\n }\n } else if (event === PlayerEvents.STATISTICS_INFO) {\n if (this._statisticsInfo != null) {\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, this.statisticsInfo);\n });\n }\n }\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n attachMediaElement(mediaElement) {\n this._mediaElement = mediaElement;\n mediaElement.addEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n mediaElement.addEventListener('seeking', this.e.onvSeeking);\n mediaElement.addEventListener('canplay', this.e.onvCanPlay);\n mediaElement.addEventListener('stalled', this.e.onvStalled);\n mediaElement.addEventListener('progress', this.e.onvProgress);\n\n this._msectl = new MSEController(this._config);\n\n this._msectl.on(MSEEvents.UPDATE_END, this._onmseUpdateEnd.bind(this));\n this._msectl.on(MSEEvents.BUFFER_FULL, this._onmseBufferFull.bind(this));\n this._msectl.on(MSEEvents.SOURCE_OPEN, () => {\n this._mseSourceOpened = true;\n if (this._hasPendingLoad) {\n this._hasPendingLoad = false;\n this.load();\n }\n });\n this._msectl.on(MSEEvents.ERROR, (info) => {\n this._emitter.emit(PlayerEvents.ERROR,\n ErrorTypes.MEDIA_ERROR,\n ErrorDetails.MEDIA_MSE_ERROR,\n info\n );\n });\n\n this._msectl.attachMediaElement(mediaElement);\n\n if (this._pendingSeekTime != null) {\n try {\n mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n } catch (e) {\n // IE11 may throw InvalidStateError if readyState === 0\n // We can defer set currentTime operation after loadedmetadata\n }\n }\n }\n\n detachMediaElement() {\n if (this._mediaElement) {\n this._msectl.detachMediaElement();\n this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n this._mediaElement.removeEventListener('seeking', this.e.onvSeeking);\n this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);\n this._mediaElement.removeEventListener('stalled', this.e.onvStalled);\n this._mediaElement.removeEventListener('progress', this.e.onvProgress);\n this._mediaElement = null;\n }\n if (this._msectl) {\n this._msectl.destroy();\n this._msectl = null;\n }\n }\n\n load() {\n if (!this._mediaElement) {\n throw new IllegalStateException('HTMLMediaElement must be attached before load()!');\n }\n if (this._transmuxer) {\n throw new IllegalStateException('FlvPlayer.load() has been called, please call unload() first!');\n }\n if (this._hasPendingLoad) {\n return;\n }\n\n if (this._config.deferLoadAfterSourceOpen && this._mseSourceOpened === false) {\n this._hasPendingLoad = true;\n return;\n }\n\n if (this._mediaElement.readyState > 0) {\n this._requestSetTime = true;\n // IE11 may throw InvalidStateError if readyState === 0\n this._mediaElement.currentTime = 0;\n }\n\n this._transmuxer = new Transmuxer(this._mediaDataSource, this._config);\n\n this._transmuxer.on(TransmuxingEvents.INIT_SEGMENT, (type, is) => {\n this._msectl.appendInitSegment(is);\n });\n this._transmuxer.on(TransmuxingEvents.MEDIA_SEGMENT, (type, ms) => {\n this._msectl.appendMediaSegment(ms);\n\n // lazyLoad check\n if (this._config.lazyLoad && !this._config.isLive) {\n let currentTime = this._mediaElement.currentTime;\n if (ms.info.endDts >= (currentTime + this._config.lazyLoadMaxDuration) * 1000) {\n if (this._progressChecker == null) {\n Log.v(this.TAG, 'Maximum buffering duration exceeded, suspend transmuxing task');\n this._suspendTransmuxer();\n }\n }\n }\n });\n this._transmuxer.on(TransmuxingEvents.LOADING_COMPLETE, () => {\n this._msectl.endOfStream();\n this._emitter.emit(PlayerEvents.LOADING_COMPLETE);\n });\n this._transmuxer.on(TransmuxingEvents.RECOVERED_EARLY_EOF, () => {\n this._emitter.emit(PlayerEvents.RECOVERED_EARLY_EOF);\n });\n this._transmuxer.on(TransmuxingEvents.IO_ERROR, (detail, info) => {\n this._emitter.emit(PlayerEvents.ERROR, ErrorTypes.NETWORK_ERROR, detail, info);\n });\n this._transmuxer.on(TransmuxingEvents.DEMUX_ERROR, (detail, info) => {\n this._emitter.emit(PlayerEvents.ERROR, ErrorTypes.MEDIA_ERROR, detail, {code: -1, msg: info});\n });\n this._transmuxer.on(TransmuxingEvents.MEDIA_INFO, (mediaInfo) => {\n this._mediaInfo = mediaInfo;\n this._emitter.emit(PlayerEvents.MEDIA_INFO, Object.assign({}, mediaInfo));\n });\n this._transmuxer.on(TransmuxingEvents.STATISTICS_INFO, (statInfo) => {\n this._statisticsInfo = this._fillStatisticsInfo(statInfo);\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, Object.assign({}, this._statisticsInfo));\n });\n this._transmuxer.on(TransmuxingEvents.RECOMMEND_SEEKPOINT, (milliseconds) => {\n if (this._mediaElement && !this._config.accurateSeek) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = milliseconds / 1000;\n }\n });\n\n this._transmuxer.open();\n }\n\n unload() {\n if (this._mediaElement) {\n this._mediaElement.pause();\n }\n if (this._msectl) {\n this._msectl.seek(0);\n }\n if (this._transmuxer) {\n this._transmuxer.close();\n this._transmuxer.destroy();\n this._transmuxer = null;\n }\n }\n\n play() {\n return this._mediaElement.play();\n }\n\n pause() {\n this._mediaElement.pause();\n }\n\n get type() {\n return this._type;\n }\n\n get buffered() {\n return this._mediaElement.buffered;\n }\n\n get duration() {\n return this._mediaElement.duration;\n }\n\n get volume() {\n return this._mediaElement.volume;\n }\n\n set volume(value) {\n this._mediaElement.volume = value;\n }\n\n get muted() {\n return this._mediaElement.muted;\n }\n\n set muted(muted) {\n this._mediaElement.muted = muted;\n }\n\n get currentTime() {\n if (this._mediaElement) {\n return this._mediaElement.currentTime;\n }\n return 0;\n }\n\n set currentTime(seconds) {\n if (this._mediaElement) {\n this._internalSeek(seconds);\n } else {\n this._pendingSeekTime = seconds;\n }\n }\n\n get mediaInfo() {\n return Object.assign({}, this._mediaInfo);\n }\n\n get statisticsInfo() {\n if (this._statisticsInfo == null) {\n this._statisticsInfo = {};\n }\n this._statisticsInfo = this._fillStatisticsInfo(this._statisticsInfo);\n return Object.assign({}, this._statisticsInfo);\n }\n\n _fillStatisticsInfo(statInfo) {\n statInfo.playerType = this._type;\n\n if (!(this._mediaElement instanceof HTMLVideoElement)) {\n return statInfo;\n }\n\n let hasQualityInfo = true;\n let decoded = 0;\n let dropped = 0;\n\n if (this._mediaElement.getVideoPlaybackQuality) {\n let quality = this._mediaElement.getVideoPlaybackQuality();\n decoded = quality.totalVideoFrames;\n dropped = quality.droppedVideoFrames;\n } else if (this._mediaElement.webkitDecodedFrameCount != undefined) {\n decoded = this._mediaElement.webkitDecodedFrameCount;\n dropped = this._mediaElement.webkitDroppedFrameCount;\n } else {\n hasQualityInfo = false;\n }\n\n if (hasQualityInfo) {\n statInfo.decodedFrames = decoded;\n statInfo.droppedFrames = dropped;\n }\n\n return statInfo;\n }\n\n _onmseUpdateEnd() {\n if (!this._config.lazyLoad || this._config.isLive) {\n return;\n }\n\n let buffered = this._mediaElement.buffered;\n let currentTime = this._mediaElement.currentTime;\n let currentRangeStart = 0;\n let currentRangeEnd = 0;\n\n for (let i = 0; i < buffered.length; i++) {\n let start = buffered.start(i);\n let end = buffered.end(i);\n if (start <= currentTime && currentTime < end) {\n currentRangeStart = start;\n currentRangeEnd = end;\n break;\n }\n }\n\n if (currentRangeEnd >= currentTime + this._config.lazyLoadMaxDuration && this._progressChecker == null) {\n Log.v(this.TAG, 'Maximum buffering duration exceeded, suspend transmuxing task');\n this._suspendTransmuxer();\n }\n }\n\n _onmseBufferFull() {\n Log.v(this.TAG, 'MSE SourceBuffer is full, suspend transmuxing task');\n if (this._progressChecker == null) {\n this._suspendTransmuxer();\n }\n }\n\n _suspendTransmuxer() {\n if (this._transmuxer) {\n this._transmuxer.pause();\n\n if (this._progressChecker == null) {\n this._progressChecker = window.setInterval(this._checkProgressAndResume.bind(this), 1000);\n }\n }\n }\n\n _checkProgressAndResume() {\n let currentTime = this._mediaElement.currentTime;\n let buffered = this._mediaElement.buffered;\n\n let needResume = false;\n\n for (let i = 0; i < buffered.length; i++) {\n let from = buffered.start(i);\n let to = buffered.end(i);\n if (currentTime >= from && currentTime < to) {\n if (currentTime >= to - this._config.lazyLoadRecoverDuration) {\n needResume = true;\n }\n break;\n }\n }\n\n if (needResume) {\n window.clearInterval(this._progressChecker);\n this._progressChecker = null;\n if (needResume) {\n Log.v(this.TAG, 'Continue loading from paused position');\n this._transmuxer.resume();\n }\n }\n }\n\n _isTimepointBuffered(seconds) {\n let buffered = this._mediaElement.buffered;\n\n for (let i = 0; i < buffered.length; i++) {\n let from = buffered.start(i);\n let to = buffered.end(i);\n if (seconds >= from && seconds < to) {\n return true;\n }\n }\n return false;\n }\n\n _internalSeek(seconds) {\n let directSeek = this._isTimepointBuffered(seconds);\n\n let directSeekBegin = false;\n let directSeekBeginTime = 0;\n\n if (seconds < 1.0 && this._mediaElement.buffered.length > 0) {\n let videoBeginTime = this._mediaElement.buffered.start(0);\n if ((videoBeginTime < 1.0 && seconds < videoBeginTime) || Browser.safari) {\n directSeekBegin = true;\n // also workaround for Safari: Seek to 0 may cause video stuck, use 0.1 to avoid\n directSeekBeginTime = Browser.safari ? 0.1 : videoBeginTime;\n }\n }\n\n if (directSeekBegin) { // seek to video begin, set currentTime directly if beginPTS buffered\n this._requestSetTime = true;\n this._mediaElement.currentTime = directSeekBeginTime;\n } else if (directSeek) { // buffered position\n if (!this._alwaysSeekKeyframe) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = seconds;\n } else {\n let idr = this._msectl.getNearestKeyframe(Math.floor(seconds * 1000));\n this._requestSetTime = true;\n if (idr != null) {\n this._mediaElement.currentTime = idr.dts / 1000;\n } else {\n this._mediaElement.currentTime = seconds;\n }\n }\n if (this._progressChecker != null) {\n this._checkProgressAndResume();\n }\n } else {\n if (this._progressChecker != null) {\n window.clearInterval(this._progressChecker);\n this._progressChecker = null;\n }\n this._msectl.seek(seconds);\n this._transmuxer.seek(Math.floor(seconds * 1000)); // in milliseconds\n // no need to set mediaElement.currentTime if non-accurateSeek,\n // just wait for the recommend_seekpoint callback\n if (this._config.accurateSeek) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = seconds;\n }\n }\n }\n\n _checkAndApplyUnbufferedSeekpoint() {\n if (this._seekpointRecord) {\n if (this._seekpointRecord.recordTime <= this._now() - 100) {\n let target = this._mediaElement.currentTime;\n this._seekpointRecord = null;\n if (!this._isTimepointBuffered(target)) {\n if (this._progressChecker != null) {\n window.clearTimeout(this._progressChecker);\n this._progressChecker = null;\n }\n // .currentTime is consists with .buffered timestamp\n // Chrome/Edge use DTS, while FireFox/Safari use PTS\n this._msectl.seek(target);\n this._transmuxer.seek(Math.floor(target * 1000));\n // set currentTime if accurateSeek, or wait for recommend_seekpoint callback\n if (this._config.accurateSeek) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = target;\n }\n }\n } else {\n window.setTimeout(this._checkAndApplyUnbufferedSeekpoint.bind(this), 50);\n }\n }\n }\n\n _checkAndResumeStuckPlayback(stalled) {\n let media = this._mediaElement;\n if (stalled || !this._receivedCanPlay || media.readyState < 2) { // HAVE_CURRENT_DATA\n let buffered = media.buffered;\n if (buffered.length > 0 && media.currentTime < buffered.start(0)) {\n Log.w(this.TAG, `Playback seems stuck at ${media.currentTime}, seek to ${buffered.start(0)}`);\n this._requestSetTime = true;\n this._mediaElement.currentTime = buffered.start(0);\n this._mediaElement.removeEventListener('progress', this.e.onvProgress);\n }\n } else {\n // Playback didn't stuck, remove progress event listener\n this._mediaElement.removeEventListener('progress', this.e.onvProgress);\n }\n }\n\n _onvLoadedMetadata(e) {\n if (this._pendingSeekTime != null) {\n this._mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n }\n }\n\n _onvSeeking(e) { // handle seeking request from browser's progress bar\n let target = this._mediaElement.currentTime;\n let buffered = this._mediaElement.buffered;\n\n if (this._requestSetTime) {\n this._requestSetTime = false;\n return;\n }\n\n if (target < 1.0 && buffered.length > 0) {\n // seek to video begin, set currentTime directly if beginPTS buffered\n let videoBeginTime = buffered.start(0);\n if ((videoBeginTime < 1.0 && target < videoBeginTime) || Browser.safari) {\n this._requestSetTime = true;\n // also workaround for Safari: Seek to 0 may cause video stuck, use 0.1 to avoid\n this._mediaElement.currentTime = Browser.safari ? 0.1 : videoBeginTime;\n return;\n }\n }\n\n if (this._isTimepointBuffered(target)) {\n if (this._alwaysSeekKeyframe) {\n let idr = this._msectl.getNearestKeyframe(Math.floor(target * 1000));\n if (idr != null) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = idr.dts / 1000;\n }\n }\n if (this._progressChecker != null) {\n this._checkProgressAndResume();\n }\n return;\n }\n\n this._seekpointRecord = {\n seekPoint: target,\n recordTime: this._now()\n };\n window.setTimeout(this._checkAndApplyUnbufferedSeekpoint.bind(this), 50);\n }\n\n _onvCanPlay(e) {\n this._receivedCanPlay = true;\n this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);\n }\n\n _onvStalled(e) {\n this._checkAndResumeStuckPlayback(true);\n }\n\n _onvProgress(e) {\n this._checkAndResumeStuckPlayback();\n }\n\n}\n\nexport default FlvPlayer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport PlayerEvents from './player-events.js';\nimport {createDefaultConfig} from '../config.js';\nimport {InvalidArgumentException, IllegalStateException} from '../utils/exception.js';\n\n// Player wrapper for browser's native player (HTMLVideoElement) without MediaSource src. \nclass NativePlayer {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'NativePlayer';\n this._type = 'NativePlayer';\n this._emitter = new EventEmitter();\n\n this._config = createDefaultConfig();\n if (typeof config === 'object') {\n Object.assign(this._config, config);\n }\n\n if (mediaDataSource.type.toLowerCase() === 'flv') {\n throw new InvalidArgumentException('NativePlayer does\\'t support flv MediaDataSource input!');\n }\n if (mediaDataSource.hasOwnProperty('segments')) {\n throw new InvalidArgumentException(`NativePlayer(${mediaDataSource.type}) doesn't support multipart playback!`);\n }\n\n this.e = {\n onvLoadedMetadata: this._onvLoadedMetadata.bind(this)\n };\n\n this._pendingSeekTime = null;\n this._statisticsReporter = null;\n\n this._mediaDataSource = mediaDataSource;\n this._mediaElement = null;\n }\n\n destroy() {\n if (this._mediaElement) {\n this.unload();\n this.detachMediaElement();\n }\n this.e = null;\n this._mediaDataSource = null;\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n if (event === PlayerEvents.MEDIA_INFO) {\n if (this._mediaElement != null && this._mediaElement.readyState !== 0) { // HAVE_NOTHING\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.MEDIA_INFO, this.mediaInfo);\n });\n }\n } else if (event === PlayerEvents.STATISTICS_INFO) {\n if (this._mediaElement != null && this._mediaElement.readyState !== 0) {\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, this.statisticsInfo);\n });\n }\n }\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n attachMediaElement(mediaElement) {\n this._mediaElement = mediaElement;\n mediaElement.addEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n\n if (this._pendingSeekTime != null) {\n try {\n mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n } catch (e) {\n // IE11 may throw InvalidStateError if readyState === 0\n // Defer set currentTime operation after loadedmetadata\n }\n }\n }\n\n detachMediaElement() {\n if (this._mediaElement) {\n this._mediaElement.src = '';\n this._mediaElement.removeAttribute('src');\n this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n this._mediaElement = null;\n }\n if (this._statisticsReporter != null) {\n window.clearInterval(this._statisticsReporter);\n this._statisticsReporter = null;\n }\n }\n\n load() {\n if (!this._mediaElement) {\n throw new IllegalStateException('HTMLMediaElement must be attached before load()!');\n }\n this._mediaElement.src = this._mediaDataSource.url;\n\n if (this._mediaElement.readyState > 0) {\n this._mediaElement.currentTime = 0;\n }\n\n this._mediaElement.preload = 'auto';\n this._mediaElement.load();\n this._statisticsReporter = window.setInterval(\n this._reportStatisticsInfo.bind(this),\n this._config.statisticsInfoReportInterval);\n }\n\n unload() {\n if (this._mediaElement) {\n this._mediaElement.src = '';\n this._mediaElement.removeAttribute('src');\n }\n if (this._statisticsReporter != null) {\n window.clearInterval(this._statisticsReporter);\n this._statisticsReporter = null;\n }\n }\n\n play() {\n return this._mediaElement.play();\n }\n\n pause() {\n this._mediaElement.pause();\n }\n\n get type() {\n return this._type;\n }\n\n get buffered() {\n return this._mediaElement.buffered;\n }\n\n get duration() {\n return this._mediaElement.duration;\n }\n\n get volume() {\n return this._mediaElement.volume;\n }\n\n set volume(value) {\n this._mediaElement.volume = value;\n }\n\n get muted() {\n return this._mediaElement.muted;\n }\n\n set muted(muted) {\n this._mediaElement.muted = muted;\n }\n\n get currentTime() {\n if (this._mediaElement) {\n return this._mediaElement.currentTime;\n }\n return 0;\n }\n\n set currentTime(seconds) {\n if (this._mediaElement) {\n this._mediaElement.currentTime = seconds;\n } else {\n this._pendingSeekTime = seconds;\n }\n }\n\n get mediaInfo() {\n let mediaPrefix = (this._mediaElement instanceof HTMLAudioElement) ? 'audio/' : 'video/';\n let info = {\n mimeType: mediaPrefix + this._mediaDataSource.type\n };\n if (this._mediaElement) {\n info.duration = Math.floor(this._mediaElement.duration * 1000);\n if (this._mediaElement instanceof HTMLVideoElement) {\n info.width = this._mediaElement.videoWidth;\n info.height = this._mediaElement.videoHeight;\n }\n }\n return info;\n }\n\n get statisticsInfo() {\n let info = {\n playerType: this._type,\n url: this._mediaDataSource.url\n };\n\n if (!(this._mediaElement instanceof HTMLVideoElement)) {\n return info;\n }\n\n let hasQualityInfo = true;\n let decoded = 0;\n let dropped = 0;\n\n if (this._mediaElement.getVideoPlaybackQuality) {\n let quality = this._mediaElement.getVideoPlaybackQuality();\n decoded = quality.totalVideoFrames;\n dropped = quality.droppedVideoFrames;\n } else if (this._mediaElement.webkitDecodedFrameCount != undefined) {\n decoded = this._mediaElement.webkitDecodedFrameCount;\n dropped = this._mediaElement.webkitDroppedFrameCount;\n } else {\n hasQualityInfo = false;\n }\n\n if (hasQualityInfo) {\n info.decodedFrames = decoded;\n info.droppedFrames = dropped;\n }\n \n return info;\n }\n\n _onvLoadedMetadata(e) {\n if (this._pendingSeekTime != null) {\n this._mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n }\n this._emitter.emit(PlayerEvents.MEDIA_INFO, this.mediaInfo);\n }\n\n _reportStatisticsInfo() {\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, this.statisticsInfo);\n }\n\n}\n\nexport default NativePlayer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {LoaderErrors} from '../io/loader.js';\nimport DemuxErrors from '../demux/demux-errors.js';\n\nexport const ErrorTypes = {\n NETWORK_ERROR: 'NetworkError',\n MEDIA_ERROR: 'MediaError',\n OTHER_ERROR: 'OtherError'\n};\n\nexport const ErrorDetails = {\n NETWORK_EXCEPTION: LoaderErrors.EXCEPTION,\n NETWORK_STATUS_CODE_INVALID: LoaderErrors.HTTP_STATUS_CODE_INVALID,\n NETWORK_TIMEOUT: LoaderErrors.CONNECTING_TIMEOUT,\n NETWORK_UNRECOVERABLE_EARLY_EOF: LoaderErrors.UNRECOVERABLE_EARLY_EOF,\n\n MEDIA_MSE_ERROR: 'MediaMSEError',\n\n MEDIA_FORMAT_ERROR: DemuxErrors.FORMAT_ERROR,\n MEDIA_FORMAT_UNSUPPORTED: DemuxErrors.FORMAT_UNSUPPORTED,\n MEDIA_CODEC_UNSUPPORTED: DemuxErrors.CODEC_UNSUPPORTED\n};","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst PlayerEvents = {\n ERROR: 'error',\n LOADING_COMPLETE: 'loading_complete',\n RECOVERED_EARLY_EOF: 'recovered_early_eof',\n MEDIA_INFO: 'media_info',\n STATISTICS_INFO: 'statistics_info'\n};\n\nexport default PlayerEvents;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * This file is modified from dailymotion's hls.js library (hls.js/src/helper/aac.js)\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass AAC {\n\n static getSilentFrame(codec, channelCount) {\n if (codec === 'mp4a.40.2') {\n // handle LC-AAC\n if (channelCount === 1) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);\n } else if (channelCount === 2) {\n return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]);\n } else if (channelCount === 3) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]);\n } else if (channelCount === 4) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]);\n } else if (channelCount === 5) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]);\n } else if (channelCount === 6) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]);\n }\n } else {\n // handle HE-AAC (mp4a.40.5 / mp4a.40.29)\n if (channelCount === 1) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0:d=0.05\" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);\n } else if (channelCount === 2) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0|0:d=0.05\" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);\n } else if (channelCount === 3) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0|0|0:d=0.05\" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);\n }\n }\n return null;\n }\n\n}\n\nexport default AAC;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * This file is derived from dailymotion's hls.js library (hls.js/src/remux/mp4-generator.js)\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// MP4 boxes generator for ISO BMFF (ISO Base Media File Format, defined in ISO/IEC 14496-12)\nclass MP4 {\n\n static init() {\n MP4.types = {\n avc1: [], avcC: [], btrt: [], dinf: [],\n dref: [], esds: [], ftyp: [], hdlr: [],\n mdat: [], mdhd: [], mdia: [], mfhd: [],\n minf: [], moof: [], moov: [], mp4a: [],\n mvex: [], mvhd: [], sdtp: [], stbl: [],\n stco: [], stsc: [], stsd: [], stsz: [],\n stts: [], tfdt: [], tfhd: [], traf: [],\n trak: [], trun: [], trex: [], tkhd: [],\n vmhd: [], smhd: [], '.mp3': []\n };\n\n for (let name in MP4.types) {\n if (MP4.types.hasOwnProperty(name)) {\n MP4.types[name] = [\n name.charCodeAt(0),\n name.charCodeAt(1),\n name.charCodeAt(2),\n name.charCodeAt(3)\n ];\n }\n }\n\n let constants = MP4.constants = {};\n\n constants.FTYP = new Uint8Array([\n 0x69, 0x73, 0x6F, 0x6D, // major_brand: isom\n 0x0, 0x0, 0x0, 0x1, // minor_version: 0x01\n 0x69, 0x73, 0x6F, 0x6D, // isom\n 0x61, 0x76, 0x63, 0x31 // avc1\n ]);\n\n constants.STSD_PREFIX = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x01 // entry_count\n ]);\n\n constants.STTS = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00 // entry_count\n ]);\n\n constants.STSC = constants.STCO = constants.STTS;\n\n constants.STSZ = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // sample_size\n 0x00, 0x00, 0x00, 0x00 // sample_count\n ]);\n\n constants.HDLR_VIDEO = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // pre_defined\n 0x76, 0x69, 0x64, 0x65, // handler_type: 'vide'\n 0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x56, 0x69, 0x64, 0x65,\n 0x6F, 0x48, 0x61, 0x6E,\n 0x64, 0x6C, 0x65, 0x72, 0x00 // name: VideoHandler\n ]);\n\n constants.HDLR_AUDIO = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // pre_defined\n 0x73, 0x6F, 0x75, 0x6E, // handler_type: 'soun'\n 0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x53, 0x6F, 0x75, 0x6E,\n 0x64, 0x48, 0x61, 0x6E,\n 0x64, 0x6C, 0x65, 0x72, 0x00 // name: SoundHandler\n ]);\n\n constants.DREF = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x01, // entry_count\n 0x00, 0x00, 0x00, 0x0C, // entry_size\n 0x75, 0x72, 0x6C, 0x20, // type 'url '\n 0x00, 0x00, 0x00, 0x01 // version(0) + flags\n ]);\n\n // Sound media header\n constants.SMHD = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00 // balance(2) + reserved(2)\n ]);\n\n // video media header\n constants.VMHD = new Uint8Array([\n 0x00, 0x00, 0x00, 0x01, // version(0) + flags\n 0x00, 0x00, // graphicsmode: 2 bytes\n 0x00, 0x00, 0x00, 0x00, // opcolor: 3 * 2 bytes\n 0x00, 0x00\n ]);\n }\n\n // Generate a box\n static box(type) {\n let size = 8;\n let result = null;\n let datas = Array.prototype.slice.call(arguments, 1);\n let arrayCount = datas.length;\n\n for (let i = 0; i < arrayCount; i++) {\n size += datas[i].byteLength;\n }\n\n result = new Uint8Array(size);\n result[0] = (size >>> 24) & 0xFF; // size\n result[1] = (size >>> 16) & 0xFF;\n result[2] = (size >>> 8) & 0xFF;\n result[3] = (size) & 0xFF;\n\n result.set(type, 4); // type\n\n let offset = 8;\n for (let i = 0; i < arrayCount; i++) { // data body\n result.set(datas[i], offset);\n offset += datas[i].byteLength;\n }\n\n return result;\n }\n\n // emit ftyp & moov\n static generateInitSegment(meta) {\n let ftyp = MP4.box(MP4.types.ftyp, MP4.constants.FTYP);\n let moov = MP4.moov(meta);\n\n let result = new Uint8Array(ftyp.byteLength + moov.byteLength);\n result.set(ftyp, 0);\n result.set(moov, ftyp.byteLength);\n return result;\n }\n\n // Movie metadata box\n static moov(meta) {\n let mvhd = MP4.mvhd(meta.timescale, meta.duration);\n let trak = MP4.trak(meta);\n let mvex = MP4.mvex(meta);\n return MP4.box(MP4.types.moov, mvhd, trak, mvex);\n }\n\n // Movie header box\n static mvhd(timescale, duration) {\n return MP4.box(MP4.types.mvhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // creation_time\n 0x00, 0x00, 0x00, 0x00, // modification_time\n (timescale >>> 24) & 0xFF, // timescale: 4 bytes\n (timescale >>> 16) & 0xFF,\n (timescale >>> 8) & 0xFF,\n (timescale) & 0xFF,\n (duration >>> 24) & 0xFF, // duration: 4 bytes\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n 0x00, 0x01, 0x00, 0x00, // Preferred rate: 1.0\n 0x01, 0x00, 0x00, 0x00, // PreferredVolume(1.0, 2bytes) + reserved(2bytes)\n 0x00, 0x00, 0x00, 0x00, // reserved: 4 + 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x01, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x40, 0x00, 0x00, 0x00, // ----end composition matrix----\n 0x00, 0x00, 0x00, 0x00, // ----begin pre_defined 6 * 4 bytes----\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, // ----end pre_defined 6 * 4 bytes----\n 0xFF, 0xFF, 0xFF, 0xFF // next_track_ID\n ]));\n }\n\n // Track box\n static trak(meta) {\n return MP4.box(MP4.types.trak, MP4.tkhd(meta), MP4.mdia(meta));\n }\n\n // Track header box\n static tkhd(meta) {\n let trackId = meta.id, duration = meta.duration;\n let width = meta.presentWidth, height = meta.presentHeight;\n\n return MP4.box(MP4.types.tkhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x07, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // creation_time\n 0x00, 0x00, 0x00, 0x00, // modification_time\n (trackId >>> 24) & 0xFF, // track_ID: 4 bytes\n (trackId >>> 16) & 0xFF,\n (trackId >>> 8) & 0xFF,\n (trackId) & 0xFF,\n 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes\n (duration >>> 24) & 0xFF, // duration: 4 bytes\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, // layer(2bytes) + alternate_group(2bytes)\n 0x00, 0x00, 0x00, 0x00, // volume(2bytes) + reserved(2bytes)\n 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x01, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x40, 0x00, 0x00, 0x00, // ----end composition matrix----\n (width >>> 8) & 0xFF, // width and height\n (width) & 0xFF,\n 0x00, 0x00,\n (height >>> 8) & 0xFF,\n (height) & 0xFF,\n 0x00, 0x00\n ]));\n }\n\n // Media Box\n static mdia(meta) {\n return MP4.box(MP4.types.mdia, MP4.mdhd(meta), MP4.hdlr(meta), MP4.minf(meta));\n }\n\n // Media header box\n static mdhd(meta) {\n let timescale = meta.timescale;\n let duration = meta.duration;\n return MP4.box(MP4.types.mdhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // creation_time\n 0x00, 0x00, 0x00, 0x00, // modification_time\n (timescale >>> 24) & 0xFF, // timescale: 4 bytes\n (timescale >>> 16) & 0xFF,\n (timescale >>> 8) & 0xFF,\n (timescale) & 0xFF,\n (duration >>> 24) & 0xFF, // duration: 4 bytes\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n 0x55, 0xC4, // language: und (undetermined)\n 0x00, 0x00 // pre_defined = 0\n ]));\n }\n\n // Media handler reference box\n static hdlr(meta) {\n let data = null;\n if (meta.type === 'audio') {\n data = MP4.constants.HDLR_AUDIO;\n } else {\n data = MP4.constants.HDLR_VIDEO;\n }\n return MP4.box(MP4.types.hdlr, data);\n }\n\n // Media infomation box\n static minf(meta) {\n let xmhd = null;\n if (meta.type === 'audio') {\n xmhd = MP4.box(MP4.types.smhd, MP4.constants.SMHD);\n } else {\n xmhd = MP4.box(MP4.types.vmhd, MP4.constants.VMHD);\n }\n return MP4.box(MP4.types.minf, xmhd, MP4.dinf(), MP4.stbl(meta));\n }\n\n // Data infomation box\n static dinf() {\n let result = MP4.box(MP4.types.dinf,\n MP4.box(MP4.types.dref, MP4.constants.DREF)\n );\n return result;\n }\n\n // Sample table box\n static stbl(meta) {\n let result = MP4.box(MP4.types.stbl, // type: stbl\n MP4.stsd(meta), // Sample Description Table\n MP4.box(MP4.types.stts, MP4.constants.STTS), // Time-To-Sample\n MP4.box(MP4.types.stsc, MP4.constants.STSC), // Sample-To-Chunk\n MP4.box(MP4.types.stsz, MP4.constants.STSZ), // Sample size\n MP4.box(MP4.types.stco, MP4.constants.STCO) // Chunk offset\n ); \n return result; \n }\n\n // Sample description box\n static stsd(meta) {\n if (meta.type === 'audio') {\n if (meta.codec === 'mp3') {\n return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp3(meta));\n }\n // else: aac -> mp4a\n return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp4a(meta));\n } else {\n return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.avc1(meta));\n }\n }\n\n static mp3(meta) {\n let channelCount = meta.channelCount;\n let sampleRate = meta.audioSampleRate;\n\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)\n 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, channelCount, // channelCount(2)\n 0x00, 0x10, // sampleSize(2)\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n (sampleRate >>> 8) & 0xFF, // Audio sample rate\n (sampleRate) & 0xFF,\n 0x00, 0x00\n ]);\n\n return MP4.box(MP4.types['.mp3'], data);\n }\n\n static mp4a(meta) {\n let channelCount = meta.channelCount;\n let sampleRate = meta.audioSampleRate;\n\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)\n 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, channelCount, // channelCount(2)\n 0x00, 0x10, // sampleSize(2)\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n (sampleRate >>> 8) & 0xFF, // Audio sample rate\n (sampleRate) & 0xFF,\n 0x00, 0x00\n ]);\n\n return MP4.box(MP4.types.mp4a, data, MP4.esds(meta));\n }\n\n static esds(meta) {\n let config = meta.config || [];\n let configSize = config.length;\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version 0 + flags\n\n 0x03, // descriptor_type\n 0x17 + configSize, // length3\n 0x00, 0x01, // es_id\n 0x00, // stream_priority\n\n 0x04, // descriptor_type\n 0x0F + configSize, // length\n 0x40, // codec: mpeg4_audio\n 0x15, // stream_type: Audio\n 0x00, 0x00, 0x00, // buffer_size\n 0x00, 0x00, 0x00, 0x00, // maxBitrate\n 0x00, 0x00, 0x00, 0x00, // avgBitrate\n\n 0x05 // descriptor_type\n ].concat([\n configSize\n ]).concat(\n config\n ).concat([\n 0x06, 0x01, 0x02 // GASpecificConfig\n ]));\n return MP4.box(MP4.types.esds, data);\n }\n\n static avc1(meta) {\n let avcc = meta.avcc;\n let width = meta.codecWidth, height = meta.codecHeight;\n\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)\n 0x00, 0x00, 0x00, 0x00, // pre_defined(2) + reserved(2)\n 0x00, 0x00, 0x00, 0x00, // pre_defined: 3 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n (width >>> 8) & 0xFF, // width: 2 bytes\n (width) & 0xFF,\n (height >>> 8) & 0xFF, // height: 2 bytes\n (height) & 0xFF,\n 0x00, 0x48, 0x00, 0x00, // horizresolution: 4 bytes\n 0x00, 0x48, 0x00, 0x00, // vertresolution: 4 bytes\n 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes\n 0x00, 0x01, // frame_count\n 0x0A, // strlen\n 0x78, 0x71, 0x71, 0x2F, // compressorname: 32 bytes\n 0x66, 0x6C, 0x76, 0x2E,\n 0x6A, 0x73, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00,\n 0x00, 0x18, // depth\n 0xFF, 0xFF // pre_defined = -1\n ]);\n return MP4.box(MP4.types.avc1, data, MP4.box(MP4.types.avcC, avcc));\n }\n\n // Movie Extends box\n static mvex(meta) {\n return MP4.box(MP4.types.mvex, MP4.trex(meta));\n }\n\n // Track Extends box\n static trex(meta) {\n let trackId = meta.id;\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n (trackId >>> 24) & 0xFF, // track_ID\n (trackId >>> 16) & 0xFF,\n (trackId >>> 8) & 0xFF,\n (trackId) & 0xFF,\n 0x00, 0x00, 0x00, 0x01, // default_sample_description_index\n 0x00, 0x00, 0x00, 0x00, // default_sample_duration\n 0x00, 0x00, 0x00, 0x00, // default_sample_size\n 0x00, 0x01, 0x00, 0x01 // default_sample_flags\n ]);\n return MP4.box(MP4.types.trex, data);\n }\n\n // Movie fragment box\n static moof(track, baseMediaDecodeTime) {\n return MP4.box(MP4.types.moof, MP4.mfhd(track.sequenceNumber), MP4.traf(track, baseMediaDecodeTime));\n }\n\n static mfhd(sequenceNumber) {\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00,\n (sequenceNumber >>> 24) & 0xFF, // sequence_number: int32\n (sequenceNumber >>> 16) & 0xFF,\n (sequenceNumber >>> 8) & 0xFF,\n (sequenceNumber) & 0xFF\n ]);\n return MP4.box(MP4.types.mfhd, data);\n }\n\n // Track fragment box\n static traf(track, baseMediaDecodeTime) {\n let trackId = track.id;\n\n // Track fragment header box\n let tfhd = MP4.box(MP4.types.tfhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) & flags\n (trackId >>> 24) & 0xFF, // track_ID\n (trackId >>> 16) & 0xFF,\n (trackId >>> 8) & 0xFF,\n (trackId) & 0xFF\n ]));\n // Track Fragment Decode Time\n let tfdt = MP4.box(MP4.types.tfdt, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) & flags\n (baseMediaDecodeTime >>> 24) & 0xFF, // baseMediaDecodeTime: int32\n (baseMediaDecodeTime >>> 16) & 0xFF,\n (baseMediaDecodeTime >>> 8) & 0xFF,\n (baseMediaDecodeTime) & 0xFF\n ]));\n let sdtp = MP4.sdtp(track);\n let trun = MP4.trun(track, sdtp.byteLength + 16 + 16 + 8 + 16 + 8 + 8);\n\n return MP4.box(MP4.types.traf, tfhd, tfdt, trun, sdtp);\n }\n\n // Sample Dependency Type box\n static sdtp(track) {\n let samples = track.samples || [];\n let sampleCount = samples.length;\n let data = new Uint8Array(4 + sampleCount);\n // 0~4 bytes: version(0) & flags\n for (let i = 0; i < sampleCount; i++) {\n let flags = samples[i].flags;\n data[i + 4] = (flags.isLeading << 6) // is_leading: 2 (bit)\n | (flags.dependsOn << 4) // sample_depends_on\n | (flags.isDependedOn << 2) // sample_is_depended_on\n | (flags.hasRedundancy); // sample_has_redundancy\n }\n return MP4.box(MP4.types.sdtp, data);\n }\n\n // Track fragment run box\n static trun(track, offset) {\n let samples = track.samples || [];\n let sampleCount = samples.length;\n let dataSize = 12 + 16 * sampleCount;\n let data = new Uint8Array(dataSize);\n offset += 8 + dataSize;\n\n data.set([\n 0x00, 0x00, 0x0F, 0x01, // version(0) & flags\n (sampleCount >>> 24) & 0xFF, // sample_count\n (sampleCount >>> 16) & 0xFF,\n (sampleCount >>> 8) & 0xFF,\n (sampleCount) & 0xFF,\n (offset >>> 24) & 0xFF, // data_offset\n (offset >>> 16) & 0xFF,\n (offset >>> 8) & 0xFF,\n (offset) & 0xFF\n ], 0);\n\n for (let i = 0; i < sampleCount; i++) {\n let duration = samples[i].duration;\n let size = samples[i].size;\n let flags = samples[i].flags;\n let cts = samples[i].cts;\n data.set([\n (duration >>> 24) & 0xFF, // sample_duration\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n (size >>> 24) & 0xFF, // sample_size\n (size >>> 16) & 0xFF,\n (size >>> 8) & 0xFF,\n (size) & 0xFF,\n (flags.isLeading << 2) | flags.dependsOn, // sample_flags\n (flags.isDependedOn << 6) | (flags.hasRedundancy << 4) | flags.isNonSync,\n 0x00, 0x00, // sample_degradation_priority\n (cts >>> 24) & 0xFF, // sample_composition_time_offset\n (cts >>> 16) & 0xFF,\n (cts >>> 8) & 0xFF,\n (cts) & 0xFF\n ], 12 + 16 * i);\n }\n return MP4.box(MP4.types.trun, data);\n }\n\n static mdat(data) {\n return MP4.box(MP4.types.mdat, data);\n }\n\n}\n\nMP4.init();\n\nexport default MP4;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport MP4 from './mp4-generator.js';\nimport AAC from './aac-silent.js';\nimport Browser from '../utils/browser.js';\nimport {SampleInfo, MediaSegmentInfo, MediaSegmentInfoList} from '../core/media-segment-info.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\n\n// Fragmented mp4 remuxer\nclass MP4Remuxer {\n\n constructor(config) {\n this.TAG = 'MP4Remuxer';\n\n this._config = config;\n this._isLive = (config.isLive === true) ? true : false;\n\n this._dtsBase = -1;\n this._dtsBaseInited = false;\n this._audioDtsBase = Infinity;\n this._videoDtsBase = Infinity;\n this._audioNextDts = undefined;\n this._videoNextDts = undefined;\n\n this._audioMeta = null;\n this._videoMeta = null;\n\n this._audioSegmentInfoList = new MediaSegmentInfoList('audio');\n this._videoSegmentInfoList = new MediaSegmentInfoList('video');\n\n this._onInitSegment = null;\n this._onMediaSegment = null;\n\n // Workaround for chrome < 50: Always force first sample as a Random Access Point in media segment\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412\n this._forceFirstIDR = (Browser.chrome &&\n (Browser.version.major < 50 ||\n (Browser.version.major === 50 && Browser.version.build < 2661))) ? true : false;\n\n // Workaround for IE11/Edge: Fill silent aac frame after keyframe-seeking\n // Make audio beginDts equals with video beginDts, in order to fix seek freeze\n this._fillSilentAfterSeek = (Browser.msedge || Browser.msie);\n\n // While only FireFox supports 'audio/mp4, codecs=\"mp3\"', use 'audio/mpeg' for chrome, safari, ...\n this._mp3UseMpegAudio = !Browser.firefox;\n\n this._fillAudioTimestampGap = this._config.fixAudioTimestampGap;\n }\n\n destroy() {\n this._dtsBase = -1;\n this._dtsBaseInited = false;\n this._audioMeta = null;\n this._videoMeta = null;\n this._audioSegmentInfoList.clear();\n this._audioSegmentInfoList = null;\n this._videoSegmentInfoList.clear();\n this._videoSegmentInfoList = null;\n this._onInitSegment = null;\n this._onMediaSegment = null;\n }\n\n bindDataSource(producer) {\n producer.onDataAvailable = this.remux.bind(this);\n producer.onTrackMetadata = this._onTrackMetadataReceived.bind(this);\n return this;\n }\n\n /* prototype: function onInitSegment(type: string, initSegment: ArrayBuffer): void\n InitSegment: {\n type: string,\n data: ArrayBuffer,\n codec: string,\n container: string\n }\n */\n get onInitSegment() {\n return this._onInitSegment;\n }\n\n set onInitSegment(callback) {\n this._onInitSegment = callback;\n }\n\n /* prototype: function onMediaSegment(type: string, mediaSegment: MediaSegment): void\n MediaSegment: {\n type: string,\n data: ArrayBuffer,\n sampleCount: int32\n info: MediaSegmentInfo\n }\n */\n get onMediaSegment() {\n return this._onMediaSegment;\n }\n\n set onMediaSegment(callback) {\n this._onMediaSegment = callback;\n }\n\n insertDiscontinuity() {\n this._audioNextDts = this._videoNextDts = undefined;\n }\n\n seek(originalDts) {\n this._videoSegmentInfoList.clear();\n this._audioSegmentInfoList.clear();\n }\n\n remux(audioTrack, videoTrack) {\n if (!this._onMediaSegment) {\n throw new IllegalStateException('MP4Remuxer: onMediaSegment callback must be specificed!');\n }\n if (!this._dtsBaseInited) {\n this._calculateDtsBase(audioTrack, videoTrack);\n }\n this._remuxVideo(videoTrack);\n this._remuxAudio(audioTrack);\n }\n\n _onTrackMetadataReceived(type, metadata) {\n let metabox = null;\n\n let container = 'mp4';\n let codec = metadata.codec;\n\n if (type === 'audio') {\n this._audioMeta = metadata;\n if (metadata.codec === 'mp3' && this._mp3UseMpegAudio) {\n // 'audio/mpeg' for MP3 audio track\n container = 'mpeg';\n codec = '';\n metabox = new Uint8Array();\n } else {\n // 'audio/mp4, codecs=\"codec\"'\n metabox = MP4.generateInitSegment(metadata);\n }\n } else if (type === 'video') {\n this._videoMeta = metadata;\n metabox = MP4.generateInitSegment(metadata);\n } else {\n return;\n }\n\n // dispatch metabox (Initialization Segment)\n if (!this._onInitSegment) {\n throw new IllegalStateException('MP4Remuxer: onInitSegment callback must be specified!');\n }\n this._onInitSegment(type, {\n type: type,\n data: metabox.buffer,\n codec: codec,\n container: `${type}/${container}`,\n mediaDuration: metadata.duration // in timescale 1000 (milliseconds)\n });\n }\n\n _calculateDtsBase(audioTrack, videoTrack) {\n if (this._dtsBaseInited) {\n return;\n }\n\n if (audioTrack.samples && audioTrack.samples.length) {\n this._audioDtsBase = audioTrack.samples[0].dts;\n }\n if (videoTrack.samples && videoTrack.samples.length) {\n this._videoDtsBase = videoTrack.samples[0].dts;\n }\n\n this._dtsBase = Math.min(this._audioDtsBase, this._videoDtsBase);\n this._dtsBaseInited = true;\n }\n\n _remuxAudio(audioTrack) {\n if (this._audioMeta == null) {\n return;\n }\n\n let track = audioTrack;\n let samples = track.samples;\n let dtsCorrection = undefined;\n let firstDts = -1, lastDts = -1, lastPts = -1;\n let refSampleDuration = this._audioMeta.refSampleDuration;\n\n let mpegRawTrack = this._audioMeta.codec === 'mp3' && this._mp3UseMpegAudio;\n let firstSegmentAfterSeek = this._dtsBaseInited && this._audioNextDts === undefined;\n\n let insertPrefixSilentFrame = false;\n\n if (!samples || samples.length === 0) {\n return;\n }\n\n let offset = 0;\n let mdatbox = null;\n let mdatBytes = 0;\n\n // calculate initial mdat size\n if (mpegRawTrack) {\n // for raw mpeg buffer\n offset = 0;\n mdatBytes = track.length;\n } else {\n // for fmp4 mdat box\n offset = 8; // size + type\n mdatBytes = 8 + track.length;\n }\n\n let firstSampleOriginalDts = samples[0].dts - this._dtsBase;\n\n // calculate dtsCorrection\n if (this._audioNextDts) {\n dtsCorrection = firstSampleOriginalDts - this._audioNextDts;\n } else { // this._audioNextDts == undefined\n if (this._audioSegmentInfoList.isEmpty()) {\n dtsCorrection = 0;\n if (this._fillSilentAfterSeek && !this._videoSegmentInfoList.isEmpty()) {\n if (this._audioMeta.originalCodec !== 'mp3') {\n insertPrefixSilentFrame = true;\n }\n }\n } else {\n let lastSample = this._audioSegmentInfoList.getLastSampleBefore(firstSampleOriginalDts);\n if (lastSample != null) {\n let distance = (firstSampleOriginalDts - (lastSample.originalDts + lastSample.duration));\n if (distance <= 3) {\n distance = 0;\n }\n let expectedDts = lastSample.dts + lastSample.duration + distance;\n dtsCorrection = firstSampleOriginalDts - expectedDts;\n } else { // lastSample == null, cannot found\n dtsCorrection = 0;\n }\n }\n }\n\n if (insertPrefixSilentFrame) {\n // align audio segment beginDts to match with current video segment's beginDts\n let firstSampleDts = firstSampleOriginalDts - dtsCorrection;\n let videoSegment = this._videoSegmentInfoList.getLastSegmentBefore(firstSampleOriginalDts);\n if (videoSegment != null && videoSegment.beginDts < firstSampleDts) {\n let silentUnit = AAC.getSilentFrame(this._audioMeta.originalCodec, this._audioMeta.channelCount);\n if (silentUnit) {\n let dts = videoSegment.beginDts;\n let silentFrameDuration = firstSampleDts - videoSegment.beginDts;\n Log.v(this.TAG, `InsertPrefixSilentAudio: dts: ${dts}, duration: ${silentFrameDuration}`);\n samples.unshift({unit: silentUnit, dts: dts, pts: dts});\n mdatBytes += silentUnit.byteLength;\n } // silentUnit == null: Cannot generate, skip\n } else {\n insertPrefixSilentFrame = false;\n }\n }\n\n let mp4Samples = [];\n\n // Correct dts for each sample, and calculate sample duration. Then output to mp4Samples\n for (let i = 0; i < samples.length; i++) {\n let sample = samples[i];\n let unit = sample.unit;\n let originalDts = sample.dts - this._dtsBase;\n let dts = originalDts - dtsCorrection;\n\n if (firstDts === -1) {\n firstDts = dts;\n }\n\n let sampleDuration = 0;\n\n if (i !== samples.length - 1) {\n let nextDts = samples[i + 1].dts - this._dtsBase - dtsCorrection;\n sampleDuration = nextDts - dts;\n } else { // the last sample\n if (mp4Samples.length >= 1) { // use second last sample duration\n sampleDuration = mp4Samples[mp4Samples.length - 1].duration;\n } else { // the only one sample, use reference sample duration\n sampleDuration = Math.floor(refSampleDuration);\n }\n }\n\n let needFillSilentFrames = false;\n let silentFrames = null;\n\n // Silent frame generation, if large timestamp gap detected && config.fixAudioTimestampGap\n if (sampleDuration > refSampleDuration * 1.5 && this._audioMeta.codec !== 'mp3' && this._fillAudioTimestampGap && !Browser.safari) {\n // We need to insert silent frames to fill timestamp gap\n needFillSilentFrames = true;\n let delta = Math.abs(sampleDuration - refSampleDuration);\n let frameCount = Math.ceil(delta / refSampleDuration);\n let currentDts = dts + refSampleDuration; // Notice: in float\n\n Log.w(this.TAG, 'Large audio timestamp gap detected, may cause AV sync to drift. ' +\n 'Silent frames will be generated to avoid unsync.\\n' +\n `dts: ${dts + sampleDuration} ms, expected: ${dts + Math.round(refSampleDuration)} ms, ` +\n `delta: ${Math.round(delta)} ms, generate: ${frameCount} frames`);\n\n let silentUnit = AAC.getSilentFrame(this._audioMeta.originalCodec, this._audioMeta.channelCount);\n if (silentUnit == null) {\n Log.w(this.TAG, 'Unable to generate silent frame for ' +\n `${this._audioMeta.originalCodec} with ${this._audioMeta.channelCount} channels, repeat last frame`);\n // Repeat last frame\n silentUnit = unit;\n }\n silentFrames = [];\n\n for (let j = 0; j < frameCount; j++) {\n let intDts = Math.round(currentDts); // round to integer\n if (silentFrames.length > 0) {\n // Set previous frame sample duration\n let previousFrame = silentFrames[silentFrames.length - 1];\n previousFrame.duration = intDts - previousFrame.dts;\n }\n let frame = {\n dts: intDts,\n pts: intDts,\n cts: 0,\n unit: silentUnit,\n size: silentUnit.byteLength,\n duration: 0, // wait for next sample\n originalDts: originalDts,\n flags: {\n isLeading: 0,\n dependsOn: 1,\n isDependedOn: 0,\n hasRedundancy: 0\n }\n };\n silentFrames.push(frame);\n mdatBytes += unit.byteLength;\n currentDts += refSampleDuration;\n }\n\n // last frame: align end time to next frame dts\n let lastFrame = silentFrames[silentFrames.length - 1];\n lastFrame.duration = dts + sampleDuration - lastFrame.dts;\n\n // silentFrames.forEach((frame) => {\n // Log.w(this.TAG, `SilentAudio: dts: ${frame.dts}, duration: ${frame.duration}`);\n // });\n\n // Set correct sample duration for current frame\n sampleDuration = Math.round(refSampleDuration);\n }\n\n mp4Samples.push({\n dts: dts,\n pts: dts,\n cts: 0,\n unit: sample.unit,\n size: sample.unit.byteLength,\n duration: sampleDuration,\n originalDts: originalDts,\n flags: {\n isLeading: 0,\n dependsOn: 1,\n isDependedOn: 0,\n hasRedundancy: 0\n }\n });\n\n if (needFillSilentFrames) {\n // Silent frames should be inserted after wrong-duration frame\n mp4Samples.push.apply(mp4Samples, silentFrames);\n }\n }\n\n // allocate mdatbox\n if (mpegRawTrack) {\n // allocate for raw mpeg buffer\n mdatbox = new Uint8Array(mdatBytes);\n } else {\n // allocate for fmp4 mdat box\n mdatbox = new Uint8Array(mdatBytes);\n // size field\n mdatbox[0] = (mdatBytes >>> 24) & 0xFF;\n mdatbox[1] = (mdatBytes >>> 16) & 0xFF;\n mdatbox[2] = (mdatBytes >>> 8) & 0xFF;\n mdatbox[3] = (mdatBytes) & 0xFF;\n // type field (fourCC)\n mdatbox.set(MP4.types.mdat, 4);\n }\n\n // Write samples into mdatbox\n for (let i = 0; i < mp4Samples.length; i++) {\n let unit = mp4Samples[i].unit;\n mdatbox.set(unit, offset);\n offset += unit.byteLength;\n }\n\n let latest = mp4Samples[mp4Samples.length - 1];\n lastDts = latest.dts + latest.duration;\n this._audioNextDts = lastDts;\n\n // fill media segment info & add to info list\n let info = new MediaSegmentInfo();\n info.beginDts = firstDts;\n info.endDts = lastDts;\n info.beginPts = firstDts;\n info.endPts = lastDts;\n info.originalBeginDts = mp4Samples[0].originalDts;\n info.originalEndDts = latest.originalDts + latest.duration;\n info.firstSample = new SampleInfo(mp4Samples[0].dts,\n mp4Samples[0].pts,\n mp4Samples[0].duration,\n mp4Samples[0].originalDts,\n false);\n info.lastSample = new SampleInfo(latest.dts,\n latest.pts,\n latest.duration,\n latest.originalDts,\n false);\n if (!this._isLive) {\n this._audioSegmentInfoList.append(info);\n }\n\n track.samples = mp4Samples;\n track.sequenceNumber++;\n\n let moofbox = null;\n\n if (mpegRawTrack) {\n // Generate empty buffer, because useless for raw mpeg\n moofbox = new Uint8Array();\n } else {\n // Generate moof for fmp4 segment\n moofbox = MP4.moof(track, firstDts);\n }\n\n track.samples = [];\n track.length = 0;\n\n let segment = {\n type: 'audio',\n data: this._mergeBoxes(moofbox, mdatbox).buffer,\n sampleCount: mp4Samples.length,\n info: info\n };\n\n if (mpegRawTrack && firstSegmentAfterSeek) {\n // For MPEG audio stream in MSE, if seeking occurred, before appending new buffer\n // We need explicitly set timestampOffset to the desired point in timeline for mpeg SourceBuffer.\n segment.timestampOffset = firstDts;\n }\n\n this._onMediaSegment('audio', segment);\n }\n\n _remuxVideo(videoTrack) {\n if (this._videoMeta == null) {\n return;\n }\n\n let track = videoTrack;\n let samples = track.samples;\n let dtsCorrection = undefined;\n let firstDts = -1, lastDts = -1;\n let firstPts = -1, lastPts = -1;\n\n if (!samples || samples.length === 0) {\n return;\n }\n\n let offset = 8;\n let mdatBytes = 8 + videoTrack.length;\n let mdatbox = new Uint8Array(mdatBytes);\n mdatbox[0] = (mdatBytes >>> 24) & 0xFF;\n mdatbox[1] = (mdatBytes >>> 16) & 0xFF;\n mdatbox[2] = (mdatBytes >>> 8) & 0xFF;\n mdatbox[3] = (mdatBytes) & 0xFF;\n mdatbox.set(MP4.types.mdat, 4);\n\n let firstSampleOriginalDts = samples[0].dts - this._dtsBase;\n\n // calculate dtsCorrection\n if (this._videoNextDts) {\n dtsCorrection = firstSampleOriginalDts - this._videoNextDts;\n } else { // this._videoNextDts == undefined\n if (this._videoSegmentInfoList.isEmpty()) {\n dtsCorrection = 0;\n } else {\n let lastSample = this._videoSegmentInfoList.getLastSampleBefore(firstSampleOriginalDts);\n if (lastSample != null) {\n let distance = (firstSampleOriginalDts - (lastSample.originalDts + lastSample.duration));\n if (distance <= 3) {\n distance = 0;\n }\n let expectedDts = lastSample.dts + lastSample.duration + distance;\n dtsCorrection = firstSampleOriginalDts - expectedDts;\n } else { // lastSample == null, cannot found\n dtsCorrection = 0;\n }\n }\n }\n\n let info = new MediaSegmentInfo();\n let mp4Samples = [];\n\n // Correct dts for each sample, and calculate sample duration. Then output to mp4Samples\n for (let i = 0; i < samples.length; i++) {\n let sample = samples[i];\n let originalDts = sample.dts - this._dtsBase;\n let isKeyframe = sample.isKeyframe;\n let dts = originalDts - dtsCorrection;\n let cts = sample.cts;\n let pts = dts + cts;\n\n if (firstDts === -1) {\n firstDts = dts;\n firstPts = pts;\n }\n\n let sampleDuration = 0;\n\n if (i !== samples.length - 1) {\n let nextDts = samples[i + 1].dts - this._dtsBase - dtsCorrection;\n sampleDuration = nextDts - dts;\n } else { // the last sample\n if (mp4Samples.length >= 1) { // use second last sample duration\n sampleDuration = mp4Samples[mp4Samples.length - 1].duration;\n } else { // the only one sample, use reference sample duration\n sampleDuration = Math.floor(this._videoMeta.refSampleDuration);\n }\n }\n\n if (isKeyframe) {\n let syncPoint = new SampleInfo(dts, pts, sampleDuration, sample.dts, true);\n syncPoint.fileposition = sample.fileposition;\n info.appendSyncPoint(syncPoint);\n }\n\n mp4Samples.push({\n dts: dts,\n pts: pts,\n cts: cts,\n units: sample.units,\n size: sample.length,\n isKeyframe: isKeyframe,\n duration: sampleDuration,\n originalDts: originalDts,\n flags: {\n isLeading: 0,\n dependsOn: isKeyframe ? 2 : 1,\n isDependedOn: isKeyframe ? 1 : 0,\n hasRedundancy: 0,\n isNonSync: isKeyframe ? 0 : 1\n }\n });\n }\n\n // Write samples into mdatbox\n for (let i = 0; i < mp4Samples.length; i++) {\n let units = mp4Samples[i].units;\n while (units.length) {\n let unit = units.shift();\n let data = unit.data;\n mdatbox.set(data, offset);\n offset += data.byteLength;\n }\n }\n\n let latest = mp4Samples[mp4Samples.length - 1];\n lastDts = latest.dts + latest.duration;\n lastPts = latest.pts + latest.duration;\n this._videoNextDts = lastDts;\n\n // fill media segment info & add to info list\n info.beginDts = firstDts;\n info.endDts = lastDts;\n info.beginPts = firstPts;\n info.endPts = lastPts;\n info.originalBeginDts = mp4Samples[0].originalDts;\n info.originalEndDts = latest.originalDts + latest.duration;\n info.firstSample = new SampleInfo(mp4Samples[0].dts,\n mp4Samples[0].pts,\n mp4Samples[0].duration,\n mp4Samples[0].originalDts,\n mp4Samples[0].isKeyframe);\n info.lastSample = new SampleInfo(latest.dts,\n latest.pts,\n latest.duration,\n latest.originalDts,\n latest.isKeyframe);\n if (!this._isLive) {\n this._videoSegmentInfoList.append(info);\n }\n\n track.samples = mp4Samples;\n track.sequenceNumber++;\n\n // workaround for chrome < 50: force first sample as a random access point\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412\n if (this._forceFirstIDR) {\n let flags = mp4Samples[0].flags;\n flags.dependsOn = 2;\n flags.isNonSync = 0;\n }\n\n let moofbox = MP4.moof(track, firstDts);\n track.samples = [];\n track.length = 0;\n\n this._onMediaSegment('video', {\n type: 'video',\n data: this._mergeBoxes(moofbox, mdatbox).buffer,\n sampleCount: mp4Samples.length,\n info: info\n });\n }\n\n _mergeBoxes(moof, mdat) {\n let result = new Uint8Array(moof.byteLength + mdat.byteLength);\n result.set(moof, 0);\n result.set(mdat, moof.byteLength);\n return result;\n }\n\n}\n\nexport default MP4Remuxer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nlet Browser = {};\n\nfunction detect() {\n // modified from jquery-browser-plugin\n\n let ua = self.navigator.userAgent.toLowerCase();\n\n let match = /(edge)\\/([\\w.]+)/.exec(ua) ||\n /(opr)[\\/]([\\w.]+)/.exec(ua) ||\n /(chrome)[ \\/]([\\w.]+)/.exec(ua) ||\n /(iemobile)[\\/]([\\w.]+)/.exec(ua) ||\n /(version)(applewebkit)[ \\/]([\\w.]+).*(safari)[ \\/]([\\w.]+)/.exec(ua) ||\n /(webkit)[ \\/]([\\w.]+).*(version)[ \\/]([\\w.]+).*(safari)[ \\/]([\\w.]+)/.exec(ua) ||\n /(webkit)[ \\/]([\\w.]+)/.exec(ua) ||\n /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec(ua) ||\n /(msie) ([\\w.]+)/.exec(ua) ||\n ua.indexOf('trident') >= 0 && /(rv)(?::| )([\\w.]+)/.exec(ua) ||\n ua.indexOf('compatible') < 0 && /(firefox)[ \\/]([\\w.]+)/.exec(ua) ||\n [];\n\n let platform_match = /(ipad)/.exec(ua) ||\n /(ipod)/.exec(ua) ||\n /(windows phone)/.exec(ua) ||\n /(iphone)/.exec(ua) ||\n /(kindle)/.exec(ua) ||\n /(android)/.exec(ua) ||\n /(windows)/.exec(ua) ||\n /(mac)/.exec(ua) ||\n /(linux)/.exec(ua) ||\n /(cros)/.exec(ua) ||\n [];\n\n let matched = {\n browser: match[5] || match[3] || match[1] || '',\n version: match[2] || match[4] || '0',\n majorVersion: match[4] || match[2] || '0',\n platform: platform_match[0] || ''\n };\n\n let browser = {};\n if (matched.browser) {\n browser[matched.browser] = true;\n\n let versionArray = matched.majorVersion.split('.');\n browser.version = {\n major: parseInt(matched.majorVersion, 10),\n string: matched.version\n };\n if (versionArray.length > 1) {\n browser.version.minor = parseInt(versionArray[1], 10);\n }\n if (versionArray.length > 2) {\n browser.version.build = parseInt(versionArray[2], 10);\n }\n }\n\n if (matched.platform) {\n browser[matched.platform] = true;\n }\n\n if (browser.chrome || browser.opr || browser.safari) {\n browser.webkit = true;\n }\n\n // MSIE. IE11 has 'rv' identifer\n if (browser.rv || browser.iemobile) {\n if (browser.rv) {\n delete browser.rv;\n }\n let msie = 'msie';\n matched.browser = msie;\n browser[msie] = true;\n }\n\n // Microsoft Edge\n if (browser.edge) {\n delete browser.edge;\n let msedge = 'msedge';\n matched.browser = msedge;\n browser[msedge] = true;\n }\n\n // Opera 15+\n if (browser.opr) {\n let opera = 'opera';\n matched.browser = opera;\n browser[opera] = true;\n }\n\n // Stock android browsers are marked as Safari\n if (browser.safari && browser.android) {\n let android = 'android';\n matched.browser = android;\n browser[android] = true;\n }\n\n browser.name = matched.browser;\n browser.platform = matched.platform;\n\n for (let key in Browser) {\n if (Browser.hasOwnProperty(key)) {\n delete Browser[key];\n }\n }\n Object.assign(Browser, browser);\n}\n\ndetect();\n\nexport default Browser;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class RuntimeException {\n\n constructor(message) {\n this._message = message;\n }\n\n get name() {\n return 'RuntimeException';\n }\n\n get message() {\n return this._message;\n }\n\n toString() {\n return this.name + ': ' + this.message;\n }\n\n}\n\nexport class IllegalStateException extends RuntimeException {\n\n constructor(message) {\n super(message);\n }\n\n get name() {\n return 'IllegalStateException';\n }\n\n}\n\nexport class InvalidArgumentException extends RuntimeException {\n\n constructor(message) {\n super(message);\n }\n\n get name() {\n return 'InvalidArgumentException';\n }\n\n}\n\nexport class NotImplementedException extends RuntimeException {\n\n constructor(message) {\n super(message);\n }\n\n get name() {\n return 'NotImplementedException';\n }\n\n}\n","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\n\nclass Log {\n\n static e(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'error', str);\n }\n\n if (!Log.ENABLE_ERROR) {\n return;\n }\n\n if (console.error) {\n console.error(str);\n } else if (console.warn) {\n console.warn(str);\n } else {\n console.log(str);\n }\n }\n\n static i(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'info', str);\n }\n\n if (!Log.ENABLE_INFO) {\n return;\n }\n\n if (console.info) {\n console.info(str);\n } else {\n console.log(str);\n }\n }\n\n static w(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'warn', str);\n }\n\n if (!Log.ENABLE_WARN) {\n return;\n }\n\n if (console.warn) {\n console.warn(str);\n } else {\n console.log(str);\n }\n }\n\n static d(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'debug', str);\n }\n\n if (!Log.ENABLE_DEBUG) {\n return;\n }\n\n if (console.debug) {\n console.debug(str);\n } else {\n console.log(str);\n }\n }\n\n static v(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'verbose', str);\n }\n\n if (!Log.ENABLE_VERBOSE) {\n return;\n }\n\n console.log(str);\n }\n\n}\n\nLog.GLOBAL_TAG = 'flv.js';\nLog.FORCE_GLOBAL_TAG = false;\nLog.ENABLE_ERROR = true;\nLog.ENABLE_INFO = true;\nLog.ENABLE_WARN = true;\nLog.ENABLE_DEBUG = true;\nLog.ENABLE_VERBOSE = true;\n\nLog.ENABLE_CALLBACK = false;\n\nLog.emitter = new EventEmitter();\n\nexport default Log;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from './logger.js';\n\nclass LoggingControl {\n\n static get forceGlobalTag() {\n return Log.FORCE_GLOBAL_TAG;\n }\n\n static set forceGlobalTag(enable) {\n Log.FORCE_GLOBAL_TAG = enable;\n LoggingControl._notifyChange();\n }\n\n static get globalTag() {\n return Log.GLOBAL_TAG;\n }\n\n static set globalTag(tag) {\n Log.GLOBAL_TAG = tag;\n LoggingControl._notifyChange();\n }\n\n static get enableAll() {\n return Log.ENABLE_VERBOSE\n && Log.ENABLE_DEBUG\n && Log.ENABLE_INFO\n && Log.ENABLE_WARN\n && Log.ENABLE_ERROR;\n }\n\n static set enableAll(enable) {\n Log.ENABLE_VERBOSE = enable;\n Log.ENABLE_DEBUG = enable;\n Log.ENABLE_INFO = enable;\n Log.ENABLE_WARN = enable;\n Log.ENABLE_ERROR = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableDebug() {\n return Log.ENABLE_DEBUG;\n }\n\n static set enableDebug(enable) {\n Log.ENABLE_DEBUG = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableVerbose() {\n return Log.ENABLE_VERBOSE;\n }\n\n static set enableVerbose(enable) {\n Log.ENABLE_VERBOSE = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableInfo() {\n return Log.ENABLE_INFO;\n }\n\n static set enableInfo(enable) {\n Log.ENABLE_INFO = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableWarn() {\n return Log.ENABLE_WARN;\n }\n\n static set enableWarn(enable) {\n Log.ENABLE_WARN = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableError() {\n return Log.ENABLE_ERROR;\n }\n\n static set enableError(enable) {\n Log.ENABLE_ERROR = enable;\n LoggingControl._notifyChange();\n }\n\n static getConfig() {\n return {\n globalTag: Log.GLOBAL_TAG,\n forceGlobalTag: Log.FORCE_GLOBAL_TAG,\n enableVerbose: Log.ENABLE_VERBOSE,\n enableDebug: Log.ENABLE_DEBUG,\n enableInfo: Log.ENABLE_INFO,\n enableWarn: Log.ENABLE_WARN,\n enableError: Log.ENABLE_ERROR,\n enableCallback: Log.ENABLE_CALLBACK\n };\n }\n\n static applyConfig(config) {\n Log.GLOBAL_TAG = config.globalTag;\n Log.FORCE_GLOBAL_TAG = config.forceGlobalTag;\n Log.ENABLE_VERBOSE = config.enableVerbose;\n Log.ENABLE_DEBUG = config.enableDebug;\n Log.ENABLE_INFO = config.enableInfo;\n Log.ENABLE_WARN = config.enableWarn;\n Log.ENABLE_ERROR = config.enableError;\n Log.ENABLE_CALLBACK = config.enableCallback;\n }\n\n static _notifyChange() {\n let emitter = LoggingControl.emitter;\n\n if (emitter.listenerCount('change') > 0) {\n let config = LoggingControl.getConfig();\n emitter.emit('change', config);\n }\n }\n\n static registerListener(listener) {\n LoggingControl.emitter.addListener('change', listener);\n }\n\n static removeListener(listener) {\n LoggingControl.emitter.removeListener('change', listener);\n }\n\n static addLogListener(listener) {\n Log.emitter.addListener('log', listener);\n if (Log.emitter.listenerCount('log') > 0) {\n Log.ENABLE_CALLBACK = true;\n LoggingControl._notifyChange();\n }\n }\n\n static removeLogListener(listener) {\n Log.emitter.removeListener('log', listener);\n if (Log.emitter.listenerCount('log') === 0) {\n Log.ENABLE_CALLBACK = false;\n LoggingControl._notifyChange();\n }\n }\n\n}\n\nLoggingControl.emitter = new EventEmitter();\n\nexport default LoggingControl;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass Polyfill {\n\n static install() {\n // ES6 Object.setPrototypeOf\n Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {\n obj.__proto__ = proto;\n return obj;\n };\n\n // ES6 Object.assign\n Object.assign = Object.assign || function (target) {\n if (target === undefined || target === null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n let output = Object(target);\n for (let i = 1; i < arguments.length; i++) {\n let source = arguments[i];\n if (source !== undefined && source !== null) {\n for (let key in source) {\n if (source.hasOwnProperty(key)) {\n output[key] = source[key];\n }\n }\n }\n }\n return output;\n };\n\n // ES6 Promise (missing support in IE11)\n if (typeof self.Promise !== 'function') {\n require('es6-promise').polyfill();\n }\n }\n\n}\n\nPolyfill.install();\n\nexport default Polyfill;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * This file is derived from C++ project libWinTF8 (https://github.com/m13253/libWinTF8)\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nfunction checkContinuation(uint8array, start, checkLength) {\n let array = uint8array;\n if (start + checkLength < array.length) {\n while (checkLength--) {\n if ((array[++start] & 0xC0) !== 0x80)\n return false;\n }\n return true;\n } else {\n return false;\n }\n}\n\nfunction decodeUTF8(uint8array) {\n let out = [];\n let input = uint8array;\n let i = 0;\n let length = uint8array.length;\n\n while (i < length) {\n if (input[i] < 0x80) {\n out.push(String.fromCharCode(input[i]));\n ++i;\n continue;\n } else if (input[i] < 0xC0) {\n // fallthrough\n } else if (input[i] < 0xE0) {\n if (checkContinuation(input, i, 1)) {\n let ucs4 = (input[i] & 0x1F) << 6 | (input[i + 1] & 0x3F);\n if (ucs4 >= 0x80) {\n out.push(String.fromCharCode(ucs4 & 0xFFFF));\n i += 2;\n continue;\n }\n }\n } else if (input[i] < 0xF0) {\n if (checkContinuation(input, i, 2)) {\n let ucs4 = (input[i] & 0xF) << 12 | (input[i + 1] & 0x3F) << 6 | input[i + 2] & 0x3F;\n if (ucs4 >= 0x800 && (ucs4 & 0xF800) !== 0xD800) {\n out.push(String.fromCharCode(ucs4 & 0xFFFF));\n i += 3;\n continue;\n }\n }\n } else if (input[i] < 0xF8) {\n if (checkContinuation(input, i, 3)) {\n let ucs4 = (input[i] & 0x7) << 18 | (input[i + 1] & 0x3F) << 12\n | (input[i + 2] & 0x3F) << 6 | (input[i + 3] & 0x3F);\n if (ucs4 > 0x10000 && ucs4 < 0x110000) {\n ucs4 -= 0x10000;\n out.push(String.fromCharCode((ucs4 >>> 10) | 0xD800));\n out.push(String.fromCharCode((ucs4 & 0x3FF) | 0xDC00));\n i += 4;\n continue;\n }\n }\n }\n out.push(String.fromCharCode(0xFFFD));\n ++i;\n }\n\n return out.join('');\n}\n\nexport default decodeUTF8;"]} \ No newline at end of file diff --git a/tools/MP4 Stream/index.html b/tools/MP4 Stream/index.html new file mode 100644 index 0000000..bf4a4ec --- /dev/null +++ b/tools/MP4 Stream/index.html @@ -0,0 +1,29 @@ + + + + + + + FLV to Web Test by Shinobi Systems + + + + + + + \ No newline at end of file diff --git a/tools/addVideos.js.disabled b/tools/addVideos.js.disabled new file mode 100644 index 0000000..e791f3f --- /dev/null +++ b/tools/addVideos.js.disabled @@ -0,0 +1,48 @@ +//add videos to SQL tables from filesystem +var fs = require('fs'); +var moment = require('moment'); +var mysql = require('mysql'); +var config = require('../conf.json'); +s={} +s.disc=function(){ + sql = mysql.createConnection(config.db); + sql.connect(function(err){if(err){console.log('Error Connecting : DB',err);setTimeout(s.disc, 2000);}}); + sql.on('error',function(err) {console.log('DB Lost.. Retrying..');console.log(err);s.disc();return;}); +} +s.disc(); +if(!config.videosDir){config.videosDir=__dirname+'/../videos/'} +s.dir={videos:config.videosDir}; +s.nameToTime=function(x){x=x.split('.')[0].split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;} +s.moment=function(e,x){ + if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'}; + return moment(e).format(x); +} +fs.readdir(s.dir.videos,function(err,groups){ + groups.forEach(function(group){ + fs.readdir(s.dir.videos+group,function(err,cameras){ + cameras.forEach(function(camera){ + fs.readdir(s.dir.videos+group+'/'+camera,function(err,videos){ + sql.query('SELECT * FROM Videos WHERE ke=? AND mid=?',[group,camera],function(err,r){ + videos.forEach(function(filename){ + fs.stat(s.dir.videos+group+'/'+camera+'/'+filename,function(err,file){ + file.startTime=s.nameToTime(filename) + file.endTime=s.moment(file.mtime,'YYYY-MM-DD HH:mm:ss') + var save=[camera,group,filename.split('.')[1],file.size,file.startTime,file.endTime,1] + var found=null + r.forEach(function(v){ + if(s.moment(v.time,'YYYY-MM-DD HH:mm:ss')===file.startTime){ + found=v + } + }) + if(!found){ + console.log('!found',save) + sql.query('INSERT INTO Videos (mid,ke,ext,size,time,end,status) VALUES (?,?,?,?,?,?,?)',save) + } + }) + }) + }) + }) + }) + }) + }) +}) \ No newline at end of file diff --git a/tools/checkNPM.js b/tools/checkNPM.js new file mode 100644 index 0000000..ef2bdf5 --- /dev/null +++ b/tools/checkNPM.js @@ -0,0 +1,10 @@ +var fs=require('fs'); +function npmls(cb) { + require('child_process').exec('npm ls --json', function(err, stdout, stderr) { + if (err) return cb(err) + cb(null, JSON.stringify(JSON.parse(stdout),null,3)); + }); +} +npmls(function(yolo,stdout){ +fs.writeFileSync(__dirname+'/npmls.json',stdout) +}); diff --git a/tools/coco/testCoco.js b/tools/coco/testCoco.js new file mode 100644 index 0000000..b675ba8 --- /dev/null +++ b/tools/coco/testCoco.js @@ -0,0 +1,103 @@ +var cv = require('opencv4nodejs') +const fs = require('fs'); +const path = require('path'); +const classNames = require('./dnnCocoClassNames'); +const { extractResults } = require('./dnn/ssdUtils'); + +if (!cv.xmodules.dnn) { + throw new Error('exiting: opencv4nodejs compiled without dnn module'); +} + +// replace with path where you unzipped inception model +const ssdcocoModelPath = '../data/dnn/coco-SSD_300x300'; + +const prototxt = path.resolve(ssdcocoModelPath, 'deploy.prototxt'); +const modelFile = path.resolve(ssdcocoModelPath, 'VGG_coco_SSD_300x300_iter_400000.caffemodel'); + +if (!fs.existsSync(prototxt) || !fs.existsSync(modelFile)) { + console.log('could not find ssdcoco model'); + console.log('download the model from: https://drive.google.com/file/d/0BzKzrI_SkD1_dUY1Ml9GRTFpUWc/view'); + throw new Error('exiting: could not find ssdcoco model'); +} + +// initialize ssdcoco model from prototxt and modelFile +const net = cv.readNetFromCaffe(prototxt, modelFile); + +function classifyImg(img) { + // ssdcoco model works with 300 x 300 images + const imgResized = img.resize(300, 300); + + // network accepts blobs as input + const inputBlob = cv.blobFromImage(imgResized); + net.setInput(inputBlob); + + // forward pass input through entire network, will return + // classification result as 1x1xNxM Mat + let outputBlob = net.forward(); + // extract NxM Mat + outputBlob = outputBlob.flattenFloat(outputBlob.sizes[2], outputBlob.sizes[3]); + + return extractResults(outputBlob, img) + .map(r => Object.assign({}, r, { className: classNames[r.classLabel] })); +} + +const makeDrawClassDetections = predictions => (drawImg, className, getColor, thickness = 2) => { + predictions + .filter(p => classNames[p.classLabel] === className) + .forEach(p => drawRect(drawImg, p.rect, getColor(), { thickness })); + return drawImg; +}; + +const runDetectDishesExample = () => { + const img = cv.imread('../data/dishes.jpg'); + const minConfidence = 0.2; + + const predictions = classifyImg(img).filter(res => res.confidence > minConfidence); + + const drawClassDetections = makeDrawClassDetections(predictions); + + const classColors = { + fork: new cv.Vec(0, 255, 0), + bowl: new cv.Vec(255, 0, 0), + 'wine glass': new cv.Vec(0, 0, 255), + cup: new cv.Vec(0, 255, 255) + }; + + const legendLeftTop = new cv.Point(580, 20); + const alpha = 0.4; + cv.drawTextBox( + img, + legendLeftTop, + Object.keys(classColors).map(className => ({ + text: className, + fontSize: 0.8, + color: classColors[className] + })), + alpha + ); + + Object.keys(classColors).forEach((className) => { + const color = classColors[className]; + // draw detections + drawClassDetections(img, className, () => color); + }); + + cv.imshowWait('img', img); +}; + +const runDetectPeopleExample = () => { + const img = cv.imread('../data/cars.jpeg'); + const minConfidence = 0.4; + + const predictions = classifyImg(img).filter(res => res.confidence > minConfidence); + + const drawClassDetections = makeDrawClassDetections(predictions); + + const getRandomColor = () => new cv.Vec(Math.random() * 255, Math.random() * 255, 255); + + drawClassDetections(img, 'car', getRandomColor); + cv.imshowWait('img', img); +}; + +runDetectDishesExample(); +runDetectPeopleExample(); \ No newline at end of file diff --git a/tools/cron.js b/tools/cron.js new file mode 100644 index 0000000..d84c34d --- /dev/null +++ b/tools/cron.js @@ -0,0 +1,405 @@ + +var fs = require('fs'); +var path = require('path'); +var mysql = require('mysql'); +var moment = require('moment'); +var exec = require('child_process').exec; +var spawn = require('child_process').spawn; +var config=require(__dirname+'/../conf.json'); +var sql=mysql.createConnection(config.db); + +//set option defaults +s={}; +if(config.cron===undefined)config.cron={}; +if(config.cron.enabled===undefined)config.cron.enabled=true; +if(config.cron.deleteOld===undefined)config.cron.deleteOld=true; +if(config.cron.deleteOrphans===undefined)config.cron.deleteOrphans=false; +if(config.cron.deleteNoVideo===undefined)config.cron.deleteNoVideo=true; +if(config.cron.deleteNoVideoRecursion===undefined)config.cron.deleteNoVideoRecursion=false; +if(config.cron.deleteOverMax===undefined)config.cron.deleteOverMax=true; +if(config.cron.deleteLogs===undefined)config.cron.deleteLogs=true; +if(config.cron.deleteEvents===undefined)config.cron.deleteEvents=true; +if(config.cron.deleteFileBins===undefined)config.cron.deleteFileBins=true; +if(config.cron.interval===undefined)config.cron.interval=1; + +if(!config.ip||config.ip===''||config.ip.indexOf('0.0.0.0')>-1)config.ip='localhost'; +if(!config.videosDir)config.videosDir=__dirname+'/videos/'; +if(!config.binDir){config.binDir=__dirname+'/fileBin/'} +if(!config.addStorage){config.addStorage=[]} +//containers +cronOverlapLock={}; +cronAlreadyDeletedRowsWithNoVideosOnStart={}; +//functions +module.exports.checkCorrectPathEnding=function(x){ + var length=x.length + if(x.charAt(length-1)!=='/'){ + x=x+'/' + } + return x.replace('__DIR__',__dirname) +} +module.exports.dir={ + videos:module.exports.checkCorrectPathEnding(config.videosDir), + fileBin:module.exports.checkCorrectPathEnding(config.binDir), + addStorage:config.addStorage, +}; +module.exports.moment=function(e,x){ + if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'}; + return moment(e).format(x); +} +module.exports.nameToTime=function(x){x=x.replace('.webm','').replace('.mp4','').split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;} +io = require('socket.io-client')('ws://'+config.ip+':'+config.port);//connect to master +module.exports.cx=function(x){x.cronKey=config.cron.key;return io.emit('cron',x)} +//emulate master socket emitter +module.exports.tx=function(x,y){module.exports.cx({f:'module.exports.tx',data:x,to:y})} +module.exports.video=function(x,y){module.exports.cx({f:'module.exports.video',data:x,file:y})} +//Cron Job +module.exports.cx({f:'init',time:moment()}) +module.exports.getVideoDirectory=function(e){ + if(e.mid&&!e.id){e.id=e.mid}; + if(e.details&&(e.details instanceof Object)===false){ + try{e.details=JSON.parse(e.details)}catch(err){} + } + if(e.details.dir&&e.details.dir!==''){ + return module.exports.checkCorrectPathEnding(e.details.dir)+e.ke+'/'+e.id+'/' + }else{ + return module.exports.dir.videos+e.ke+'/'+e.id+'/'; + } +} +module.exports.getFileBinDirectory=function(e){ + if(e.mid&&!e.id){e.id=e.mid}; + return module.exports.dir.fileBin+e.ke+'/'+e.id+'/'; +} +//filters set by the user in their dashboard +//deleting old videos is part of the filter - config.cron.deleteOld +module.exports.cronCheckFilterRules=function(v,callback){ + //filters + if(!v.d.filters||v.d.filters==''){ + v.d.filters={}; + } + //delete old videos with filter + if(config.cron.deleteOld===true){ + v.d.filters.deleteOldByCron={ + "id":"deleteOldByCron", + "name":"deleteOldByCron", + "sort_by":"time", + "sort_by_direction":"ASC", + "limit":"", + "enabled":"1", + "archive":"0", + "email":"0", + "delete":"1", + "execute":"", + "where":[{ + "p1":"end", + "p2":"<", + "p3":"NOW() - INTERVAL "+(v.maxVideoDays[v.mid]*24)+" HOUR", + "p3_type":"function", + }] + }; + } + var keys = Object.keys(v.d.filters) + if(keys.length>0){ + keys.forEach(function(m,current){ + var b=v.d.filters[m]; + if(b.enabled==="1"){ + b.ar=[v.ke]; + b.sql=[]; + b.where.forEach(function(j,k){ + if(j.p1==='ke'){j.p3=v.ke} + switch(j.p3_type){ + case'function': + b.sql.push(j.p1+' '+j.p2+' '+j.p3) + break; + default: + b.sql.push(j.p1+' '+j.p2+' ?') + b.ar.push(j.p3) + break; + } + }) + b.sql='WHERE ke=? AND status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND ('+b.sql.join(' AND ')+')'; + if(b.sort_by&&b.sort_by!==''){ + b.sql+=' ORDER BY `'+b.sort_by+'` '+b.sort_by_direction + } + if(b.limit&&b.limit!==''){ + b.sql+=' LIMIT '+b.limit + } + sql.query('SELECT * FROM Videos '+b.sql,b.ar,function(err,r){ + if(r&&r[0]){ + b.cx={ + f:'filters', + name:b.name, + videos:r, + time:moment(), + ke:v.ke, + id:b.id + }; + if(b.archive==="1"){ + module.exports.cx({f:'filters',ff:'archive',videos:r,time:moment(),ke:v.ke,id:b.id}); + }else{ + if(b.delete==="1"){ + module.exports.cx({f:'filters',ff:'delete',videos:r,time:moment(),ke:v.ke,id:b.id}); + } + } + if(b.email==="1"){ + b.cx.ff='email'; + b.cx.delete=b.delete; + b.cx.mail=v.mail; + b.cx.execute=b.execute; + b.cx.query=b.sql; + module.exports.cx(b.cx); + } + if(b.execute&&b.execute!==""){ + module.exports.cx({f:'filters',ff:'execute',execute:b.execute,time:moment()}); + } + } + }) + + } + if(current===keys.length-1){ + //last filter + callback() + } + }) + }else{ + //no filters + callback() + } +} +//database rows with no videos in the filesystem +module.exports.cronDeleteRowsWithNoVideo=function(v,callback){ + if( + config.cron.deleteNoVideo===true&&( + config.cron.deleteNoVideoRecursion===true|| + (config.cron.deleteNoVideoRecursion===false&&!cronAlreadyDeletedRowsWithNoVideosOnStart[v.ke]) + ) + ){ + cronAlreadyDeletedRowsWithNoVideosOnStart[v.ke]=true; + es={}; + sql.query('SELECT * FROM Videos WHERE ke = ? AND status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND time < (NOW() - INTERVAL 10 MINUTE)',[v.ke],function(err,evs){ + if(evs&&evs[0]){ + es.del=[];es.ar=[v.ke]; + evs.forEach(function(ev){ + ev.dir=module.exports.getVideoDirectory(ev)+module.exports.moment(ev.time)+'.'+ev.ext; + if(fs.existsSync(ev.dir)!==true){ + module.exports.video('delete',ev) + es.del.push('(mid=? AND time=?)'); + es.ar.push(ev.mid),es.ar.push(ev.time); + module.exports.tx({f:'video_delete',filename:module.exports.moment(ev.time)+'.'+ev.ext,mid:ev.mid,ke:ev.ke,time:ev.time,end:module.exports.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+ev.ke); + } + }); + if(es.del.length>0){ + module.exports.cx({f:'deleteNoVideo',msg:es.del.length+' SQL rows with no file deleted',ke:v.ke,time:moment()}) + } + } + setTimeout(function(){ + callback() + },3000) + }) + }else{ + callback() + } +} +//info about what the application is doing +module.exports.cronDeleteOldLogs=function(v,callback){ + if(!v.d.log_days||v.d.log_days==''){v.d.log_days=10}else{v.d.log_days=parseFloat(v.d.log_days)}; + if(config.cron.deleteLogs===true&&v.d.log_days!==0){ + sql.query("DELETE FROM Logs WHERE ke=? AND `time` < DATE_SUB(NOW(), INTERVAL ? DAY)",[v.ke,v.d.log_days],function(err,rrr){ + callback() + if(err)return console.error(err); + if(rrr.affectedRows.length>0){ + module.exports.cx({f:'deleteLogs',msg:rrr.affectedRows+' SQL rows older than '+v.d.log_days+' days deleted',ke:v.ke,time:moment()}) + } + }) + }else{ + callback() + } +} +//events - motion, object, etc. detections +module.exports.cronDeleteOldEvents=function(v,callback){ + if(!v.d.event_days||v.d.event_days==''){v.d.event_days=10}else{v.d.event_days=parseFloat(v.d.event_days)}; + if(config.cron.deleteEvents===true&&v.d.event_days!==0){ + sql.query("DELETE FROM Events WHERE ke=? AND `time` < DATE_SUB(NOW(), INTERVAL ? DAY)",[v.ke,v.d.event_days],function(err,rrr){ + callback() + if(err)return console.error(err); + if(rrr.affectedRows.length>0){ + module.exports.cx({f:'deleteEvents',msg:rrr.affectedRows+' SQL rows older than '+v.d.event_days+' days deleted',ke:v.ke,time:moment()}) + } + }) + }else{ + callback() + } +} +//check for temporary files (special archive) +cronDeleteOldFileBins=function(v,callback){ + if(!v.d.fileBin_days||v.d.fileBin_days==''){v.d.fileBin_days=10}else{v.d.fileBin_days=parseFloat(v.d.fileBin_days)}; + if(config.cron.deleteFileBins===true&&v.d.fileBin_days!==0){ + var fileBinQuery = ' FROM Files WHERE ke=? AND `date` < DATE_SUB(NOW(), INTERVAL ? DAY)'; + sql.query("SELECT *"+fileBinQuery,[v.ke,v.d.fileBin_days],function(err,files){ + if(files&&files[0]){ + //delete the files + files.forEach(function(file){ + fs.unlink(module.exports.getFileBinDirectory(file)+file.name,function(err){ +// if(err)console.error(err) + }) + }) + //delete the database rows + sql.query("DELETE"+fileBinQuery,[v.ke,v.d.fileBin_days],function(err,rrr){ + callback() + if(err)return console.error(err); + if(rrr.affectedRows.length>0){ + module.exports.cx({f:'deleteFileBins',msg:rrr.affectedRows+' files older than '+v.d.fileBin_days+' days deleted',ke:v.ke,time:moment()}) + } + }) + }else{ + callback() + } + }) + }else{ + callback() + } +} +//check for files with no database row +cronCheckForOrphanedFiles=function(v,callback){ + if(config.cron.deleteOrphans===true){ + var finish=function(count){ + if(count>0){ + module.exports.cx({f:'deleteOrphanedFiles',msg:count+' SQL rows with no database row deleted',ke:v.ke,time:moment()}) + } + callback() + } + e={}; + var numberOfItems = 0; + sql.query('SELECT * FROM Monitors WHERE ke=?',[v.ke],function(arr,b) { + if(b&&b[0]){ + b.forEach(function(mon,m){ + fs.readdir(module.exports.getVideoDirectory(mon), function(err, items) { + e.query=[]; + e.filesFound=[mon.ke,mon.mid]; + numberOfItems+=items.length; + if(items&&items.length>0){ + items.forEach(function(v,n){ + e.query.push('time=?') + e.filesFound.push(module.exports.nameToTime(v)) + }) + sql.query('SELECT * FROM Videos WHERE ke=? AND mid=? AND ('+e.query.join(' OR ')+')',e.filesFound,function(arr,r) { + if(!r){r=[]}; + e.foundSQLrows=[]; + r.forEach(function(v,n){ + v.index=e.filesFound.indexOf(module.exports.moment(v.time,'YYYY-MM-DD HH:mm:ss')); + if(v.index>-1){ + delete(items[v.index-2]); + } + }); + items.forEach(function(v,n){ + if(v&&v!==null){ + exec('rm '+module.exports.getVideoDirectory(mon)+v); + } + if(m===b.length-1&&n===items.length-1){ + finish(numberOfItems) + } + }) + }) + }else{ + if(m===b.length-1){ + finish(numberOfItems) + } + } + }) + }); + }else{ + finish(numberOfItems) + } + }); + }else{ + callback() + } +} +//user processing function +cronProcessUser = function(number,rows){ + console.log('processUser') + var v = rows[number]; + if(!v){ + //no user object given + return + } + if(!cronAlreadyDeletedRowsWithNoVideosOnStart[v.ke]){ + cronAlreadyDeletedRowsWithNoVideosOnStart[v.ke]=false; + } + if(!cronOverlapLock[v.ke]){ + // set overlap lock + cronOverlapLock[v.ke]=true; + //set permissions + v.d=JSON.parse(v.details); + //size + if(!v.d.size||v.d.size==''){v.d.size=10000}else{v.d.size=parseFloat(v.d.size)}; + //days to keep videos + v.maxVideoDays={} + if(!v.d.days||v.d.days==''){v.d.days=5}else{v.d.days=parseFloat(v.d.days)}; + sql.query('SELECT * FROM Monitors WHERE ke=?', [v.ke], function(err,rr) { + rr.forEach(function(b,m){ + b.details=JSON.parse(b.details); + if(b.details.max_keep_days&&b.details.max_keep_days!==''){ + v.maxVideoDays[b.mid]=parseFloat(b.details.max_keep_days) + }else{ + v.maxVideoDays[b.mid]=v.d.days + }; + }) + cronDeleteOldLogs(v,function(){ + cronDeleteOldFileBins(v,function(){ + cronDeleteOldEvents(v,function(){ + cronCheckFilterRules(v,function(){ + cronDeleteRowsWithNoVideo(v,function(){ + cronCheckForOrphanedFiles(v,function(){ + //done user, unlock current, and do next + cronOverlapLock[v.ke]=false; + cronProcessUser(number+1,rows) + }) + }) + }) + }) + }) + }) + }) + } +} +//recursive function +var cronTimeout; +cronStart = function(){ + clearTimeout(cronTimeout); + x={}; + module.exports.cx({f:'start',time:moment()}) + sql.query('SELECT ke,uid,details,mail FROM Users WHERE details NOT LIKE \'%"sub"%\'', function(err,rows) { + if(err){ + console.error(err) + } + if(rows&&rows[0]){ + cronProcessUser(0,rows) + } + }) + cronTimeout=setTimeout(function(){ + cronStart(); + },parseFloat(config.cron.interval)*60000*60) +} +cronStop = function(){ + clearTimeout(cronTimeout); +} +//socket commander +io.on('f',function(d){ + switch(d.f){ + case'start':case'restart': + cronStart(); + break; + case'stop': + cronStop(); + break; + } +}) +console.log('Shinobi : cron.js loaded') +module.exports = { + begin:cronStart, + start:cronStart, + restart:cronStart, + stop:cronStop, + end:cronStop, + kill:cronStop +} \ No newline at end of file diff --git a/tools/ffmpegToWeb.rar b/tools/ffmpegToWeb.rar new file mode 100644 index 0000000..7338586 Binary files /dev/null and b/tools/ffmpegToWeb.rar differ diff --git a/tools/ffmpegToWeb/.gitignore b/tools/ffmpegToWeb/.gitignore new file mode 100644 index 0000000..2de7dcc --- /dev/null +++ b/tools/ffmpegToWeb/.gitignore @@ -0,0 +1,9 @@ +node_modules +videos +events +frames +web.old +.DS_Store +.vagrant +conf.json +ffmpeg \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/.gitignore b/tools/ffmpegToWeb/Player/broadway/.gitignore new file mode 100644 index 0000000..fdc4fde --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/.gitignore @@ -0,0 +1,3 @@ +/npm-debug.log +/node_modules +/disc diff --git a/tools/ffmpegToWeb/Player/broadway/.npmignore b/tools/ffmpegToWeb/Player/broadway/.npmignore new file mode 100644 index 0000000..3f14c7c --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/.npmignore @@ -0,0 +1,4 @@ +/npm-debug.log +/node_modules +/dist +/disc diff --git a/tools/ffmpegToWeb/Player/broadway/AUTHORS b/tools/ffmpegToWeb/Player/broadway/AUTHORS new file mode 100644 index 0000000..0ba3fb5 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/AUTHORS @@ -0,0 +1,19 @@ +The following authors have all licensed their contributions to the project +under the licensing terms detailed in LICENSE (MIT style) + +# h264-live-player +* Francois Leurent @131 <131.js@cloudyks.org> + +# Broadway emscriptend h264 (broadway/Decoder.js) +* Michael Bebenita +* Alon Zakai +* Andreas Gal +* Mathieu 'p01' Henri +* Matthias 'soliton4' Behrens + +# WebGL canvas helpers +* Sam Leitch @oneam + +# AVC player inspiration +* Benjamin Xiao @urbenlegend + diff --git a/tools/ffmpegToWeb/Player/broadway/LICENSE b/tools/ffmpegToWeb/Player/broadway/LICENSE new file mode 100644 index 0000000..507f677 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/LICENSE @@ -0,0 +1,10 @@ +Copyright (c) 2016, Project Authors (see AUTHORS file) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * 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. + * Neither the names of the Project Authors 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. diff --git a/tools/ffmpegToWeb/Player/broadway/README.md b/tools/ffmpegToWeb/Player/broadway/README.md new file mode 100644 index 0000000..01556d7 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/README.md @@ -0,0 +1,11 @@ +# Motivation + +This is a very efficient h264 video player (that can run on live stream) for your browser. +You might use this with raspicam raw h264 stream. + +This is a player around [Broadway](https://github.com/mbebenita/Broadway) Decoder, with very simple API. +NAL unit (h264 frames) are split on the server side, so the client side is very simple (and allow frame skipping easily) + + +See [github sample project's page for more information](https://github.com/131/h264-live-player) + diff --git a/tools/ffmpegToWeb/Player/broadway/broadway/Decoder.js b/tools/ffmpegToWeb/Player/broadway/broadway/Decoder.js new file mode 100644 index 0000000..0a66260 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/broadway/Decoder.js @@ -0,0 +1,966 @@ +// universal module definition +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], factory); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.Decoder = factory(); + } +}(this, function () { + + var global; + + function initglobal(){ + global = this; + if (!global){ + if (typeof window != "undefined"){ + global = window; + }else if (typeof self != "undefined"){ + global = self; + }; + }; + }; + initglobal(); + + + function error(message) { + console.error(message); + console.trace(); + }; + + + function assert(condition, message) { + if (!condition) { + error(message); + }; + }; + + + return (function(){ + "use strict"; + + + + + var getModule = function(_broadwayOnHeadersDecoded, _broadwayOnPictureDecoded){ + + var window = this; + //console.log(typeof window); + + window._broadwayOnHeadersDecoded = _broadwayOnHeadersDecoded; + window._broadwayOnPictureDecoded = _broadwayOnPictureDecoded; + + var Module = { + 'print': function(text) { console.log('stdout: ' + text); }, + 'printErr': function(text) { console.log('stderr: ' + text); } + }; + + + /* + + The reason why this is all packed into one file is that this file can also function as worker. + you can integrate the file into your build system and provide the original file to be loaded into a worker. + + */ + +function d(a){throw a;}var g=void 0,i=!0,k=null,m=!1;function n(){return function(){}}var p;p||(p=eval("(function() { try { return Module || {} } catch(e) { return {} } })()"));var aa={},r;for(r in p)p.hasOwnProperty(r)&&(aa[r]=p[r]);var t="object"===typeof process&&"function"===typeof null,ba="object"===typeof window,ca="function"===typeof importScripts,da=!ba&&!t&&!ca; +if(t){p.print||(p.print=function(a){process.stdout.write(a+"\n")});p.printErr||(p.printErr=function(a){process.stderr.write(a+"\n")});var fa=(null)("fs"),ga=(null)("path");p.read=function(a,b){var a=ga.normalize(a),c=fa.readFileSync(a);!c&&a!=ga.resolve(a)&&(a=path.join(__dirname,"..","src",a),c=fa.readFileSync(a));c&&!b&&(c=c.toString());return c};p.readBinary=function(a){return p.read(a,i)};p.load=function(a){ha(read(a))};p.thisProgram=1 0) var gc = undefined")):ba||ca?(p.read=function(a){var b=new XMLHttpRequest;b.open("GET",a,m);b.send(k);return b.responseText},"undefined"!=typeof arguments&&(p.arguments=arguments),"undefined"!==typeof console?(p.print||(p.print=function(a){console.log(a)}),p.printErr||(p.printErr=function(a){console.log(a)})):p.print||(p.print= +n()),ba?window.Module=p:p.load=importScripts):d("Unknown runtime environment. Where are we?");function ha(a){eval.call(k,a)}!p.load&&p.read&&(p.load=function(a){ha(p.read(a))});p.print||(p.print=n());p.printErr||(p.printErr=p.print);p.arguments||(p.arguments=[]);p.thisProgram||(p.thisProgram="./this.program");p.print=p.print;p.fa=p.printErr;p.preRun=[];p.postRun=[];for(r in aa)aa.hasOwnProperty(r)&&(p[r]=aa[r]); +var z={Yd:function(a){ja=a},xd:function(){return ja},Tb:function(){return y},Sb:function(a){y=a},oc:function(a){switch(a){case "i1":case "i8":return 1;case "i16":return 2;case "i32":return 4;case "i64":return 8;case "float":return 4;case "double":return 8;default:return"*"===a[a.length-1]?z.ia:"i"===a[0]?(a=parseInt(a.substr(1)),w(0===a%8),a/8):0}},vd:function(a){return Math.max(z.oc(a),z.ia)},Qf:16,ng:function(a,b,c){return!c&&("i64"==a||"double"==a)?8:!a?Math.min(b,8):Math.min(b||(a?z.vd(a):0), +z.ia)},Fa:function(a,b,c){return c&&c.length?(c.splice||(c=Array.prototype.slice.call(c)),c.splice(0,0,b),p["dynCall_"+a].apply(k,c)):p["dynCall_"+a].call(k,b)},eb:[],Vc:function(a){for(var b=0;b=F&&A("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+F+", (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.");return b},ub:function(a,b){return Math.ceil(a/(b?b:16))*(b?b:16)},Fg:function(a,b,c){return c?+(a>>>0)+4294967296*+(b>>>0):+(a>>>0)+4294967296* ++(b|0)},Pc:8,ia:4,Rf:0};p.Runtime=z;z.addFunction=z.Vc;z.removeFunction=z.Sd;var H=m,la,ma,ja;function w(a,b){a||A("Assertion failed: "+b)}function na(a){var b=p["_"+a];if(!b)try{b=eval("_"+a)}catch(c){}w(b,"Cannot call unknown function "+a+" (perhaps LLVM optimizations or closure removed it?)");return b}var oa,pa; +(function(){function a(a){a=a.toString().match(e).slice(1);return{arguments:a[0],body:a[1],returnValue:a[2]}}var b={stackSave:function(){z.Tb()},stackRestore:function(){z.Sb()},arrayToC:function(a){var b=z.pb(a.length);qa(a,b);return b},stringToC:function(a){var b=0;a!==k&&(a!==g&&0!==a)&&(b=z.pb((a.length<<2)+1),ra(a,b));return b}},c={string:b.stringToC,array:b.arrayToC};pa=function(a,b,e,f){var h=na(a),s=[],a=0;if(f)for(var v=0;v>0]=b;break;case "i8":I[a>>0]=b;break;case "i16":J[a>>1]=b;break;case "i32":K[a>>2]=b;break;case "i64":ma=[b>>>0,(la=b,1<=+ta(la)?0>>0:~~+xa((la-+(~~la>>>0))/4294967296)>>>0:0)];K[a>>2]=ma[0];K[a+4>>2]=ma[1];break;case "float":ya[a>>2]=b;break;case "double":za[a>>3]=b;break;default:A("invalid type for setValue: "+c)}}p.setValue=sa; +function Aa(a,b){b=b||"i8";"*"===b.charAt(b.length-1)&&(b="i32");switch(b){case "i1":return I[a>>0];case "i8":return I[a>>0];case "i16":return J[a>>1];case "i32":return K[a>>2];case "i64":return K[a>>2];case "float":return ya[a>>2];case "double":return za[a>>3];default:A("invalid type for setValue: "+b)}return k}p.getValue=Aa;var L=2,Ba=4;p.ALLOC_NORMAL=0;p.ALLOC_STACK=1;p.ALLOC_STATIC=L;p.ALLOC_DYNAMIC=3;p.ALLOC_NONE=Ba; +function M(a,b,c,e){var f,h;"number"===typeof a?(f=i,h=a):(f=m,h=a.length);var j="string"===typeof b?b:k,c=c==Ba?e:[Ca,z.pb,z.Ec,z.bb][c===g?L:c](Math.max(h,j?1:b.length));if(f){e=c;w(0==(c&3));for(a=c+(h&-4);e>2]=0;for(a=c+h;e>0]=0;return c}if("i8"===j)return a.subarray||a.slice?N.set(a,c):N.set(new Uint8Array(a),c),c;for(var e=0,l,u;e>0];if(128<=e)c=i;else if(0==e&&!b)break;f++;if(b&&f==b)break}b||(b=f);var h="";if(!c){for(;0>0],h+=c.nb(e);return h}p.Pointer_stringify=ka;p.UTF16ToString=function(a){for(var b=0,c="";;){var e=J[a+2*b>>1];if(0==e)return c;++b;c+=String.fromCharCode(e)}}; +p.stringToUTF16=function(a,b){for(var c=0;c>1]=a.charCodeAt(c);J[b+2*a.length>>1]=0};p.UTF32ToString=function(a){for(var b=0,c="";;){var e=K[a+4*b>>2];if(0==e)return c;++b;65536<=e?(e-=65536,c+=String.fromCharCode(55296|e>>10,56320|e&1023)):c+=String.fromCharCode(e)}};p.stringToUTF32=function(a,b){for(var c=0,e=0;e=f)var h=a.charCodeAt(++e),f=65536+((f&1023)<<10)|h&1023;K[b+4*c>>2]=f;++c}K[b+4*c>>2]=0}; +function Da(a){function b(c,e,f){var e=e||Infinity,h="",j=[],s;if("N"===a[l]){l++;"K"===a[l]&&l++;for(s=[];"E"!==a[l];)if("S"===a[l]){l++;var C=a.indexOf("_",l);s.push(q[a.substring(l,C)||0]||"?");l=C+1}else if("C"===a[l])s.push(s[s.length-1]),l+=2;else{var C=parseInt(a.substr(l)),P=C.toString().length;if(!C||!P){l--;break}var sb=a.substr(l+P,C);s.push(sb);q.push(sb);l+=P+C}l++;s=s.join("::");e--;if(0===e)return c?[s]:s}else if(("K"===a[l]||x&&"L"===a[l])&&l++,C=parseInt(a.substr(l)))P=C.toString().length, +s=a.substr(l+P,C),l+=P+C;x=m;"I"===a[l]?(l++,C=b(i),P=b(i,1,i),h+=P[0]+" "+s+"<"+C.join(", ")+">"):h=s;a:for(;lO?2*O:O+16777216; +O!==F&&(p.fa("increasing TOTAL_MEMORY to "+O+" to be compliant with the asm.js spec"),F=O);w("undefined"!==typeof Int32Array&&"undefined"!==typeof Float64Array&&!!(new Int32Array(1)).subarray&&!!(new Int32Array(1)).set,"JS engine does not provide full typed array support");var Q=new ArrayBuffer(F);I=new Int8Array(Q);J=new Int16Array(Q);K=new Int32Array(Q);N=new Uint8Array(Q);Ga=new Uint16Array(Q);Ha=new Uint32Array(Q);ya=new Float32Array(Q);za=new Float64Array(Q);K[0]=255;w(255===N[0]&&0===N[3],"Typed arrays 2 must be run on a little-endian system"); +p.HEAP=g;p.buffer=Q;p.HEAP8=I;p.HEAP16=J;p.HEAP32=K;p.HEAPU8=N;p.HEAPU16=Ga;p.HEAPU32=Ha;p.HEAPF32=ya;p.HEAPF64=za;function Na(a){for(;0>0]=a[c],c+=1}p.writeStringToMemory=ra;function qa(a,b){for(var c=0;c>0]=a[c]}p.writeArrayToMemory=qa; +p.writeAsciiToMemory=function(a,b,c){for(var e=0;e>0]=a.charCodeAt(e);c||(I[b+a.length>>0]=0)};if(!Math.imul||-5!==Math.imul(4294967295,5))Math.imul=function(a,b){var c=a&65535,e=b&65535;return c*e+((a>>>16)*e+c*(b>>>16)<<16)|0};Math.vg=Math.imul;var ta=Math.abs,xa=Math.ceil,wa=Math.floor,va=Math.min,S=0,Wa=k,Xa=k;function Ya(){S++;p.monitorRunDependencies&&p.monitorRunDependencies(S)}p.addRunDependency=Ya; +function Za(){S--;p.monitorRunDependencies&&p.monitorRunDependencies(S);if(0==S&&(Wa!==k&&(clearInterval(Wa),Wa=k),Xa)){var a=Xa;Xa=k;a()}}p.removeRunDependency=Za;p.preloadedImages={};p.preloadedAudios={};var T=k,Ia=8,D=Ia+7808;R.push(); +M([0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,0,0,0,0,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,0,0,0,0,10,0,0,0,13,0,0,0,16,0,0,0,11,0,0,0,14,0,0,0,18,0,0,0,13,0,0,0,16,0,0,0,20,0,0,0,14,0,0,0,18,0,0,0,23,0,0,0,16,0,0,0,20,0,0,0,25,0,0,0,18,0,0,0,23,0,0,0,29,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0, +0,0,14,0,0,0,15,0,0,0,16,0,0,0,17,0,0,0,18,0,0,0,19,0,0,0,20,0,0,0,21,0,0,0,22,0,0,0,23,0,0,0,24,0,0,0,25,0,0,0,26,0,0,0,27,0,0,0,28,0,0,0,29,0,0,0,29,0,0,0,30,0,0,0,31,0,0,0,32,0,0,0,32,0,0,0,33,0,0,0,34,0,0,0,34,0,0,0,35,0,0,0,35,0,0,0,36,0,0,0,36,0,0,0,37,0,0,0,37,0,0,0,37,0,0,0,38,0,0,0,38,0,0,0,38,0,0,0,39,0,0,0,39,0,0,0,39,0,0,0,39,0,0,0,1,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,16,0,0,0,32,0,0,0,64,0,0,0,128,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,1,0,0,0,4,0,0, +0,5,0,0,0,2,0,0,0,3,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,12,0,0,0,13,0,0,0,10,0,0,0,11,0,0,0,14,0,0,0,15,0,0,0,47,31,15,0,23,27,29,30,7,11,13,14,39,43,45,46,16,3,5,10,12,19,21,26,28,35,37,42,44,1,2,4,8,17,18,20,24,6,9,22,25,32,33,34,36,40,38,41,0,16,1,2,4,8,32,3,5,10,12,15,47,7,11,13,14,6,9,31,35,37,42,44,33,34,36,40,39,43,45,46,17,18,20,24,19,21,26,28,23,27,29,30,22,25,38,41,17,1,0,0,0,0,0,0,34,18,1,1,0,0,0,0,50,34,18,2,0,0,0,0,67,51,34,34,18,18,2,2,83,67,51,35,18,18,2,2,19,35,67,51,99,83,2,2,0, +0,101,85,68,68,52,52,35,35,35,35,19,19,19,19,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,249,233,217,200,200,184,184,167,167,167,167,151,151,151,151,134,134,134,134,134,134,134,134,118,118,118,118,118,118,118,118,230,214,198,182,165,165,149,149,132,132,132,132,116,116,116,116,100,100,100,100,84,84,84,84,67,67,67,67,67,67,67,67,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,19,19,19,19,19,19,19,19,3,3,3,3,3,3,3,3,214,182,197,197,165,165,149,149,132,132,132,132,84,84,84,84,68,68,68,68,4,4,4,4,115,115,115,115, +115,115,115,115,99,99,99,99,99,99,99,99,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,19,19,19,19,19,19,19,19,197,181,165,5,148,148,116,116,52,52,36,36,131,131,131,131,99,99,99,99,83,83,83,83,67,67,67,67,19,19,19,19,181,149,164,164,132,132,36,36,20,20,4,4,115,115,115,115,99,99,99,99,83,83,83,83,67,67,67,67,51,51,51,51,166,6,21,21,132,132,132,132,147,147,147,147,147,147,147,147,115,115,115,115,115,115,115,115,99,99,99,99,99,99,99,99,83,83,83,83,83,83,83,83,67,67,67,67,67,67,67,67,51,51,51,51,51, +51,51,51,35,35,35,35,35,35,35,35,150,6,21,21,116,116,116,116,131,131,131,131,131,131,131,131,99,99,99,99,99,99,99,99,67,67,67,67,67,67,67,67,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,134,6,37,37,20,20,20,20,115,115,115,115,115,115,115,115,99,99,99,99,99,99,99,99,51,51,51,51,51,51,51,51,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,22,6,117,117,36,36,36,36,83,83,83,83,83,83,83,83,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,21,5,100,100,35,35,35,35,82,82,82,82,82,82,82,82,66,66,66,66,66,66,66,66,50,50,50,50,50,50,50,50,4,20,35,35,51,51,83,83,65,65,65,65,65,65,65,65,4,20,67,67,34,34,34,34,49,49,49,49,49,49,49,49,3,19,50,50,33,33,33,33,2,18,33,33,0,0,0,0,0,0,0,0,0,0,102,32,38,16,6,8,101,24,101,24,67,16,67,16,67,16,67,16,67,16,67,16,67,16,67,16,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34, +8,34,8,34,8,34,8,34,8,34,8,34,8,0,0,0,0,0,0,0,0,106,64,74,48,42,40,10,32,105,56,105,56,73,40,73,40,41,32,41,32,9,24,9,24,104,48,104,48,104,48,104,48,72,32,72,32,72,32,72,32,40,24,40,24,40,24,40,24,8,16,8,16,8,16,8,16,103,40,103,40,103,40,103,40,103,40,103,40,103,40,103,40,71,24,71,24,71,24,71,24,71,24,71,24,71,24,71,24,110,96,78,88,46,80,14,80,110,88,78,80,46,72,14,72,13,64,13,64,77,72,77,72,45,64,45,64,13,56,13,56,109,80,109,80,77,64,77,64,45,56,45,56,13,48,13,48,107,72,107,72,107,72,107,72,107, +72,107,72,107,72,107,72,75,56,75,56,75,56,75,56,75,56,75,56,75,56,75,56,43,48,43,48,43,48,43,48,43,48,43,48,43,48,43,48,11,40,11,40,11,40,11,40,11,40,11,40,11,40,11,40,0,0,0,0,47,104,47,104,16,128,80,128,48,128,16,120,112,128,80,120,48,120,16,112,112,120,80,112,48,112,16,104,111,112,111,112,79,104,79,104,47,96,47,96,15,96,15,96,111,104,111,104,79,96,79,96,47,88,47,88,15,88,15,88,0,0,0,0,0,0,0,0,102,56,70,32,38,32,6,16,102,48,70,24,38,24,6,8,101,40,101,40,37,16,37,16,100,32,100,32,100,32,100,32,100, +24,100,24,100,24,100,24,67,16,67,16,67,16,67,16,67,16,67,16,67,16,67,16,0,0,0,0,0,0,0,0,105,72,73,56,41,56,9,48,8,40,8,40,72,48,72,48,40,48,40,48,8,32,8,32,103,64,103,64,103,64,103,64,71,40,71,40,71,40,71,40,39,40,39,40,39,40,39,40,7,24,7,24,7,24,7,24,0,0,0,0,109,120,109,120,110,128,78,128,46,128,14,128,46,120,14,120,78,120,46,112,77,112,77,112,13,112,13,112,109,112,109,112,77,104,77,104,45,104,45,104,13,104,13,104,109,104,109,104,77,96,77,96,45,96,45,96,13,96,13,96,12,88,12,88,12,88,12,88,76,88, +76,88,76,88,76,88,44,88,44,88,44,88,44,88,12,80,12,80,12,80,12,80,108,96,108,96,108,96,108,96,76,80,76,80,76,80,76,80,44,80,44,80,44,80,44,80,12,72,12,72,12,72,12,72,107,88,107,88,107,88,107,88,107,88,107,88,107,88,107,88,75,72,75,72,75,72,75,72,75,72,75,72,75,72,75,72,43,72,43,72,43,72,43,72,43,72,43,72,43,72,43,72,11,64,11,64,11,64,11,64,11,64,11,64,11,64,11,64,107,80,107,80,107,80,107,80,107,80,107,80,107,80,107,80,75,64,75,64,75,64,75,64,75,64,75,64,75,64,75,64,43,64,43,64,43,64,43,64,43,64,43, +64,43,64,43,64,11,56,11,56,11,56,11,56,11,56,11,56,11,56,11,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,24,70,56,38,56,6,16,102,72,70,48,38,48,6,8,37,40,37,40,69,40,69,40,37,32,37,32,69,32,69,32,37,24,37,24,101,64,101,64,69,24,69,24,37,16,37,16,100,56,100,56,100,56,100,56,100,48,100,48,100,48,100,48,100,40,100,40,100,40,100,40,100,32,100,32,100,32,100,32,100,24,100,24,100,24,100,24,68,16,68,16,68,16,68,16,36,8,36,8,36,8,36,8,4,0,4,0,4,0,4,0,0,0,10,128,106,128,74,128,42,128,10,120,106,120,74,120,42,120,10, +112,106,112,74,112,42,112,10,104,41,104,41,104,9,96,9,96,73,104,73,104,41,96,41,96,9,88,9,88,105,104,105,104,73,96,73,96,41,88,41,88,9,80,9,80,104,96,104,96,104,96,104,96,72,88,72,88,72,88,72,88,40,80,40,80,40,80,40,80,8,72,8,72,8,72,8,72,104,88,104,88,104,88,104,88,72,80,72,80,72,80,72,80,40,72,40,72,40,72,40,72,8,64,8,64,8,64,8,64,7,56,7,56,7,56,7,56,7,56,7,56,7,56,7,56,7,48,7,48,7,48,7,48,7,48,7,48,7,48,7,48,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,7,40,7,40,7,40,7,40,7,40,7,40,7,40,7,40, +103,80,103,80,103,80,103,80,103,80,103,80,103,80,103,80,71,64,71,64,71,64,71,64,71,64,71,64,71,64,71,64,39,64,39,64,39,64,39,64,39,64,39,64,39,64,39,64,7,32,7,32,7,32,7,32,7,32,7,32,7,32,7,32,6,8,38,8,0,0,6,0,6,16,38,16,70,16,0,0,6,24,38,24,70,24,102,24,6,32,38,32,70,32,102,32,6,40,38,40,70,40,102,40,6,48,38,48,70,48,102,48,6,56,38,56,70,56,102,56,6,64,38,64,70,64,102,64,6,72,38,72,70,72,102,72,6,80,38,80,70,80,102,80,6,88,38,88,70,88,102,88,6,96,38,96,70,96,102,96,6,104,38,104,70,104,102,104,6,112, +38,112,70,112,102,112,6,120,38,120,70,120,102,120,6,128,38,128,70,128,102,128,0,0,67,16,2,0,2,0,33,8,33,8,33,8,33,8,103,32,103,32,72,32,40,32,71,24,71,24,39,24,39,24,6,32,6,32,6,32,6,32,6,24,6,24,6,24,6,24,6,16,6,16,6,16,6,16,102,24,102,24,102,24,102,24,38,16,38,16,38,16,38,16,6,8,6,8,6,8,6,8,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,3, +0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,3,0,0,0,19,0,0,0,1,0,0,0,18,0,0,0,0,0,0,0,17,0,0,0,4,0,0,0,16,0,0,0,3,0,0,0,23,0,0,0,1,0,0,0,22,0,0,0,0,0,0,0,21,0,0,0,4,0,0,0,20,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,4,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,12,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,4,0,0,0,13,0,0,0,255,0,0,0,8,0,0,0,1,0,0,0,19,0,0,0,2,0,0,0,18,0,0,0,4,0, +0,0,17,0,0,0,255,0,0,0,16,0,0,0,1,0,0,0,23,0,0,0,2,0,0,0,22,0,0,0,4,0,0,0,21,0,0,0,255,0,0,0,20,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,13,0,0,0,1,0,0,0,18,0,0,0,1,0,0,0,19,0,0,0,4,0,0,0,16,0,0,0,4,0,0,0,17,0,0,0,1,0,0,0,22,0,0,0,1,0,0,0,23,0,0,0,4,0,0,0,20,0,0,0,4,0,0,0,21,0,0,0,0, +0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,15,0,0,0,4,0,0,0,10,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,11,0,0,0,4,0,0,0,14,0,0,0,0,0,0,0,17,0,0,0,4,0,0,0,16,0,0,0,0,0,0,0,19,0,0,0,4,0,0,0,18,0,0,0,0,0,0,0,21,0,0,0,4,0,0,0,20,0,0,0,0,0,0,0,23,0,0,0,4,0,0,0,22,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,12,0,0,0,8,0,0,0,12,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0, +12,0,0,0,8,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,8,0,0,0,8,0,0,0,12,0,0,0,12,0,0,0,8,0,0,0,8,0,0,0,12,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108, +109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234, +235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,0,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,1,0,0,0,255,0, +0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,13,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0, +0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,4,0,0,0,2,0,0,0,10,0,0, +0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,2,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0, +0,0,4,0,0,0,9,0,0,0,255,0,0,0,12,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,4,0,0,0,13,0,0,0,255,0,0,0,8,0,0,0,1,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,4,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,255,0, +0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0, +0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,13,0,0,0,0,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0, +0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,13,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0, +0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,15,0,0,0,4,0,0,0,10,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,11,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,11,0,0,0,4,0,0,0,14,0,0, +0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0,0,0,14,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,5,6,7,8,9,10,12,13,15,17,20,22,25,28,32,36,40,45,50,56,63,71,80,90,101,113,127,144,162,182,203,226,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,3,4,4,4,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,1,0,0,1,0,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,1,1,2,1,1,2,1,2,3,1,2,3,2,2,3,2,2,4,2,3,4,2,3,4,3,3,5,3,4,6,3,4,6,4,5,7,4,5,8,4,6,9,5,7,10,6,8,11,6,8,13,7,10,14,8,11,16,9,12,18,10,13,20,11,15,23,13,17,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,69,67,79,68,69,82,32,73,78,73,84,73,65,76,73,90,65,84,73,79,78,32,70,65,73,76,69,68,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"i8",Ba,z.Pc);var $a=z.ub(M(12,"i8",L),8);w(0==$a%8); +var U={O:1,Q:2,Ef:3,De:4,ha:5,Zb:6,be:7,$e:8,V:9,oe:10,Ca:11,Of:11,Mc:12,qb:13,ye:14,mf:15,ga:16,Xb:17,Oc:18,Qa:19,Sa:20,pa:21,B:22,Ve:23,Lc:24,Nc:25,Lf:26,ze:27,hf:28,Ua:29,Bf:30,Oe:31,uf:32,ve:33,yf:34,df:42,Be:43,pe:44,Fe:45,Ge:46,He:47,Ne:48,Mf:49,Ye:50,Ee:51,te:35,af:37,ge:52,je:53,Pf:54,We:55,ke:56,le:57,ue:35,me:59,kf:60,Ze:61,If:62,jf:63,ef:64,ff:65,Af:66,bf:67,ee:68,Ff:69,qe:70,vf:71,Qe:72,we:73,ie:74,qf:76,he:77,zf:78,Ie:79,Je:80,Me:81,Le:82,Ke:83,lf:38,sb:39,Re:36,rb:40,Ta:95,tf:96,se:104, +Xe:105,fe:97,xf:91,of:88,gf:92,Cf:108,Wb:111,ce:98,re:103,Ue:101,Se:100,Jf:110,Ae:112,Yb:113,Jc:115,Hc:114,Ic:89,Pe:90,wf:93,Df:94,de:99,Te:102,Kc:106,Ra:107,Kf:109,Nf:87,xe:122,Gf:116,pf:95,cf:123,Ce:84,rf:75,ne:125,nf:131,sf:130,Hf:86},ab={"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"},bb=0;function V(a){return K[bb>>2]=a} +function cb(a,b){for(var c=0,e=a.length-1;0<=e;e--){var f=a[e];"."===f?a.splice(e,1):".."===f?(a.splice(e,1),c++):c&&(a.splice(e,1),c--)}if(b)for(;c--;c)a.unshift("..");return a}function db(a){var b="/"===a.charAt(0),c="/"===a.substr(-1),a=cb(a.split("/").filter(function(a){return!!a}),!b).join("/");!a&&!b&&(a=".");a&&c&&(a+="/");return(b?"/":"")+a} +function eb(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 W(a){if("/"===a)return"/";var b=a.lastIndexOf("/");return-1===b?a:a.substr(b+1)}function fb(){var a=Array.prototype.slice.call(arguments,0);return db(a.join("/"))}function X(a,b){return db(a+"/"+b)} +function gb(){for(var a="",b=m,c=arguments.length-1;-1<=c&&!b;c--){b=0<=c?arguments[c]:B.yb();"string"!==typeof b&&d(new TypeError("Arguments to path.resolve must be strings"));if(!b)return"";a=b+"/"+a;b="/"===b.charAt(0)}a=cb(a.split("/").filter(function(a){return!!a}),!b).join("/");return(b?"/":"")+a||"."} +function hb(a,b){function c(a){for(var b=0;bc?[]:a.slice(b,c-b+1)}for(var a=gb(a).substr(1),b=gb(b).substr(1),e=c(a.split("/")),f=c(b.split("/")),h=Math.min(e.length,f.length),j=h,l=0;la.k.length)&&(a.k=Y.ud(a),a.q=a.k.length);if(!a.k||a.k.subarray){var c=a.k?a.k.buffer.byteLength:0;c>=b||(b=Math.max(b,c*(1048576>c?2:1.125)|0),0!=c&&(b=Math.max(b,256)),c=a.k,a.k=new Uint8Array(b),0b)a.k.length=b;else for(;a.k.length=a.g.q)return 0;a=Math.min(a.g.q-f,e);w(0<=a);if(8b&&d(new B.e(U.B));return b},Ea:function(a,b,c){Y.lc(a.g,b+c);a.g.q=Math.max(a.g.q,b+c)},Ja:function(a,b,c,e,f,h,j){B.isFile(a.g.mode)||d(new B.e(U.Qa));c=a.g.k;if(!(j&2)&&(c.buffer===b||c.buffer=== +b.buffer))a=m,e=c.byteOffset;else{if(0>>0)%B.T.length},tc:function(a){var b=B.Fb(a.parent.id,a.name);a.ma=B.T[b];B.T[b]=a},uc:function(a){var b=B.Fb(a.parent.id,a.name);if(B.T[b]===a)B.T[b]=a.ma;else for(b=B.T[b];b;){if(b.ma===a){b.ma=a.ma;break}b=b.ma}},aa:function(a,b){var c=B.Gd(a);c&&d(new B.e(c,a));for(c=B.T[B.Fb(a.id,b)];c;c=c.ma){var e=c.name;if(c.parent.id===a.id&&e===b)return c}return B.ra(a,b)},createNode:function(a,b,c,e){B.Va||(B.Va=function(a,b,c,e){a|| +(a=this);this.parent=a;this.F=a.F;this.Ka=k;this.id=B.Jd++;this.name=b;this.mode=c;this.n={};this.p={};this.ob=e},B.Va.prototype={},Object.defineProperties(B.Va.prototype,{M:{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}},Dd:{get:function(){return B.J(this.mode)}},Gb:{get:function(){return B.ib(this.mode)}}}));a=new B.Va(a,b,c,e);B.tc(a);return a}, +zb:function(a){B.uc(a)},jb:function(a){return a===a.parent},ka:function(a){return!!a.Ka},isFile:function(a){return 32768===(a&61440)},J:function(a){return 16384===(a&61440)},Ia:function(a){return 40960===(a&61440)},ib:function(a){return 8192===(a&61440)},Bd:function(a){return 24576===(a&61440)},Cd:function(a){return 4096===(a&61440)},Ed:function(a){return 49152===(a&49152)},rd:{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}, +wc:function(a){var b=B.rd[a];"undefined"===typeof b&&d(Error("Unknown file open mode: "+a));return b},sd:function(a){var b=["r","w","rw"][a&2097155];a&512&&(b+="w");return b},na:function(a,b){return B.vc?0:-1!==b.indexOf("r")&&!(a.mode&292)||-1!==b.indexOf("w")&&!(a.mode&146)||-1!==b.indexOf("x")&&!(a.mode&73)?U.qb:0},Gd:function(a){var b=B.na(a,"x");return b?b:!a.n.ra?U.qb:0},Jb:function(a,b){try{return B.aa(a,b),U.Xb}catch(c){}return B.na(a,"wx")},kb:function(a,b,c){var e;try{e=B.aa(a,b)}catch(f){return f.cb}if(a= +B.na(a,"wx"))return a;if(c){if(!B.J(e.mode))return U.Sa;if(B.jb(e)||B.da(e)===B.yb())return U.ga}else if(B.J(e.mode))return U.pa;return 0},Hd:function(a,b){return!a?U.Q:B.Ia(a.mode)?U.rb:B.J(a.mode)&&(0!==(b&2097155)||b&512)?U.pa:B.na(a,B.sd(b))},Qc:4096,Kd:function(a,b){for(var b=b||B.Qc,c=a||0;c<=b;c++)if(!B.oa[c])return c;d(new B.e(U.Lc))},qa:function(a){return B.oa[a]},fc:function(a,b,c){B.Wa||(B.Wa=n(),B.Wa.prototype={},Object.defineProperties(B.Wa.prototype,{object:{get:function(){return this.g}, +set:function(a){this.g=a}},yg:{get:function(){return 1!==(this.D&2097155)}},zg:{get:function(){return 0!==(this.D&2097155)}},xg:{get:function(){return this.D&1024}}}));var e=new B.Wa,f;for(f in a)e[f]=a[f];a=e;b=B.Kd(b,c);a.C=b;return B.oa[b]=a},dd:function(a){B.oa[a]=k},pc:function(a){return B.oa[a-1]},Eb:function(a){return a?a.C+1:0},bd:{open:function(a){a.p=B.td(a.g.ob).p;a.p.open&&a.p.open(a)},$:function(){d(new B.e(U.Ua))}},Ib:function(a){return a>>8},Gg:function(a){return a&255},la:function(a, +b){return a<<8|b},Ob:function(a,b){B.ic[a]={p:b}},td:function(a){return B.ic[a]},nc:function(a){for(var b=[],a=[a];a.length;){var c=a.pop();b.push(c);a.push.apply(a,c.La)}return b},Fc:function(a,b){function c(a){if(a){if(!c.pd)return c.pd=i,b(a)}else++f>=e.length&&b(k)}"function"===typeof a&&(b=a,a=m);var e=B.nc(B.root.F),f=0;e.forEach(function(b){if(!b.type.Fc)return c(k);b.type.Fc(b,a,c)})},F:function(a,b,c){var e="/"===c,f=!c,h;e&&B.root&&d(new B.e(U.ga));!e&&!f&&(h=B.u(c,{Bb:m}),c=h.path,h=h.g, +B.ka(h)&&d(new B.e(U.ga)),B.J(h.mode)||d(new B.e(U.Sa)));b={type:a,Kg:b,Id:c,La:[]};a=a.F(b);a.F=b;b.root=a;e?B.root=a:h&&(h.Ka=b,h.F&&h.F.La.push(b));return a},Qg:function(a){a=B.u(a,{Bb:m});B.ka(a.g)||d(new B.e(U.B));var a=a.g,b=a.Ka,c=B.nc(b);Object.keys(B.T).forEach(function(a){for(a=B.T[a];a;){var b=a.ma;-1!==c.indexOf(a.F)&&B.zb(a);a=b}});a.Ka=k;b=a.F.La.indexOf(b);w(-1!==b);a.F.La.splice(b,1)},ra:function(a,b){return a.n.ra(a,b)},ba:function(a,b,c){var e=B.u(a,{parent:i}).g,a=W(a);(!a||"."=== +a||".."===a)&&d(new B.e(U.B));var f=B.Jb(e,a);f&&d(new B.e(f));e.n.ba||d(new B.e(U.O));return e.n.ba(e,a,b,c)},create:function(a,b){b=(b!==g?b:438)&4095;b|=32768;return B.ba(a,b,0)},ea:function(a,b){b=(b!==g?b:511)&1023;b|=16384;return B.ba(a,b,0)},lb:function(a,b,c){"undefined"===typeof c&&(c=b,b=438);return B.ba(a,b|8192,c)},ca:function(a,b){gb(a)||d(new B.e(U.Q));var c=B.u(b,{parent:i}).g;c||d(new B.e(U.Q));var e=W(b),f=B.Jb(c,e);f&&d(new B.e(f));c.n.ca||d(new B.e(U.O));return c.n.ca(c,e,a)},rename:function(a, +b){var c=eb(a),e=eb(b),f=W(a),h=W(b),j,l,u;try{j=B.u(a,{parent:i}),l=j.g,j=B.u(b,{parent:i}),u=j.g}catch(q){d(new B.e(U.ga))}(!l||!u)&&d(new B.e(U.Q));l.F!==u.F&&d(new B.e(U.Oc));j=B.aa(l,f);e=hb(a,e);"."!==e.charAt(0)&&d(new B.e(U.B));e=hb(b,c);"."!==e.charAt(0)&&d(new B.e(U.sb));var x;try{x=B.aa(u,h)}catch(s){}if(j!==x){c=B.J(j.mode);(f=B.kb(l,f,c))&&d(new B.e(f));(f=x?B.kb(u,h,c):B.Jb(u,h))&&d(new B.e(f));l.n.rename||d(new B.e(U.O));(B.ka(j)||x&&B.ka(x))&&d(new B.e(U.ga));u!==l&&(f=B.na(l,"w"))&& +d(new B.e(f));try{B.H.willMovePath&&B.H.willMovePath(a,b)}catch(v){console.log("FS.trackingDelegate['willMovePath']('"+a+"', '"+b+"') threw an exception: "+v.message)}B.uc(j);try{l.n.rename(j,u,h)}catch(G){d(G)}finally{B.tc(j)}try{if(B.H.onMovePath)B.H.onMovePath(a,b)}catch(ua){console.log("FS.trackingDelegate['onMovePath']('"+a+"', '"+b+"') threw an exception: "+ua.message)}}},Oa:function(a){var b=B.u(a,{parent:i}).g,c=W(a),e=B.aa(b,c),f=B.kb(b,c,i);f&&d(new B.e(f));b.n.Oa||d(new B.e(U.O));B.ka(e)&& +d(new B.e(U.ga));try{B.H.willDeletePath&&B.H.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.n.Oa(b,c);B.zb(e);try{if(B.H.onDeletePath)B.H.onDeletePath(a)}catch(j){console.log("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+j.message)}},Na:function(a){a=B.u(a,{R:i}).g;a.n.Na||d(new B.e(U.Sa));return a.n.Na(a)},za:function(a){var b=B.u(a,{parent:i}).g,c=W(a),e=B.aa(b,c),f=B.kb(b,c,m);f&&(f===U.pa&&(f=U.O), +d(new B.e(f)));b.n.za||d(new B.e(U.O));B.ka(e)&&d(new B.e(U.ga));try{B.H.willDeletePath&&B.H.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.n.za(b,c);B.zb(e);try{if(B.H.onDeletePath)B.H.onDeletePath(a)}catch(j){console.log("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+j.message)}},ta:function(a){(a=B.u(a).g)||d(new B.e(U.Q));a.n.ta||d(new B.e(U.B));return a.n.ta(a)},Dc:function(a,b){var c=B.u(a,{R:!b}).g; +c||d(new B.e(U.Q));c.n.S||d(new B.e(U.O));return c.n.S(c)},Eg:function(a){return B.Dc(a,i)},Ya:function(a,b,c){a="string"===typeof a?B.u(a,{R:!c}).g:a;a.n.I||d(new B.e(U.O));a.n.I(a,{mode:b&4095|a.mode&-4096,timestamp:Date.now()})},Bg:function(a,b){B.Ya(a,b,i)},jg:function(a,b){var c=B.qa(a);c||d(new B.e(U.V));B.Ya(c.g,b)},dc:function(a,b,c,e){a="string"===typeof a?B.u(a,{R:!e}).g:a;a.n.I||d(new B.e(U.O));a.n.I(a,{timestamp:Date.now()})},Cg:function(a,b,c){B.dc(a,b,c,i)},kg:function(a,b,c){(a=B.qa(a))|| +d(new B.e(U.V));B.dc(a.g,b,c)},truncate:function(a,b){0>b&&d(new B.e(U.B));var c;c="string"===typeof a?B.u(a,{R:i}).g:a;c.n.I||d(new B.e(U.O));B.J(c.mode)&&d(new B.e(U.pa));B.isFile(c.mode)||d(new B.e(U.B));var e=B.na(c,"w");e&&d(new B.e(e));c.n.I(c,{size:b,timestamp:Date.now()})},mg:function(a,b){var c=B.qa(a);c||d(new B.e(U.V));0===(c.D&2097155)&&d(new B.e(U.B));B.truncate(c.g,b)},Rg:function(a,b,c){a=B.u(a,{R:i}).g;a.n.I(a,{timestamp:Math.max(b,c)})},open:function(a,b,c,e,f){""===a&&d(new B.e(U.Q)); +var b="string"===typeof b?B.wc(b):b,c=b&64?("undefined"===typeof c?438:c)&4095|32768:0,h;if("object"===typeof a)h=a;else{a=db(a);try{h=B.u(a,{R:!(b&131072)}).g}catch(j){}}var l=m;b&64&&(h?b&128&&d(new B.e(U.Xb)):(h=B.ba(a,c,0),l=i));h||d(new B.e(U.Q));B.ib(h.mode)&&(b&=-513);l||(c=B.Hd(h,b))&&d(new B.e(c));b&512&&B.truncate(h,0);b&=-641;e=B.fc({g:h,path:B.da(h),D:b,seekable:i,position:0,p:h.p,$d:[],error:m},e,f);e.p.open&&e.p.open(e);p.logReadFiles&&!(b&1)&&(B.Mb||(B.Mb={}),a in B.Mb||(B.Mb[a]=1, +p.printErr("read file: "+a)));try{B.H.onOpenFile&&(f=0,1!==(b&2097155)&&(f|=B.Gc.yc.Rc),0!==(b&2097155)&&(f|=B.Gc.yc.Sc),B.H.onOpenFile(a,f))}catch(u){console.log("FS.trackingDelegate['onOpenFile']('"+a+"', flags) threw an exception: "+u.message)}return e},close:function(a){try{a.p.close&&a.p.close(a)}catch(b){d(b)}finally{B.dd(a.C)}},$:function(a,b,c){(!a.seekable||!a.p.$)&&d(new B.e(U.Ua));a.position=a.p.$(a,b,c);a.$d=[];return a.position},M:function(a,b,c,e,f){(0>e||0>f)&&d(new B.e(U.B));1===(a.D& +2097155)&&d(new B.e(U.V));B.J(a.g.mode)&&d(new B.e(U.pa));a.p.M||d(new B.e(U.B));var h=i;"undefined"===typeof f?(f=a.position,h=m):a.seekable||d(new B.e(U.Ua));b=a.p.M(a,b,c,e,f);h||(a.position+=b);return b},write:function(a,b,c,e,f,h){(0>e||0>f)&&d(new B.e(U.B));0===(a.D&2097155)&&d(new B.e(U.V));B.J(a.g.mode)&&d(new B.e(U.pa));a.p.write||d(new B.e(U.B));a.D&1024&&B.$(a,0,2);var j=i;"undefined"===typeof f?(f=a.position,j=m):a.seekable||d(new B.e(U.Ua));b=a.p.write(a,b,c,e,f,h);j||(a.position+=b); +try{if(a.path&&B.H.onWriteToFile)B.H.onWriteToFile(a.path)}catch(l){console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: "+l.message)}return b},Ea:function(a,b,c){(0>b||0>=c)&&d(new B.e(U.B));0===(a.D&2097155)&&d(new B.e(U.V));!B.isFile(a.g.mode)&&!B.J(node.mode)&&d(new B.e(U.Qa));a.p.Ea||d(new B.e(U.Ta));a.p.Ea(a,b,c)},Ja:function(a,b,c,e,f,h,j){1===(a.D&2097155)&&d(new B.e(U.qb));a.p.Ja||d(new B.e(U.Qa));return a.p.Ja(a,b,c,e,f,h,j)},Ha:function(a,b,c){a.p.Ha||d(new B.e(U.Nc)); +return a.p.Ha(a,b,c)},Mg:function(a,b){b=b||{};b.D=b.D||"r";b.encoding=b.encoding||"binary";"utf8"!==b.encoding&&"binary"!==b.encoding&&d(Error('Invalid encoding type "'+b.encoding+'"'));var c,e=B.open(a,b.D),f=B.Dc(a).size,h=new Uint8Array(f);B.M(e,h,0,f,0);if("utf8"===b.encoding){c="";for(var j=new z.Da,l=0;l>2]=B.Eb(a);w(0===a.C,"invalid handle for stdin ("+a.C+")");a=B.open("/dev/stdout","w");K[pb>>2]=B.Eb(a);w(1===a.C,"invalid handle for stdout ("+a.C+")");a=B.open("/dev/stderr","w");K[qb>>2]=B.Eb(a);w(2===a.C,"invalid handle for stderr ("+a.C+")")},jc:function(){B.e||(B.e=function(a,b){this.g=b;this.Xd=function(a){this.cb=a;for(var b in U)if(U[b]=== +a){this.code=b;break}};this.Xd(a);this.message=ab[a]},B.e.prototype=Error(),[U.Q].forEach(function(a){B.Db[a]=new B.e(a);B.Db[a].stack=""}))},Zd:function(){B.jc();B.T=Array(4096);B.F(Y,{},"/");B.fd();B.ed()},Ga:function(a,b,c){w(!B.Ga.hb,"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)");B.Ga.hb=i;B.jc();p.stdin=a||p.stdin;p.stdout=b||p.stdout;p.stderr= +c||p.stderr;B.od()},Qd:function(){B.Ga.hb=m;for(var a=0;athis.length-1||0>a)){var b=a%this.cd;return this.yd(a/ +this.cd|0)[b]}};h.prototype.Wd=function(a){this.yd=a};h.prototype.bc=function(){var a=new XMLHttpRequest;a.open("HEAD",c,m);a.send(k);200<=a.status&&300>a.status||304===a.status||d(Error("Couldn't load "+c+". Status: "+a.status));var b=Number(a.getResponseHeader("Content-length")),e,f=1048576;if(!((e=a.getResponseHeader("Accept-Ranges"))&&"bytes"===e))f=b;var h=this;h.Wd(function(a){var e=a*f,j=(a+1)*f-1,j=Math.min(j,b-1);if("undefined"===typeof h.Za[a]){var l=h.Za;e>j&&d(Error("invalid range ("+ +e+", "+j+") or no bytes requested!"));j>b-1&&d(Error("only "+b+" bytes available! programmer error!"));var q=new XMLHttpRequest;q.open("GET",c,m);b!==f&&q.setRequestHeader("Range","bytes="+e+"-"+j);"undefined"!=typeof Uint8Array&&(q.responseType="arraybuffer");q.overrideMimeType&&q.overrideMimeType("text/plain; charset=x-user-defined");q.send(k);200<=q.status&&300>q.status||304===q.status||d(Error("Couldn't load "+c+". Status: "+q.status));e=q.response!==g?new Uint8Array(q.response||[]):Va(q.responseText|| +"",i);l[a]=e}"undefined"===typeof h.Za[a]&&d(Error("doXHR failed!"));return h.Za[a]});this.Uc=b;this.Tc=f;this.Hb=i};if("undefined"!==typeof XMLHttpRequest){ca||d("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc");var j=new h;Object.defineProperty(j,"length",{get:function(){this.Hb||this.bc();return this.Uc}});Object.defineProperty(j,"chunkSize",{get:function(){this.Hb||this.bc();return this.Tc}});j={Gb:m,k:j}}else j={Gb:m,url:c}; +var l=B.gd(a,b,j,e,f);j.k?l.k=j.k:j.url&&(l.k=k,l.url=j.url);Object.defineProperty(l,"usedBytes",{get:function(){return this.k.length}});var u={};Object.keys(l.p).forEach(function(a){var b=l.p[a];u[a]=function(){B.mc(l)||d(new B.e(U.ha));return b.apply(k,arguments)}});u.M=function(a,b,c,e,f){B.mc(l)||d(new B.e(U.ha));a=a.g.k;if(f>=a.length)return 0;e=Math.min(a.length-f,e);w(0<=e);if(a.slice)for(var h=0;h>h-6&63,h=h-6,c=c+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[q]}2==h?(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&3)<<4],c+="=="):4==h&&(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&15)<<2],c+="="); +s.src="data:audio/x-"+b.substr(-3)+";base64,"+c;f(s)}};s.src=l;p.noExitRuntime=i;setTimeout(function(){H||f(s)},1E4)}else return h()}});var v=p.canvas;v&&(v.Pb=v.requestPointerLock||v.mozRequestPointerLock||v.webkitRequestPointerLock||v.msRequestPointerLock||n(),v.kc=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock||document.msExitPointerLock||n(),v.kc=v.kc.bind(document),document.addEventListener("pointerlockchange",q,m),document.addEventListener("mozpointerlockchange", +q,m),document.addEventListener("webkitpointerlockchange",q,m),document.addEventListener("mspointerlockchange",q,m),p.elementPointerLock&&v.addEventListener("click",function(a){!rb&&v.Pb&&(v.Pb(),a.preventDefault())},m))}var G=b?gb(X(a,b)):a;Ya();"string"==typeof c?yb(c,function(a){x(a)},j):x(c)},indexedDB:function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},Ub:function(){return"EM_FS_"+window.location.pathname},Vb:20,Ba:"FILE_DATA",Og:function(a,b,c){var b= +b||n(),c=c||n(),e=B.indexedDB();try{var f=e.open(B.Ub(),B.Vb)}catch(h){return c(h)}f.Ld=function(){console.log("creating db");f.result.createObjectStore(B.Ba)};f.onsuccess=function(){var e=f.result.transaction([B.Ba],"readwrite"),h=e.objectStore(B.Ba),u=0,q=0,x=a.length;a.forEach(function(a){a=h.put(B.vb(a).object.k,a);a.onsuccess=function(){u++;u+q==x&&(0==q?b():c())};a.onerror=function(){q++;u+q==x&&(0==q?b():c())}});e.onerror=c};f.onerror=c},Dg:function(a,b,c){var b=b||n(),c=c||n(),e=B.indexedDB(); +try{var f=e.open(B.Ub(),B.Vb)}catch(h){return c(h)}f.Ld=c;f.onsuccess=function(){var e=f.result;try{var h=e.transaction([B.Ba],"readonly")}catch(u){c(u);return}var q=h.objectStore(B.Ba),x=0,s=0,v=a.length;a.forEach(function(a){var e=q.get(a);e.onsuccess=function(){B.vb(a).Ab&&B.za(a);B.xb(eb(a),W(a),e.result,i,i,i);x++;x+s==v&&(0==s?b():c())};e.onerror=function(){s++;x+s==v&&(0==s?b():c())}});h.onerror=c};f.onerror=c}};function zb(){d("TODO")} +var Z={F:function(){p.websocket=p.websocket&&"object"===typeof p.websocket?p.websocket:{};p.websocket.tb={};p.websocket.on=function(a,b){"function"===typeof b&&(this.tb[a]=b);return this};p.websocket.P=function(a,b){"function"===typeof this.tb[a]&&this.tb[a].call(this,b)};return B.createNode(k,"/",16895,0)},nd:function(a,b,c){c&&w(1==b==(6==c));a={qd:a,type:b,protocol:c,G:k,error:k,Ma:{},Kb:[],ua:[],wa:Z.L};b=Z.mb();c=B.createNode(Z.root,b,49152,0);c.va=a;b=B.fc({path:b,g:c,D:B.wc("r+"),seekable:m, +p:Z.p});a.A=b;return a},wd:function(a){a=B.qa(a);return!a||!B.Ed(a.g.mode)?k:a.g.va},p:{zc:function(a){a=a.g.va;return a.wa.zc(a)},Ha:function(a,b,c){a=a.g.va;return a.wa.Ha(a,b,c)},M:function(a,b,c,e){a=a.g.va;e=a.wa.Rd(a,e);if(!e)return 0;b.set(e.buffer,c);return e.buffer.length},write:function(a,b,c,e){a=a.g.va;return a.wa.Vd(a,b,c,e)},close:function(a){a=a.g.va;a.wa.close(a)}},mb:function(){Z.mb.gc||(Z.mb.gc=0);return"socket["+Z.mb.gc++ +"]"},L:{$a:function(a,b,c){var e;"object"===typeof b&&(e= +b,c=b=k);if(e)e._socket?(b=e._socket.remoteAddress,c=e._socket.remotePort):((c=/ws[s]?:\/\/([^:]+):(\d+)/.exec(e.url))||d(Error("WebSocket URL must be in the format ws(s)://address:port")),b=c[1],c=parseInt(c[2],10));else try{var f=p.websocket&&"object"===typeof p.websocket,h="ws:#".replace("#","//");f&&"string"===typeof p.websocket.url&&(h=p.websocket.url);if("ws://"===h||"wss://"===h)var j=b.split("/"),h=h+j[0]+":"+c+"/"+j.slice(1).join("/");j="binary";f&&"string"===typeof p.websocket.subprotocol&& +(j=p.websocket.subprotocol);var j=j.replace(/^ +| +$/g,"").split(/ *, */),l=t?{protocol:j.toString()}:j;e=new (t?(null)("ws"):window.WebSocket)(h,l);e.binaryType="arraybuffer"}catch(u){d(new B.e(U.Yb))}b={W:b,port:c,o:e,ab:[]};Z.L.$b(a,b);Z.L.zd(a,b);2===a.type&&"undefined"!==typeof a.ya&&b.ab.push(new Uint8Array([255,255,255,255,112,111,114,116,(a.ya&65280)>>8,a.ya&255]));return b},gb:function(a,b,c){return a.Ma[b+":"+c]},$b:function(a,b){a.Ma[b.W+":"+b.port]=b},Bc:function(a,b){delete a.Ma[b.W+ +":"+b.port]},zd:function(a,b){function c(){p.websocket.P("open",a.A.C);try{for(var c=b.ab.shift();c;)b.o.send(c),c=b.ab.shift()}catch(e){b.o.close()}}function e(c){w("string"!==typeof c&&c.byteLength!==g);var c=new Uint8Array(c),e=f;f=m;e&&10===c.length&&255===c[0]&&255===c[1]&&255===c[2]&&255===c[3]&&112===c[4]&&111===c[5]&&114===c[6]&&116===c[7]?(c=c[8]<<8|c[9],Z.L.Bc(a,b),b.port=c,Z.L.$b(a,b)):(a.ua.push({W:b.W,port:b.port,data:c}),p.websocket.P("message",a.A.C))}var f=i;t?(b.o.on("open",c),b.o.on("message", +function(a,b){b.binary&&e((new Uint8Array(a)).buffer)}),b.o.on("close",function(){p.websocket.P("close",a.A.C)}),b.o.on("error",function(){a.error=U.Wb;p.websocket.P("error",[a.A.C,a.error,"ECONNREFUSED: Connection refused"])})):(b.o.onopen=c,b.o.onclose=function(){p.websocket.P("close",a.A.C)},b.o.onmessage=function(a){e(a.data)},b.o.onerror=function(){a.error=U.Wb;p.websocket.P("error",[a.A.C,a.error,"ECONNREFUSED: Connection refused"])})},zc:function(a){if(1===a.type&&a.G)return a.Kb.length?65: +0;var b=0,c=1===a.type?Z.L.gb(a,a.Y,a.Z):k;if(a.ua.length||!c||c&&c.o.readyState===c.o.Pa||c&&c.o.readyState===c.o.CLOSED)b|=65;if(!c||c&&c.o.readyState===c.o.OPEN)b|=4;if(c&&c.o.readyState===c.o.Pa||c&&c.o.readyState===c.o.CLOSED)b|=16;return b},Ha:function(a,b,c){switch(b){case 21531:return b=0,a.ua.length&&(b=a.ua[0].data.length),K[c>>2]=b,0;default:return U.B}},close:function(a){if(a.G){try{a.G.close()}catch(b){}a.G=k}for(var c=Object.keys(a.Ma),e=0;e>0]=c;if(-1==Ab(Cb(b),Eb.Cc,1)){if(c=B.pc(b))c.error=i;return-1}return c}function Fb(a){Fb.$c||(E=E+4095&-4096,Fb.$c=i,w(z.bb),Fb.Wc=z.bb,z.bb=function(){A("cannot dynamically allocate, sbrk now has control")});var b=E;0!=a&&Fb.Wc(a);return b}p._memset=Gb;function Hb(a,b,c){window._broadwayOnPictureDecoded(a,b,c)}p._broadwayOnPictureDecoded=Hb;function Ib(){window._broadwayOnHeadersDecoded()}p._broadwayOnHeadersDecoded=Ib; +function Jb(a,b){Kb=a;Lb=b;if(!Mb)return 1;0==a?(Nb=function(){setTimeout(Ob,b)},Pb="timeout"):1==a&&(Nb=function(){Qb(Ob)},Pb="rAF");return 0} +function Rb(a,b,c,e){p.noExitRuntime=i;w(!Mb,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");Mb=a;Sb=e;var f=Tb;Ob=function(){if(!H)if(0=bc;)bc+=1E3/60;b=Math.max(bc-b,0);setTimeout(a,b)}function Qb(a){"undefined"===typeof window?cc(a):(window.requestAnimationFrame||(window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||cc),window.requestAnimationFrame(a))} +function xb(a){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",bmp:"image/bmp",ogg:"audio/ogg",wav:"audio/wav",mp3:"audio/mpeg"}[a.substr(a.lastIndexOf(".")+1)]} +function yb(a,b,c){function e(){c?c():d('Loading data file "'+a+'" failed.')}var f=new XMLHttpRequest;f.open("GET",a,i);f.responseType="arraybuffer";f.onload=function(){if(200==f.status||0==f.status&&f.response){var c=f.response;w(c,'Loading data file "'+a+'" failed (no arrayBuffer).');b(new Uint8Array(c));Za()}else e()};f.onerror=e;f.send(k);Ya()}var dc=[];function ec(){var a=p.canvas;dc.forEach(function(b){b(a.width,a.height)})} +function fc(a,b,c){b&&c?(a.ae=b,a.Ad=c):(b=a.ae,c=a.Ad);var e=b,f=c;p.forcedAspectRatio&&0>2]=0;R.unshift({ja:n()});Qa.push({ja:n()});var lb=new z.Da;t&&((null)("fs"),process.platform.match(/^win/));R.push({ja:function(){Z.root=B.F(Z,{},k)}}); +Eb.Cc=M([0],"i8",L); +p.requestFullScreen=function(a,b){function c(){Yb=m;var a=e.parentNode;(document.webkitFullScreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.mozFullscreenElement||document.fullScreenElement||document.fullscreenElement||document.msFullScreenElement||document.msFullscreenElement||document.webkitCurrentFullScreenElement)===a?(e.cc=document.cancelFullScreen||document.mozCancelFullScreen||document.webkitCancelFullScreen||document.msExitFullscreen||document.exitFullscreen|| +n(),e.cc=e.cc.bind(document),$b&&e.Pb(),Yb=i,ac&&("undefined"!=typeof SDL&&(a=Ha[SDL.screen+0*z.ia>>2],K[SDL.screen+0*z.ia>>2]=a|8388608),ec())):(a.parentNode.insertBefore(e,a),a.parentNode.removeChild(a),ac&&("undefined"!=typeof SDL&&(a=Ha[SDL.screen+0*z.ia>>2],K[SDL.screen+0*z.ia>>2]=a&-8388609),ec()));if(p.onFullScreen)p.onFullScreen(Yb);fc(e)}$b=a;ac=b;"undefined"===typeof $b&&($b=i);"undefined"===typeof ac&&(ac=m);var e=p.canvas;Zb||(Zb=i,document.addEventListener("fullscreenchange",c,m),document.addEventListener("mozfullscreenchange", +c,m),document.addEventListener("webkitfullscreenchange",c,m),document.addEventListener("MSFullscreenChange",c,m));var f=document.createElement("div");e.parentNode.insertBefore(f,e);f.appendChild(e);f.Td=f.requestFullScreen||f.mozRequestFullScreen||f.msRequestFullscreen||(f.webkitRequestFullScreen?function(){f.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}:k);f.Td()};p.requestAnimationFrame=function(a){Qb(a)};p.setCanvasSize=function(a,b,c){fc(p.canvas,a,b);c||ec()}; +p.pauseMainLoop=function(){Nb=k;Tb++};p.resumeMainLoop=function(){Tb++;var a=Kb,b=Lb,c=Mb;Mb=k;Rb(c,0,m,Sb);Jb(a,b)};p.getUserMedia=function(){window.qc||(window.qc=navigator.getUserMedia||navigator.mozGetUserMedia);window.qc(g)};Ja=y=z.ub(D);Ka=Ja+Ma;La=E=z.ub(Ka);w(La>2],a=Db(a,b);return 0>a?a:0>Eb(10,b)?-1:a+1},_fflush:n(),_fputc:Eb,_send:function(a,b,c){return!Z.wd(a)?(V(U.V),-1):Ab(a,b,c)},_pwrite:function(a,b,c,e){a=B.qa(a);if(!a)return V(U.V),-1;try{return B.write(a,I,b,c,e)}catch(f){return B.sc(f),-1}},_fputs:Db,_emscripten_set_main_loop:Rb, +_abort:function(){p.abort()},___setErrNo:V,_sbrk:Fb,_mkport:zb,_emscripten_set_main_loop_timing:Jb,_emscripten_memcpy_big:function(a,b,c){N.set(N.subarray(b,b+c),a);return a},_fileno:Cb,_broadwayOnHeadersDecoded:Ib,_write:Ab,_time:function(a){var b=Date.now()/1E3|0;a&&(K[a>>2]=b);return b},_sysconf:function(a){switch(a){case 30:return 4096;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 79:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809; +case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32; +case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1E3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:return"object"===typeof navigator?navigator.hardwareConcurrency||1:1}V(U.B);return-1}, +___errno_location:function(){return bb},STACKTOP:y,STACK_MAX:Ka,tempDoublePtr:$a,ABORT:H,NaN:NaN,Infinity:Infinity};// EMSCRIPTEN_START_ASM +var $=(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.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=0;var n=0;var o=0;var p=0;var q=+env.NaN,r=+env.Infinity;var s=0,t=0,u=0,v=0,w=0.0,x=0,y=0,z=0,A=0.0;var B=0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=global.Math.floor;var M=global.Math.abs;var N=global.Math.sqrt;var O=global.Math.pow;var P=global.Math.cos;var Q=global.Math.sin;var R=global.Math.tan;var S=global.Math.acos;var T=global.Math.asin;var U=global.Math.atan;var V=global.Math.atan2;var W=global.Math.exp;var X=global.Math.log;var Y=global.Math.ceil;var Z=global.Math.imul;var _=env.abort;var $=env.assert;var aa=env.min;var ba=env.invoke_viiiii;var ca=env._broadwayOnPictureDecoded;var da=env._puts;var ea=env._fflush;var fa=env._fputc;var ga=env._send;var ha=env._pwrite;var ia=env._fputs;var ja=env._emscripten_set_main_loop;var ka=env._abort;var la=env.___setErrNo;var ma=env._sbrk;var na=env._mkport;var oa=env._emscripten_set_main_loop_timing;var pa=env._emscripten_memcpy_big;var qa=env._fileno;var ra=env._broadwayOnHeadersDecoded;var sa=env._write;var ta=env._time;var ua=env._sysconf;var va=env.___errno_location;var wa=0.0; +// EMSCRIPTEN_START_FUNCS +function Sb(a,f,g,h,j,k){a=a|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var 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,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;X=i;i=i+32|0;W=X;p=c[j+4>>2]|0;V=(h>>>0)/(p>>>0)|0;U=V<<4;V=h-(Z(V,p)|0)<<4;c[W+4>>2]=p;c[W+8>>2]=c[j+8>>2];p=c[a>>2]|0;do if((p|0)==1|(p|0)==0){A=c[f+144>>2]|0;l=a+4|0;n=c[a+200>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){o=n+152|0;o=e[o>>1]|e[o+2>>1]<<16;m=1;v=o&65535;o=o>>>16&65535;s=c[n+104>>2]|0}else{m=1;v=0;o=0;s=-1}else{m=0;v=0;o=0;s=-1}n=c[a+204>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){w=n+172|0;w=e[w>>1]|e[w+2>>1]<<16;u=w&65535;q=1;r=c[n+108>>2]|0;w=w>>>16&65535}else{u=0;q=1;r=-1;w=0}else{u=0;q=0;r=-1;w=0}do if(!p)if(!((m|0)==0|(q|0)==0)){if((s|0)==0?((o&65535)<<16|v&65535|0)==0:0){n=0;o=0;break}if((r|0)==0?((w&65535)<<16|u&65535|0)==0:0){n=0;o=0}else T=16}else{n=0;o=0}else T=16;while(0);if((T|0)==16){y=b[f+160>>1]|0;z=b[f+162>>1]|0;n=c[a+208>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){t=n+172|0;p=c[n+108>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;T=25}else{p=-1;t=0;T=25}else T=20;do if((T|0)==20){p=c[a+212>>2]|0;if((p|0)!=0?(c[p+4>>2]|0)==(c[l>>2]|0):0){if((c[p>>2]|0)>>>0>=6){p=-1;t=0;T=25;break}t=p+192|0;p=c[p+112>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;T=25;break}if((m|0)==0|(q|0)!=0){p=-1;t=0;T=25}else n=v}while(0);do if((T|0)==25){m=(s|0)==(A|0);n=(r|0)==(A|0);if(((n&1)+(m&1)+((p|0)==(A|0)&1)|0)==1){if(m|n){n=m?v:u;o=m?o:w;break}n=t&65535;o=t>>>16&65535;break}n=v<<16>>16;l=u<<16>>16;p=t<<16>>16;if(u<<16>>16>v<<16>>16)m=l;else{m=n;n=(l|0)<(n|0)?l:n}if((m|0)<(p|0))p=m;else p=(n|0)>(p|0)?n:p;n=o<<16>>16;m=w<<16>>16;l=t>>16;if(w<<16>>16>o<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=p&65535;o=o&65535}while(0);n=(n&65535)+(y&65535)|0;o=(o&65535)+(z&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}else{n=n&65535;o=o&65535}}l=ic(g,A)|0;if(!l){G=1;i=X;return G|0}else{G=a+132|0;E=a+136|0;D=a+140|0;C=a+144|0;B=a+148|0;z=a+152|0;y=a+156|0;x=a+160|0;w=a+164|0;v=a+168|0;m=a+172|0;p=a+176|0;q=a+180|0;r=a+184|0;s=a+188|0;F=a+192|0;b[a+192>>1]=n;b[a+194>>1]=o;F=e[F>>1]|e[F+2>>1]<<16;b[s>>1]=F;b[s+2>>1]=F>>>16;b[r>>1]=F;b[r+2>>1]=F>>>16;b[q>>1]=F;b[q+2>>1]=F>>>16;b[p>>1]=F;b[p+2>>1]=F>>>16;b[m>>1]=F;b[m+2>>1]=F>>>16;b[v>>1]=F;b[v+2>>1]=F>>>16;b[w>>1]=F;b[w+2>>1]=F>>>16;b[x>>1]=F;b[x+2>>1]=F>>>16;b[y>>1]=F;b[y+2>>1]=F>>>16;b[z>>1]=F;b[z+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+100>>2]=A;c[a+104>>2]=A;c[a+108>>2]=A;c[a+112>>2]=A;c[a+116>>2]=l;c[a+120>>2]=l;c[a+124>>2]=l;c[a+128>>2]=l;c[W>>2]=l;dc(k,a+132|0,W,V,U,0,0,16,16);break}}else if((p|0)==3){x=b[f+160>>1]|0;y=b[f+162>>1]|0;C=c[f+144>>2]|0;u=a+4|0;o=c[a+200>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){w=o+152|0;w=e[w>>1]|e[w+2>>1]<<16;n=1;s=w&65535;w=w>>>16&65535;o=c[o+104>>2]|0}else{n=1;s=0;w=0;o=-1}else{n=0;s=0;w=0;o=-1}a:do if((o|0)==(C|0)){n=s;o=w}else{o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){G=o+172|0;G=e[G>>1]|e[G+2>>1]<<16;t=o+188|0;p=c[o+108>>2]|0;l=c[o+112>>2]|0;n=G&65535;o=G>>>16&65535;t=e[t>>1]|e[t+2>>1]<<16}else{p=-1;l=-1;n=0;o=0;t=0}else T=107;do if((T|0)==107){o=c[a+212>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0){if((c[o>>2]|0)>>>0>=6){p=-1;l=-1;n=0;o=0;t=0;break}t=o+192|0;p=-1;l=c[o+112>>2]|0;n=0;o=0;t=e[t>>1]|e[t+2>>1]<<16;break}if(!n){p=-1;l=-1;n=0;o=0;t=0}else{n=s;o=w;break a}}while(0);m=(p|0)==(C|0);if(((m&1)+((l|0)==(C|0)&1)|0)==1){if(m)break;n=t&65535;o=t>>>16&65535;break}l=s<<16>>16;p=n<<16>>16;q=t<<16>>16;if(n<<16>>16>s<<16>>16){m=p;n=l}else{m=l;n=(p|0)<(l|0)?p:l}if((m|0)<(q|0))q=m;else q=(n|0)>(q|0)?n:q;n=w<<16>>16;m=o<<16>>16;l=t>>16;if(o<<16>>16>w<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=q&65535;o=o&65535}while(0);n=(n&65535)+(x&65535)|0;o=(o&65535)+(y&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}m=ic(g,C)|0;if(!m){G=1;i=X;return G|0}x=a+132|0;z=a+136|0;A=a+140|0;y=a+144|0;G=a+164|0;F=a+168|0;E=a+172|0;w=a+176|0;b[a+176>>1]=n;b[a+178>>1]=o;w=e[w>>1]|e[w+2>>1]<<16;b[E>>1]=w;b[E+2>>1]=w>>>16;b[F>>1]=w;b[F+2>>1]=w>>>16;b[G>>1]=w;b[G+2>>1]=w>>>16;b[y>>1]=w;b[y+2>>1]=w>>>16;b[A>>1]=w;b[A+2>>1]=w>>>16;b[z>>1]=w;b[z+2>>1]=w>>>16;b[x>>1]=w;b[x+2>>1]=w>>>16;c[a+100>>2]=C;c[a+108>>2]=C;x=a+116|0;c[x>>2]=m;c[a+124>>2]=m;z=b[f+164>>1]|0;A=b[f+166>>1]|0;y=c[f+148>>2]|0;o=c[a+208>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){r=o+172|0;o=c[o+108>>2]|0;p=1;r=e[r>>1]|e[r+2>>1]<<16}else{o=-1;p=1;r=0}else{o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){r=o+176|0;o=c[o+108>>2]|0;p=1;r=e[r>>1]|e[r+2>>1]<<16}else{o=-1;p=1;r=0}else{o=-1;p=0;r=0}}do if((o|0)!=(y|0)){s=w&65535;o=w>>>16;v=o&65535;n=c[a+204>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[u>>2]|0):0)if((c[n>>2]|0)>>>0<6){u=n+188|0;u=e[u>>1]|e[u+2>>1]<<16;p=c[n+112>>2]|0;l=u&65535;u=u>>>16&65535}else{p=-1;l=0;u=0}else if(!p){m=w;break}else{p=-1;l=0;u=0}m=(C|0)==(y|0);n=(p|0)==(y|0);if(((n&1)+(m&1)|0)==1){if(m){m=w;break}if(n){o=u&65535;m=o<<16|l&65535;break}else{m=r;o=r>>>16;break}}o=w<<16>>16;p=l<<16>>16;q=r<<16>>16;if(l<<16>>16>s<<16>>16)m=p;else{m=o;o=(p|0)<(o|0)?p:o}if((m|0)>=(q|0))m=(o|0)>(q|0)?o:q;n=w>>16;l=u<<16>>16;p=r>>16;if(u<<16>>16>v<<16>>16)o=l;else{o=n;n=(l|0)<(n|0)?l:n}if((o|0)>=(p|0))o=(n|0)>(p|0)?n:p}else{m=r;o=r>>>16}while(0);m=(m&65535)+(z&65535)|0;n=(o&65535)+(A&65535)|0;if(((m<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((n<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}o=ic(g,y)|0;if(!o){G=1;i=X;return G|0}else{G=a+148|0;E=a+152|0;D=a+156|0;C=a+160|0;B=a+180|0;A=a+184|0;z=a+188|0;F=a+192|0;b[a+192>>1]=m;b[a+194>>1]=n;F=e[F>>1]|e[F+2>>1]<<16;b[z>>1]=F;b[z+2>>1]=F>>>16;b[A>>1]=F;b[A+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+104>>2]=y;c[a+112>>2]=y;F=a+120|0;c[F>>2]=o;c[a+128>>2]=o;c[W>>2]=c[x>>2];dc(k,a+132|0,W,V,U,0,0,8,16);c[W>>2]=c[F>>2];dc(k,G,W,V,U,8,0,8,16);break}}else if((p|0)==2){z=b[f+160>>1]|0;A=b[f+162>>1]|0;C=c[f+144>>2]|0;B=a+4|0;o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[B>>2]|0):0)if((c[o>>2]|0)>>>0<6){w=o+172|0;w=e[w>>1]|e[w+2>>1]<<16;m=1;o=c[o+108>>2]|0;r=w&65535;w=w>>>16&65535}else{m=1;o=-1;r=0;w=0}else{m=0;o=-1;r=0;w=0}b:do if((o|0)==(C|0)){n=r;o=w}else{n=c[a+200>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0)if((c[n>>2]|0)>>>0<6){o=n+152|0;o=e[o>>1]|e[o+2>>1]<<16;q=1;s=o&65535;o=o>>>16&65535;p=c[n+104>>2]|0}else{q=1;s=0;o=0;p=-1}else{q=0;s=0;o=0;p=-1}n=c[a+208>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0)if((c[n>>2]|0)>>>0<6){t=n+172|0;n=c[n+108>>2]|0;t=e[t>>1]|e[t+2>>1]<<16}else{n=-1;t=0}else T=54;do if((T|0)==54){n=c[a+212>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0){if((c[n>>2]|0)>>>0>=6){n=-1;t=0;break}t=n+192|0;n=c[n+112>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;break}if((q|0)==0|(m|0)!=0){n=-1;t=0}else{n=s;break b}}while(0);m=(p|0)==(C|0);if((((n|0)==(C|0)&1)+(m&1)|0)==1){if(m){n=m?s:r;o=m?o:w;break}n=t&65535;o=t>>>16&65535;break}n=s<<16>>16;l=r<<16>>16;p=t<<16>>16;if(r<<16>>16>s<<16>>16)m=l;else{m=n;n=(l|0)<(n|0)?l:n}if((m|0)<(p|0))q=m;else q=(n|0)>(p|0)?n:p;n=o<<16>>16;m=w<<16>>16;l=t>>16;if(w<<16>>16>o<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=q&65535;o=o&65535}while(0);n=(n&65535)+(z&65535)|0;o=(o&65535)+(A&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}m=ic(g,C)|0;if(!m){G=1;i=X;return G|0}A=a+132|0;x=a+136|0;y=a+140|0;z=a+144|0;q=a+148|0;p=a+152|0;G=a+156|0;v=a+160|0;b[a+160>>1]=n;b[a+162>>1]=o;v=e[v>>1]|e[v+2>>1]<<16;b[G>>1]=v;b[G+2>>1]=v>>>16;b[p>>1]=v;b[p+2>>1]=v>>>16;b[q>>1]=v;b[q+2>>1]=v>>>16;b[z>>1]=v;b[z+2>>1]=v>>>16;b[y>>1]=v;b[y+2>>1]=v>>>16;b[x>>1]=v;b[x+2>>1]=v>>>16;b[A>>1]=v;b[A+2>>1]=v>>>16;c[a+100>>2]=C;c[a+104>>2]=C;A=a+116|0;c[A>>2]=m;c[a+120>>2]=m;x=b[f+164>>1]|0;y=b[f+166>>1]|0;z=c[f+148>>2]|0;q=c[a+200>>2]|0;p=(q|0)==0;if((!p?(c[q+4>>2]|0)==(c[B>>2]|0):0)?(c[q>>2]|0)>>>0<6:0){w=q+184|0;w=e[w>>1]|e[w+2>>1]<<16;r=w&65535;w=w>>>16&65535;o=c[q+112>>2]|0}else{r=0;w=0;o=-1}do if((o|0)!=(z|0)){s=v&65535;n=v>>>16;u=n&65535;if((!p?(c[q+4>>2]|0)==(c[B>>2]|0):0)?(c[q>>2]|0)>>>0<6:0){t=q+160|0;p=c[q+104>>2]|0;t=e[t>>1]|e[t+2>>1]<<16}else{p=-1;t=0}o=(C|0)==(z|0);if((((p|0)==(z|0)&1)+(o&1)|0)==1){m=o?v:t;o=o?n:t>>>16;break}o=r<<16>>16;p=v<<16>>16;q=t<<16>>16;if(s<<16>>16>r<<16>>16)m=p;else{m=o;o=(p|0)<(o|0)?p:o}if((m|0)>=(q|0))m=(o|0)>(q|0)?o:q;n=w<<16>>16;l=v>>16;p=t>>16;if(u<<16>>16>w<<16>>16)o=l;else{o=n;n=(l|0)<(n|0)?l:n}if((o|0)>=(p|0))o=(n|0)>(p|0)?n:p}else{o=w&65535;m=o<<16|r&65535}while(0);m=(m&65535)+(x&65535)|0;n=(o&65535)+(y&65535)|0;if(((m<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((n<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}o=ic(g,z)|0;if(!o){G=1;i=X;return G|0}else{G=a+164|0;E=a+168|0;D=a+172|0;C=a+176|0;B=a+180|0;y=a+184|0;x=a+188|0;F=a+192|0;b[a+192>>1]=m;b[a+194>>1]=n;F=e[F>>1]|e[F+2>>1]<<16;b[x>>1]=F;b[x+2>>1]=F>>>16;b[y>>1]=F;b[y+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+108>>2]=z;c[a+112>>2]=z;F=a+124|0;c[F>>2]=o;c[a+128>>2]=o;c[W>>2]=c[A>>2];dc(k,a+132|0,W,V,U,0,0,16,8);c[W>>2]=c[F>>2];dc(k,G,W,V,U,0,8,16,8);break}}else{S=a+4|0;H=0;c:while(1){D=f+(H<<2)+176|0;G=eb(c[D>>2]|0)|0;E=f+(H<<2)+192|0;c[a+(H<<2)+100>>2]=c[E>>2];F=ic(g,c[E>>2]|0)|0;c[a+(H<<2)+116>>2]=F;if(!F){l=1;T=212;break}if(G){J=H<<2;K=a+(J<<2)+132|0;O=a+(J<<2)+134|0;P=J|1;L=a+(P<<2)+132|0;P=a+(P<<2)+134|0;Q=J|2;M=a+(Q<<2)+132|0;Q=a+(Q<<2)+134|0;R=J|3;N=a+(R<<2)+132|0;R=a+(R<<2)+134|0;I=0;do{C=b[f+(H<<4)+(I<<2)+208>>1]|0;B=b[f+(H<<4)+(I<<2)+210>>1]|0;F=hb(c[D>>2]|0)|0;n=c[E>>2]|0;s=ub(a,c[6288+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;r=d[6288+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((s|0)!=0?(c[s+4>>2]|0)==(c[S>>2]|0):0)if((c[s>>2]|0)>>>0<6){q=s+(r<<2)+132|0;q=e[q>>1]|e[q+2>>1]<<16;A=c[s+(r>>>2<<2)+100>>2]|0;o=q&65535;z=1;q=q>>>16&65535}else{A=-1;o=0;z=1;q=0}else{A=-1;o=0;z=0;q=0}v=ub(a,c[5776+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;l=d[5776+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((v|0)!=0?(c[v+4>>2]|0)==(c[S>>2]|0):0)if((c[v>>2]|0)>>>0<6){p=v+(l<<2)+132|0;p=e[p>>1]|e[p+2>>1]<<16;y=1;x=c[v+(l>>>2<<2)+100>>2]|0;m=p&65535;p=p>>>16&65535}else{y=1;x=-1;m=0;p=0}else{y=0;x=-1;m=0;p=0}w=ub(a,c[5264+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;v=d[5264+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((w|0)!=0?(c[w+4>>2]|0)==(c[S>>2]|0):0)if((c[w>>2]|0)>>>0<6){z=w+(v<<2)+132|0;z=e[z>>1]|e[z+2>>1]<<16;v=c[w+(v>>>2<<2)+100>>2]|0;T=180}else{z=0;v=-1;T=180}else T=175;do if((T|0)==175){T=0;w=ub(a,c[4752+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;v=d[4752+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((w|0)!=0?(c[w+4>>2]|0)==(c[S>>2]|0):0){if((c[w>>2]|0)>>>0>=6){z=0;v=-1;T=180;break}z=w+(v<<2)+132|0;z=e[z>>1]|e[z+2>>1]<<16;v=c[w+(v>>>2<<2)+100>>2]|0;T=180;break}if((z|0)==0|(y|0)!=0){z=0;v=-1;T=180}else{v=o;t=q}}while(0);do if((T|0)==180){l=(A|0)==(n|0);w=(x|0)==(n|0);if(((w&1)+(l&1)+((v|0)==(n|0)&1)|0)==1){if(l|w){v=l?o:m;t=l?q:p;break}v=z&65535;t=z>>>16&65535;break}u=o<<16>>16;w=m<<16>>16;l=z<<16>>16;if(m<<16>>16>o<<16>>16)v=w;else{v=u;u=(w|0)<(u|0)?w:u}if((v|0)<(l|0))w=v;else w=(u|0)>(l|0)?u:l;t=q<<16>>16;v=p<<16>>16;l=z>>16;if(p<<16>>16>q<<16>>16)s=v;else{s=t;t=(v|0)<(t|0)?v:t}if((s|0)>=(l|0))s=(t|0)>(l|0)?t:l;v=w&65535;t=s&65535}while(0);C=(v&65535)+(C&65535)|0;q=C&65535;s=(t&65535)+(B&65535)|0;r=s&65535;if(((C<<16>>16)+8192|0)>>>0>16383){l=1;T=212;break c}if(((s<<16>>16)+2048|0)>>>0>4095){l=1;T=212;break c}if(!F){b[K>>1]=q;b[O>>1]=r;b[L>>1]=q;b[P>>1]=r;b[M>>1]=q;b[Q>>1]=r;b[N>>1]=q;b[R>>1]=r}else if((F|0)==1){F=(I<<1)+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r;F=F|1;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}else if((F|0)==2){F=I+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r;F=F+2|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}else if((F|0)==3){F=I+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}I=I+1|0}while(I>>>0>>0)}H=H+1|0;if(H>>>0>=4){T=201;break}}if((T|0)==201){o=0;do{c[W>>2]=c[a+(o<<2)+116>>2];m=hb(c[f+(o<<2)+176>>2]|0)|0;l=o<<3&8;n=o>>>0<2?0:8;if(!m)dc(k,a+(o<<2<<2)+132|0,W,V,U,l,n,8,8);else if((m|0)==1){G=o<<2;dc(k,a+(G<<2)+132|0,W,V,U,l,n,8,4);dc(k,a+((G|2)<<2)+132|0,W,V,U,l,n|4,8,4)}else if((m|0)==2){G=o<<2;dc(k,a+(G<<2)+132|0,W,V,U,l,n,4,8);dc(k,a+((G|1)<<2)+132|0,W,V,U,l|4,n,4,8)}else{E=o<<2;dc(k,a+(E<<2)+132|0,W,V,U,l,n,4,4);F=l|4;dc(k,a+((E|1)<<2)+132|0,W,V,U,F,n,4,4);G=n|4;dc(k,a+((E|2)<<2)+132|0,W,V,U,l,G,4,4);dc(k,a+((E|3)<<2)+132|0,W,V,U,F,G,4,4)}o=o+1|0}while((o|0)!=4)}else if((T|0)==212){i=X;return l|0}}while(0);if((c[a+196>>2]|0)>>>0>1){G=0;i=X;return G|0}if(!(c[a>>2]|0)){sc(j,k);G=0;i=X;return G|0}else{tc(j,h,k,f+328|0);G=0;i=X;return G|0}return 0}function Tb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0,D=0,E=0,F=0;B=i;i=i+144|0;m=B;if((e|0)>=0?!((e+1+k|0)>>>0>g>>>0|(f|0)<0|(l+f|0)>>>0>h>>>0):0)m=b;else{A=k+1|0;Ub(b,m,e,f,g,h,A,l,A);Ub(b+(Z(h,g)|0)|0,m+(Z(A,l)|0)|0,e,f,g,h,A,l,A);h=l;g=A;e=0;f=0}A=8-j|0;v=l>>>1;z=(v|0)==0;w=k>>>1;y=(w|0)==0;x=16-k|0;u=(g<<1)-k|0;s=g+1|0;t=g+2|0;p=w<<1;r=0;do{l=m+((Z((Z(r,h)|0)+f|0,g)|0)+e)|0;if(!(z|y)){q=c+(r<<6)|0;o=v;while(1){k=q;b=l;n=w;while(1){D=d[b>>0]|0;E=d[b+s>>0]|0;F=b;b=b+2|0;C=d[F+1>>0]|0;a[k+8>>0]=(((Z(E,j)|0)+(Z(d[F+g>>0]|0,A)|0)<<3)+32|0)>>>6;a[k>>0]=(((Z(C,j)|0)+(Z(D,A)|0)<<3)+32|0)>>>6;D=d[b>>0]|0;a[k+9>>0]=(((Z(d[F+t>>0]|0,j)|0)+(Z(E,A)|0)<<3)+32|0)>>>6;a[k+1>>0]=(((Z(D,j)|0)+(Z(C,A)|0)<<3)+32|0)>>>6;n=n+-1|0;if(!n)break;else k=k+2|0}o=o+-1|0;if(!o)break;else{q=q+(p+x)|0;l=l+(p+u)|0}}}r=r+1|0}while((r|0)!=2);i=B;return}function Ub(a,b,c,d,e,f,g,h,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;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;k=g+c|0;o=h+d|0;s=(c|0)<0|(k|0)>(e|0)?2:1;m=(o|0)<0?0-h|0:d;d=(k|0)<0?0-g|0:c;m=(m|0)>(f|0)?f:m;d=(d|0)>(e|0)?e:d;k=d+g|0;l=m+h|0;if((d|0)>0)a=a+d|0;if((m|0)>0)a=a+(Z(m,e)|0)|0;r=(d|0)<0?0-d|0:0;q=(k|0)>(e|0)?k-e|0:0;p=g-r-q|0;g=0-m|0;m=(m|0)<0?g:0;c=l-f|0;n=(l|0)>(f|0)?c:0;k=h-m|0;d=k-n|0;if(m){m=h+-1-((o|0)>0?o:0)|0;l=~f;l=(m|0)>(l|0)?m:l;m=~l;m=Z(l+((m|0)>0?m:0)+1|0,j)|0;l=b;while(1){xa[s&3](a,l,r,p,q);g=g+-1|0;if(!g)break;else l=l+j|0}b=b+m|0}if((k|0)!=(n|0)){l=h+-1|0;g=l-((o|0)>0?o:0)|0;k=~f;k=(g|0)>(k|0)?g:k;l=l-k|0;g=~k;g=h+f+-1-((l|0)<(f|0)?f:l)-k-((g|0)>0?g:0)|0;k=Z(g,j)|0;g=Z(g,e)|0;l=b;m=a;while(1){xa[s&3](m,l,r,p,q);d=d+-1|0;if(!d)break;else{l=l+j|0;m=m+e|0}}b=b+k|0;a=a+g|0}a=a+(0-e)|0;if(!n){i=t;return}while(1){xa[s&3](a,b,r,p,q);c=c+-1|0;if(!c)break;else b=b+j|0}i=t;return}function Vb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0,D=0,E=0;C=i;i=i+144|0;m=C;if(((e|0)>=0?!((k+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+1+l|0)>>>0<=h>>>0:0)m=b;else{A=l+1|0;Ub(b,m,e,f,g,h,k,A,k);Ub(b+(Z(h,g)|0)|0,m+(Z(A,k)|0)|0,e,f,g,h,k,A,k);h=A;g=k;e=0;f=0}B=8-j|0;w=l>>>1;A=(w|0)==0;x=k>>>1;z=(x|0)==0;y=16-k|0;v=g<<1;u=v-k|0;t=v|1;s=g+1|0;p=x<<1;r=0;do{l=m+((Z((Z(r,h)|0)+f|0,g)|0)+e)|0;if(!(A|z)){q=c+(r<<6)|0;o=w;while(1){k=q;b=l;n=x;while(1){D=d[b+g>>0]|0;E=d[b>>0]|0;a[k+8>>0]=(((Z(D,B)|0)+(Z(d[b+v>>0]|0,j)|0)<<3)+32|0)>>>6;a[k>>0]=(((Z(E,B)|0)+(Z(D,j)|0)<<3)+32|0)>>>6;D=d[b+s>>0]|0;E=d[b+1>>0]|0;a[k+9>>0]=(((Z(D,B)|0)+(Z(d[b+t>>0]|0,j)|0)<<3)+32|0)>>>6;a[k+1>>0]=(((Z(E,B)|0)+(Z(D,j)|0)<<3)+32|0)>>>6;n=n+-1|0;if(!n)break;else{k=k+2|0;b=b+2|0}}o=o+-1|0;if(!o)break;else{q=q+(p+y)|0;l=l+(p+u)|0}}}r=r+1|0}while((r|0)!=2);i=C;return}function Wb(b,c,e,f,g,h,j,k,l,m){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,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;I=i;i=i+176|0;n=I;if(((e|0)>=0?!((e+1+l|0)>>>0>g>>>0|(f|0)<0):0)?(f+1+m|0)>>>0<=h>>>0:0)n=b;else{B=l+1|0;A=m+1|0;Ub(b,n,e,f,g,h,B,A,B);Ub(b+(Z(h,g)|0)|0,n+(Z(A,B)|0)|0,e,f,g,h,B,A,B);h=A;g=B;e=0;f=0}G=8-j|0;H=8-k|0;B=m>>>1;E=(B|0)==0;A=g<<1;C=l>>>1;F=(C|0)==0;D=16-l|0;z=A-l|0;v=g+1|0;w=A|1;x=g+2|0;y=A+2|0;s=C<<1;u=0;do{l=n+((Z((Z(u,h)|0)+f|0,g)|0)+e)|0;if(!(E|F)){t=c+(u<<6)|0;r=B;while(1){p=d[l+g>>0]|0;m=t;b=l;o=(Z(p,k)|0)+(Z(d[l>>0]|0,H)|0)|0;p=(Z(d[l+A>>0]|0,k)|0)+(Z(p,H)|0)|0;q=C;while(1){K=d[b+v>>0]|0;J=(Z(K,k)|0)+(Z(d[b+1>>0]|0,H)|0)|0;K=(Z(d[b+w>>0]|0,k)|0)+(Z(K,H)|0)|0;M=((Z(o,G)|0)+32+(Z(J,j)|0)|0)>>>6;a[m+8>>0]=((Z(p,G)|0)+32+(Z(K,j)|0)|0)>>>6;a[m>>0]=M;M=b;b=b+2|0;L=d[M+x>>0]|0;o=(Z(L,k)|0)+(Z(d[b>>0]|0,H)|0)|0;p=(Z(d[M+y>>0]|0,k)|0)+(Z(L,H)|0)|0;J=((Z(J,G)|0)+32+(Z(o,j)|0)|0)>>>6;a[m+9>>0]=((Z(K,G)|0)+32+(Z(p,j)|0)|0)>>>6;a[m+1>>0]=J;q=q+-1|0;if(!q)break;else m=m+2|0}r=r+-1|0;if(!r)break;else{t=t+(s+D)|0;l=l+(s+z)|0}}}u=u+1|0}while((u|0)!=2);i=I;return}function Xb(b,c,e,f,g,h,j,k){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var 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;r=i;i=i+448|0;l=r;if(((e|0)>=0?!((j+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)l=b;else{Ub(b,l,e,f,g,h,j,k+5|0,j);g=j;e=0;f=0}h=e+g+(Z(f,g)|0)|0;b=k>>>2;if(!b){i=r;return}n=g<<2;q=0-g|0;o=q<<1;p=g<<1;if(!j){i=r;return}else{m=l+h|0;e=l+(h+(g*5|0))|0}while(1){l=j;h=c;k=m;f=e;while(1){u=d[f+o>>0]|0;v=d[f+q>>0]|0;w=d[f+g>>0]|0;y=d[f>>0]|0;x=w+u|0;s=d[k+p>>0]|0;a[h+48>>0]=a[((d[f+p>>0]|0)+16-x-(x<<2)+s+((y+v|0)*20|0)>>5)+3984>>0]|0;x=s+y|0;t=d[k+g>>0]|0;a[h+32>>0]=a[(w+16-x-(x<<2)+t+((v+u|0)*20|0)>>5)+3984>>0]|0;x=t+v|0;w=d[k>>0]|0;a[h+16>>0]=a[(y+16-x-(x<<2)+w+((s+u|0)*20|0)>>5)+3984>>0]|0;u=w+u|0;a[h>>0]=a[(v+16-u-(u<<2)+(d[k+q>>0]|0)+((t+s|0)*20|0)>>5)+3984>>0]|0;l=l+-1|0;if(!l)break;else{h=h+1|0;k=k+1|0;f=f+1|0}}b=b+-1|0;if(!b)break;else{c=c+64|0;m=m+n|0;e=e+n|0}}i=r;return}function Yb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0;v=i;i=i+448|0;m=v;if(((e|0)>=0?!((j+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)m=b;else{Ub(b,m,e,f,g,h,j,k+5|0,j);g=j;e=0;f=0}h=e+g+(Z(f,g)|0)|0;b=k>>>2;if(!b){i=v;return}u=(j|0)==0;s=(g<<2)-j|0;t=64-j|0;r=0-g|0;p=r<<1;q=g<<1;e=m+h|0;f=m+(h+(Z(g,l+2|0)|0))|0;m=m+(h+(g*5|0))|0;while(1){if(u){h=c;k=f}else{k=f+j|0;h=c+j|0;l=j;o=e;n=m;while(1){y=d[n+p>>0]|0;z=d[n+r>>0]|0;A=d[n+g>>0]|0;C=d[n>>0]|0;B=A+y|0;w=d[o+q>>0]|0;a[c+48>>0]=((d[((d[n+q>>0]|0)+16-B-(B<<2)+w+((C+z|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+q>>0]|0)|0)>>>1;B=w+C|0;x=d[o+g>>0]|0;a[c+32>>0]=((d[(A+16-B-(B<<2)+x+((z+y|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+g>>0]|0)|0)>>>1;B=x+z|0;A=d[o>>0]|0;a[c+16>>0]=((d[(C+16-B-(B<<2)+A+((w+y|0)*20|0)>>5)+3984>>0]|0)+1+(d[f>>0]|0)|0)>>>1;y=A+y|0;a[c>>0]=((d[(z+16-y-(y<<2)+(d[o+r>>0]|0)+((x+w|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+r>>0]|0)|0)>>>1;l=l+-1|0;if(!l)break;else{c=c+1|0;o=o+1|0;f=f+1|0;n=n+1|0}}e=e+j|0;m=m+j|0}b=b+-1|0;if(!b)break;else{c=h+t|0;e=e+s|0;f=k+s|0;m=m+s|0}}i=v;return}function Zb(b,c,e,f,g,h,j,k){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;u=i;i=i+448|0;l=u;if((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0|(k+f|0)>>>0>h>>>0):0)l=b;else{n=j+5|0;Ub(b,l,e,f,g,h,n,k,n);g=n;e=0;f=0}if(!k){i=u;return}r=j>>>2;t=(r|0)==0;s=g-j|0;q=16-j|0;p=r<<2;b=c;l=l+(e+5+(Z(f,g)|0))|0;o=k;while(1){if(t)h=b;else{h=b+p|0;e=l;g=d[l+-1>>0]|0;k=d[l+-2>>0]|0;m=d[l+-3>>0]|0;n=d[l+-4>>0]|0;j=d[l+-5>>0]|0;c=r;while(1){f=n+g|0;v=n;n=d[e>>0]|0;a[b>>0]=a[(j+16-f-(f<<2)+n+((m+k|0)*20|0)>>5)+3984>>0]|0;j=n+m|0;f=m;m=d[e+1>>0]|0;a[b+1>>0]=a[(v+16-j-(j<<2)+m+((k+g|0)*20|0)>>5)+3984>>0]|0;j=m+k|0;v=k;k=d[e+2>>0]|0;a[b+2>>0]=a[(f+16-j-(j<<2)+k+((n+g|0)*20|0)>>5)+3984>>0]|0;j=k+g|0;f=d[e+3>>0]|0;a[b+3>>0]=a[(v+16-j-(j<<2)+f+((m+n|0)*20|0)>>5)+3984>>0]|0;c=c+-1|0;if(!c)break;else{j=g;b=b+4|0;e=e+4|0;g=f}}l=l+p|0}o=o+-1|0;if(!o)break;else{b=h+q|0;l=l+s|0}}i=u;return}function _b(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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;v=i;i=i+448|0;m=v;if((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0|(k+f|0)>>>0>h>>>0):0)m=b;else{o=j+5|0;Ub(b,m,e,f,g,h,o,k,o);g=o;e=0;f=0}if(!k){i=v;return}s=j>>>2;u=(s|0)==0;t=g-j|0;r=16-j|0;q=(l|0)!=0;p=s<<2;b=c;m=m+(e+5+(Z(f,g)|0))|0;while(1){if(u)h=b;else{h=b+p|0;l=m;e=d[m+-1>>0]|0;g=d[m+-2>>0]|0;n=d[m+-3>>0]|0;o=d[m+-4>>0]|0;j=d[m+-5>>0]|0;c=s;while(1){f=o+e|0;w=o;o=d[l>>0]|0;a[b>>0]=((q?g:n)+1+(d[(j+16-f-(f<<2)+o+((n+g|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=o+n|0;f=n;n=d[l+1>>0]|0;a[b+1>>0]=((q?e:g)+1+(d[(w+16-j-(j<<2)+n+((g+e|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=n+g|0;w=g;g=d[l+2>>0]|0;a[b+2>>0]=((q?o:e)+1+(d[(f+16-j-(j<<2)+g+((o+e|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=g+e|0;f=d[l+3>>0]|0;a[b+3>>0]=((q?n:o)+1+(d[(w+16-j-(j<<2)+f+((n+o|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;c=c+-1|0;if(!c)break;else{j=e;b=b+4|0;l=l+4|0;e=f}}m=m+p|0}k=k+-1|0;if(!k)break;else{b=h+r|0;m=m+t|0}}i=v;return}function $b(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0;z=i;i=i+448|0;m=z;if(((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)m=b;else{y=j+5|0;Ub(b,m,e,f,g,h,y,k+5|0,y);g=y;e=0;f=0}b=(Z(f,g)|0)+e|0;y=(l&1|2)+g+b|0;n=m+y|0;if(!k){i=z;return}u=j>>>2;w=(u|0)==0;v=g-j|0;x=16-j|0;t=u<<2;b=m+((Z(g,l>>>1&1|2)|0)+5+b)|0;s=k;while(1){if(!w){r=c+t|0;h=b;e=d[b+-1>>0]|0;f=d[b+-2>>0]|0;o=d[b+-3>>0]|0;p=d[b+-4>>0]|0;l=d[b+-5>>0]|0;q=u;while(1){A=p+e|0;B=p;p=d[h>>0]|0;a[c>>0]=a[(l+16-A-(A<<2)+p+((o+f|0)*20|0)>>5)+3984>>0]|0;A=p+o|0;l=o;o=d[h+1>>0]|0;a[c+1>>0]=a[(B+16-A-(A<<2)+o+((f+e|0)*20|0)>>5)+3984>>0]|0;A=o+f|0;B=f;f=d[h+2>>0]|0;a[c+2>>0]=a[(l+16-A-(A<<2)+f+((p+e|0)*20|0)>>5)+3984>>0]|0;A=f+e|0;l=d[h+3>>0]|0;a[c+3>>0]=a[(B+16-A-(A<<2)+l+((o+p|0)*20|0)>>5)+3984>>0]|0;q=q+-1|0;if(!q)break;else{A=e;c=c+4|0;h=h+4|0;e=l;l=A}}c=r;b=b+t|0}s=s+-1|0;if(!s)break;else{c=c+x|0;b=b+v|0}}b=k>>>2;if(!b){i=z;return}t=(j|0)==0;p=(g<<2)-j|0;o=64-j|0;q=0-g|0;s=q<<1;r=g<<1;c=c+(x-(k<<4))|0;h=m+(y+(g*5|0))|0;l=b;while(1){if(t){b=c;m=n}else{b=c+j|0;m=c;e=n;f=h;c=j;while(1){x=d[f+s>>0]|0;w=d[f+q>>0]|0;u=d[f+g>>0]|0;B=d[f>>0]|0;y=u+x|0;k=d[e+r>>0]|0;A=m+48|0;a[A>>0]=((d[((d[f+r>>0]|0)+16-y-(y<<2)+k+((B+w|0)*20|0)>>5)+3984>>0]|0)+1+(d[A>>0]|0)|0)>>>1;A=k+B|0;y=d[e+g>>0]|0;v=m+32|0;a[v>>0]=((d[(u+16-A-(A<<2)+y+((w+x|0)*20|0)>>5)+3984>>0]|0)+1+(d[v>>0]|0)|0)>>>1;v=d[e>>0]|0;A=y+w|0;u=m+16|0;a[u>>0]=((d[(B+16-A-(A<<2)+v+((k+x|0)*20|0)>>5)+3984>>0]|0)+1+(d[u>>0]|0)|0)>>>1;x=v+x|0;a[m>>0]=((d[(w+16-x-(x<<2)+(d[e+q>>0]|0)+((y+k|0)*20|0)>>5)+3984>>0]|0)+1+(d[m>>0]|0)|0)>>>1;c=c+-1|0;if(!c)break;else{m=m+1|0;e=e+1|0;f=f+1|0}}m=n+j|0;h=h+j|0}l=l+-1|0;if(!l)break;else{c=b+o|0;n=m+p|0;h=h+p|0}}i=z;return}function ac(b,e,f,g,h,j,k,l){b=b|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0;x=i;i=i+1792|0;m=x+1344|0;w=x;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0){o=l+5|0;m=b;n=f+5|0}else{n=k+5|0;o=l+5|0;Ub(b,m,f,g,h,j,n,o,n);h=n;n=5;g=0}if(o){t=k>>>2;v=(t|0)==0;s=h-k|0;u=t<<2;f=w;m=m+(n+(Z(g,h)|0))|0;while(1){if(v)b=f;else{b=f+(u<<2)|0;g=m;h=d[m+-1>>0]|0;j=d[m+-2>>0]|0;p=d[m+-3>>0]|0;q=d[m+-4>>0]|0;n=d[m+-5>>0]|0;r=t;while(1){y=q+h|0;z=q;q=d[g>>0]|0;c[f>>2]=n-y-(y<<2)+q+((p+j|0)*20|0);y=q+p|0;n=p;p=d[g+1>>0]|0;c[f+4>>2]=z-y+p-(y<<2)+((j+h|0)*20|0);y=p+j|0;z=j;j=d[g+2>>0]|0;c[f+8>>2]=n-y+j-(y<<2)+((q+h|0)*20|0);y=j+h|0;n=d[g+3>>0]|0;c[f+12>>2]=z-y+n-(y<<2)+((p+q|0)*20|0);r=r+-1|0;if(!r)break;else{y=h;f=f+16|0;g=g+4|0;h=n;n=y}}m=m+u|0}o=o+-1|0;if(!o)break;else{f=b;m=m+s|0}}}h=l>>>2;if(!h){i=x;return}u=(k|0)==0;s=64-k|0;p=k*3|0;t=0-k|0;q=t<<1;r=k<<1;g=e;b=w+(k<<2)|0;m=w+(k*6<<2)|0;o=h;while(1){if(u)h=g;else{h=g+k|0;f=b;j=m;n=k;while(1){e=c[j+(q<<2)>>2]|0;w=c[j+(t<<2)>>2]|0;z=c[j+(k<<2)>>2]|0;A=c[j>>2]|0;y=z+e|0;v=c[f+(r<<2)>>2]|0;a[g+48>>0]=a[((c[j+(r<<2)>>2]|0)+512-y-(y<<2)+v+((A+w|0)*20|0)>>10)+3984>>0]|0;y=v+A|0;l=c[f+(k<<2)>>2]|0;a[g+32>>0]=a[(z+512-y-(y<<2)+l+((w+e|0)*20|0)>>10)+3984>>0]|0;y=c[f>>2]|0;z=l+w|0;a[g+16>>0]=a[(A+512-z-(z<<2)+y+((v+e|0)*20|0)>>10)+3984>>0]|0;e=y+e|0;a[g>>0]=a[(w+512-e-(e<<2)+(c[f+(t<<2)>>2]|0)+((l+v|0)*20|0)>>10)+3984>>0]|0;n=n+-1|0;if(!n)break;else{g=g+1|0;f=f+4|0;j=j+4|0}}b=b+(k<<2)|0;m=m+(k<<2)|0}o=o+-1|0;if(!o)break;else{g=h+s|0;b=b+(p<<2)|0;m=m+(p<<2)|0}}i=x;return}function bc(b,e,f,g,h,j,k,l,m){b=b|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0;y=i;i=i+1792|0;n=y+1344|0;x=y;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0){o=l+5|0;n=b;f=f+5|0}else{q=k+5|0;o=l+5|0;Ub(b,n,f,g,h,j,q,o,q);h=q;f=5;g=0}if(o){v=k>>>2;t=(v|0)==0;u=h-k|0;w=v<<2;p=x;n=n+(f+(Z(g,h)|0))|0;s=o;while(1){if(t)b=p;else{b=p+(w<<2)|0;g=n;f=d[n+-1>>0]|0;h=d[n+-2>>0]|0;j=d[n+-3>>0]|0;q=d[n+-4>>0]|0;o=d[n+-5>>0]|0;r=v;while(1){z=q+f|0;A=q;q=d[g>>0]|0;c[p>>2]=o-z-(z<<2)+q+((j+h|0)*20|0);z=q+j|0;o=j;j=d[g+1>>0]|0;c[p+4>>2]=A-z+j-(z<<2)+((h+f|0)*20|0);z=j+h|0;A=h;h=d[g+2>>0]|0;c[p+8>>2]=o-z+h-(z<<2)+((q+f|0)*20|0);z=h+f|0;o=d[g+3>>0]|0;c[p+12>>2]=A-z+o-(z<<2)+((j+q|0)*20|0);r=r+-1|0;if(!r)break;else{z=f;p=p+16|0;g=g+4|0;f=o;o=z}}n=n+w|0}s=s+-1|0;if(!s)break;else{p=b;n=n+u|0}}}f=l>>>2;if(!f){i=y;return}w=(k|0)==0;u=64-k|0;q=k*3|0;v=0-k|0;t=v<<1;s=k<<1;b=x+(k<<2)|0;n=x+((Z(m+2|0,k)|0)+k<<2)|0;h=x+(k*6<<2)|0;r=f;while(1){if(w){g=e;f=n}else{f=n+(k<<2)|0;g=e+k|0;p=b;j=h;o=k;while(1){m=c[j+(t<<2)>>2]|0;l=c[j+(v<<2)>>2]|0;B=c[j+(k<<2)>>2]|0;C=c[j>>2]|0;A=B+m|0;z=c[p+(s<<2)>>2]|0;a[e+48>>0]=((d[((c[j+(s<<2)>>2]|0)+512-A-(A<<2)+z+((C+l|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(s<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;A=z+C|0;x=c[p+(k<<2)>>2]|0;a[e+32>>0]=((d[(B+512-A-(A<<2)+x+((l+m|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(k<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;A=c[p>>2]|0;B=x+l|0;a[e+16>>0]=((d[(C+512-B-(B<<2)+A+((z+m|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=A+m|0;a[e>>0]=((d[(l+512-m-(m<<2)+(c[p+(v<<2)>>2]|0)+((x+z|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(v<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;o=o+-1|0;if(!o)break;else{e=e+1|0;p=p+4|0;n=n+4|0;j=j+4|0}}b=b+(k<<2)|0;h=h+(k<<2)|0}r=r+-1|0;if(!r)break;else{e=g+u|0;b=b+(q<<2)|0;n=f+(q<<2)|0;h=h+(q<<2)|0}}i=y;return}function cc(b,e,f,g,h,j,k,l,m){b=b|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;B=i;i=i+1792|0;n=B+1344|0;A=B;z=k+5|0;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0)n=b;else{Ub(b,n,f,g,h,j,z,l+5|0,z);h=z;f=0;g=0}s=f+h+(Z(g,h)|0)|0;g=l>>>2;if(g){y=(z|0)==0;x=(h<<2)-k+-5|0;t=z*3|0;p=0-h|0;w=p<<1;v=h<<1;u=z<<1;q=-5-k|0;j=A+(z<<2)|0;r=n+s|0;f=n+(s+(h*5|0))|0;while(1){if(y)s=j;else{s=j+(z<<2)|0;n=r;b=f;o=z;while(1){E=d[b+w>>0]|0;F=d[b+p>>0]|0;H=d[b+h>>0]|0;I=d[b>>0]|0;G=H+E|0;C=d[n+v>>0]|0;c[j+(u<<2)>>2]=(d[b+v>>0]|0)-G-(G<<2)+C+((I+F|0)*20|0);G=C+I|0;D=d[n+h>>0]|0;c[j+(z<<2)>>2]=H-G+D-(G<<2)+((F+E|0)*20|0);G=d[n>>0]|0;H=D+F|0;c[j>>2]=I-H+G-(H<<2)+((C+E|0)*20|0);E=G+E|0;c[j+(q<<2)>>2]=F-E+(d[n+p>>0]|0)-(E<<2)+((D+C|0)*20|0);o=o+-1|0;if(!o)break;else{j=j+4|0;n=n+1|0;b=b+1|0}}r=r+z|0;f=f+z|0}g=g+-1|0;if(!g)break;else{j=s+(t<<2)|0;r=r+x|0;f=f+x|0}}}if(!l){i=B;return}v=k>>>2;w=(v|0)==0;u=16-k|0;t=v<<2;h=A+(m+2<<2)|0;g=A+20|0;while(1){if(w)f=h;else{f=h+(t<<2)|0;s=e;n=g;j=c[g+-4>>2]|0;o=c[g+-8>>2]|0;p=c[g+-12>>2]|0;q=c[g+-16>>2]|0;b=c[g+-20>>2]|0;r=v;while(1){m=q+j|0;k=q;q=c[n>>2]|0;a[s>>0]=((d[(b+512-m-(m<<2)+q+((p+o|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=q+p|0;b=p;p=c[n+4>>2]|0;a[s+1>>0]=((d[(k+512-m-(m<<2)+p+((o+j|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+4>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=p+o|0;k=o;o=c[n+8>>2]|0;a[s+2>>0]=((d[(b+512-m-(m<<2)+o+((q+j|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+8>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=o+j|0;b=c[n+12>>2]|0;a[s+3>>0]=((d[(k+512-m-(m<<2)+b+((p+q|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+12>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;r=r+-1|0;if(!r)break;else{m=j;s=s+4|0;h=h+16|0;n=n+16|0;j=b;b=m}}e=e+t|0;g=g+(t<<2)|0}l=l+-1|0;if(!l)break;else{e=e+u|0;h=f+20|0;g=g+20|0}}i=B;return}function dc(a,d,e,f,g,h,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|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;x=i;q=a+((j<<4)+h)|0;u=b[d>>1]|0;w=d+2|0;t=b[w>>1]|0;s=e+4|0;p=c[s>>2]<<4;r=e+8|0;o=c[r>>2]<<4;f=h+f|0;m=f+(u>>2)|0;g=j+g|0;n=g+(t>>2)|0;do switch(c[6800+((u&3)<<4)+((t&3)<<2)>>2]|0){case 10:{ac(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l);break}case 6:{cc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 4:{_b(c[e>>2]|0,q,m+-2|0,n,p,o,k,l,0);break}case 1:{Yb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l,0);break}case 2:{Xb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l);break}case 12:{_b(c[e>>2]|0,q,m+-2|0,n,p,o,k,l,1);break}case 14:{cc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}case 7:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,2);break}case 13:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}case 5:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 0:{Ub(c[e>>2]|0,q,m,n,p,o,k,l,16);break}case 9:{bc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 8:{Zb(c[e>>2]|0,q,m+-2|0,n,p,o,k,l);break}case 3:{Yb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l,1);break}case 11:{bc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}default:$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,3)}while(0);u=(h>>>1)+256+(j>>>1<<3)|0;v=a+u|0;t=c[e>>2]|0;m=c[s>>2]|0;j=c[r>>2]|0;r=m<<3;s=j<<3;p=b[d>>1]|0;e=(p>>3)+(f>>>1)|0;q=b[w>>1]|0;o=(q>>3)+(g>>>1)|0;p=p&7;q=q&7;g=k>>>1;h=l>>>1;j=Z(m<<8,j)|0;f=t+j|0;m=(p|0)!=0;n=(q|0)!=0;if(m&n){Wb(f,v,e,o,r,s,p,q,g,h);i=x;return}if(m){Tb(f,v,e,o,r,s,p,g,h);i=x;return}if(n){Vb(f,v,e,o,r,s,q,g,h);i=x;return}else{Ub(f,v,e,o,r,s,g,h,8);Ub(t+((Z(s,r)|0)+j)|0,a+(u+64)|0,e,o,r,s,g,h,8);i=x;return}}function ec(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,j=0;j=i;if(d){nd(c|0,a[b>>0]|0,d|0)|0;c=c+d|0}if(e){h=c+e|0;g=e;d=b;while(1){a[c>>0]=a[d>>0]|0;g=g+-1|0;if(!g)break;else{c=c+1|0;d=d+1|0}}c=h;b=b+e|0}if(!f){i=j;return}nd(c|0,a[b+-1>>0]|0,f|0)|0;i=j;return}function fc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;c=i;hd(b,a,d);i=c;return}function gc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;f=c[a+40>>2]|0;if(f){h=c[a>>2]|0;k=a+32|0;j=0;do{if(((c[h+(j*40|0)+20>>2]|0)+-1|0)>>>0<2){g=c[h+(j*40|0)+12>>2]|0;if(g>>>0>d>>>0)g=g-(c[k>>2]|0)|0;c[h+(j*40|0)+8>>2]=g}j=j+1|0}while((j|0)!=(f|0))}if(!(c[b>>2]|0)){p=0;i=q;return p|0}g=c[b+4>>2]|0;if(g>>>0>=3){p=0;i=q;return p|0}o=a+32|0;p=a+24|0;n=a+4|0;f=d;m=0;a:while(1){b:do if(g>>>0<2){k=c[b+(m*12|0)+8>>2]|0;if(!g){g=f-k|0;if((g|0)<0)g=(c[o>>2]|0)+g|0}else{l=k+f|0;g=c[o>>2]|0;g=l-((l|0)<(g|0)?0:g)|0}if(g>>>0>d>>>0)f=g-(c[o>>2]|0)|0;else f=g;j=c[p>>2]|0;if(!j){f=1;g=37;break a}k=c[a>>2]|0;l=0;while(1){h=c[k+(l*40|0)+20>>2]|0;if((h+-1|0)>>>0<2?(c[k+(l*40|0)+8>>2]|0)==(f|0):0){f=g;break b}l=l+1|0;if(l>>>0>=j>>>0){f=1;g=37;break a}}}else{j=c[b+(m*12|0)+12>>2]|0;h=c[p>>2]|0;if(!h){f=1;g=37;break a}k=c[a>>2]|0;g=0;while(1){if((c[k+(g*40|0)+20>>2]|0)==3?(c[k+(g*40|0)+8>>2]|0)==(j|0):0){h=3;l=g;break b}g=g+1|0;if(g>>>0>=h>>>0){f=1;g=37;break a}}}while(0);if(!((l|0)>-1&h>>>0>1)){f=1;g=37;break}if(m>>>0>>0){k=e;do{j=k;k=k+-1|0;h=c[n>>2]|0;c[h+(j<<2)>>2]=c[h+(k<<2)>>2]}while(k>>>0>m>>>0);k=c[a>>2]|0}c[(c[n>>2]|0)+(m<<2)>>2]=k+(l*40|0);m=m+1|0;if(m>>>0<=e>>>0){g=m;k=m;do{j=c[n>>2]|0;h=c[j+(g<<2)>>2]|0;if((h|0)!=((c[a>>2]|0)+(l*40|0)|0)){c[j+(k<<2)>>2]=h;k=k+1|0}g=g+1|0}while(g>>>0<=e>>>0)}g=c[b+(m*12|0)+4>>2]|0;if(g>>>0>=3){f=0;g=37;break}}if((g|0)==37){i=q;return f|0}return 0}function hc(a,b,d,e,f,g,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var 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,G=0,H=0,I=0,J=0,K=0;K=i;I=c[d>>2]|0;J=c[a+8>>2]|0;if((I|0)!=(c[J>>2]|0)){D=1;i=K;return D|0}B=a+52|0;c[B>>2]=0;G=c[a+56>>2]|0;o=(G|0)==0;H=o&1;do if(!b){c[J+20>>2]=0;c[J+12>>2]=e;c[J+8>>2]=e;c[J+16>>2]=f;c[J+24>>2]=H;if(o){d=a+44|0;c[d>>2]=(c[d>>2]|0)+1;d=0;r=0}else{d=G;r=0}}else{if(g){k=a+20|0;c[k>>2]=0;l=a+16|0;c[l>>2]=0;r=c[a>>2]|0;s=a+44|0;q=0;do{p=r+(q*40|0)+20|0;if((c[p>>2]|0)!=0?(c[p>>2]=0,(c[r+(q*40|0)+24>>2]|0)==0):0)c[s>>2]=(c[s>>2]|0)+-1;q=q+1|0}while((q|0)!=16);a:do if(o){n=c[a+28>>2]|0;m=a+12|0;q=0;while(1){e=0;p=2147483647;o=0;do{if(c[r+(e*40|0)+24>>2]|0){C=c[r+(e*40|0)+16>>2]|0;D=(C|0)<(p|0);p=D?C:p;o=D?r+(e*40|0)|0:o}e=e+1|0}while(e>>>0<=n>>>0);if(!o){d=0;break a}D=c[m>>2]|0;c[D+(q<<4)>>2]=c[o>>2];c[D+(q<<4)+12>>2]=c[o+36>>2];c[D+(q<<4)+4>>2]=c[o+28>>2];c[D+(q<<4)+8>>2]=c[o+32>>2];q=q+1|0;c[l>>2]=q;c[o+24>>2]=0;if(c[o+20>>2]|0)continue;c[s>>2]=(c[s>>2]|0)+-1}}else d=G;while(0);p=a+40|0;c[p>>2]=0;o=a+36|0;c[o>>2]=65535;c[a+48>>2]=0;if(!(c[b>>2]|d))d=0;else{c[l>>2]=0;c[k>>2]=0}r=(c[b+4>>2]|0)==0;c[J+20>>2]=r?2:3;c[o>>2]=r?65535:0;c[J+12>>2]=0;c[J+8>>2]=0;c[J+16>>2]=0;c[J+24>>2]=H;c[s>>2]=1;c[p>>2]=1;r=0;break}if(!(c[b+8>>2]|0)){d=a+40|0;q=c[d>>2]|0;p=c[a+24>>2]|0;if(q>>>0>=p>>>0)if(q){l=c[a>>2]|0;m=0;o=-1;n=0;do{if(((c[l+(m*40|0)+20>>2]|0)+-1|0)>>>0<2){D=c[l+(m*40|0)+8>>2]|0;C=(D|0)<(n|0)|(o|0)==-1;o=C?m:o;n=C?D:n}m=m+1|0}while((m|0)!=(q|0));if((o|0)>-1){q=q+-1|0;c[l+(o*40|0)+20>>2]=0;c[d>>2]=q;if(!(c[l+(o*40|0)+24>>2]|0)){d=a+44|0;c[d>>2]=(c[d>>2]|0)+-1;d=G;n=0}else{d=G;n=0}}else{d=G;n=1}}else{q=0;d=G;n=1}else{d=G;n=0}}else{E=a+24|0;C=a+40|0;v=a+44|0;x=a+36|0;A=a+48|0;u=a+28|0;y=a+16|0;z=a+12|0;r=G;d=G;t=0;w=0;b:while(1){switch(c[b+(t*20|0)+12>>2]|0){case 4:{l=c[b+(t*20|0)+28>>2]|0;c[x>>2]=l;m=c[E>>2]|0;if(!m)s=w;else{n=c[a>>2]|0;s=l;o=0;do{k=n+(o*40|0)+20|0;do if((c[k>>2]|0)==3){if((c[n+(o*40|0)+8>>2]|0)>>>0<=l>>>0)if((s|0)==65535)s=65535;else break;c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[n+(o*40|0)+24>>2]|0))c[v>>2]=(c[v>>2]|0)+-1}while(0);o=o+1|0}while((o|0)!=(m|0));s=w}break}case 1:{n=e-(c[b+(t*20|0)+16>>2]|0)|0;l=c[E>>2]|0;if(!l){n=1;break b}m=c[a>>2]|0;s=0;while(1){k=m+(s*40|0)+20|0;if(((c[k>>2]|0)+-1|0)>>>0<2?(c[m+(s*40|0)+8>>2]|0)==(n|0):0)break;s=s+1|0;if(s>>>0>=l>>>0){n=1;break b}}if((s|0)<0){n=1;break b}c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[m+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=w}else s=w;break}case 6:{m=c[b+(t*20|0)+24>>2]|0;s=c[x>>2]|0;if((s|0)==65535|s>>>0>>0){n=1;F=101;break b}r=c[E>>2]|0;c:do if(r){l=c[a>>2]|0;s=0;while(1){k=l+(s*40|0)+20|0;if((c[k>>2]|0)==3?(c[l+(s*40|0)+8>>2]|0)==(m|0):0)break;s=s+1|0;if(s>>>0>=r>>>0){F=88;break c}}c[k>>2]=0;k=(c[C>>2]|0)+-1|0;c[C>>2]=k;if(!(c[l+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=k}else s=k}else{r=0;F=88}while(0);if((F|0)==88){F=0;s=c[C>>2]|0}if(s>>>0>=r>>>0){n=1;F=101;break b}c[J+12>>2]=e;c[J+8>>2]=m;c[J+16>>2]=f;c[J+20>>2]=3;c[J+24>>2]=H;c[C>>2]=s+1;c[v>>2]=(c[v>>2]|0)+1;r=G;d=G;s=1;break}case 2:{l=c[b+(t*20|0)+20>>2]|0;m=c[E>>2]|0;if(!m){n=1;break b}n=c[a>>2]|0;s=0;while(1){k=n+(s*40|0)+20|0;if((c[k>>2]|0)==3?(c[n+(s*40|0)+8>>2]|0)==(l|0):0)break;s=s+1|0;if(s>>>0>=m>>>0){n=1;break b}}if((s|0)<0){n=1;break b}c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[n+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=w}else s=w;break}case 3:{s=c[b+(t*20|0)+16>>2]|0;n=c[b+(t*20|0)+24>>2]|0;k=c[x>>2]|0;if((k|0)==65535|k>>>0>>0){n=1;break b}o=c[E>>2]|0;if(!o){n=1;break b}p=c[a>>2]|0;k=0;while(1){m=p+(k*40|0)+20|0;if((c[m>>2]|0)==3?(c[p+(k*40|0)+8>>2]|0)==(n|0):0){F=47;break}l=k+1|0;if(l>>>0>>0)k=l;else break}if((F|0)==47?(F=0,c[m>>2]=0,c[C>>2]=(c[C>>2]|0)+-1,(c[p+(k*40|0)+24>>2]|0)==0):0)c[v>>2]=(c[v>>2]|0)+-1;m=e-s|0;s=0;while(1){l=p+(s*40|0)+20|0;k=c[l>>2]|0;if((k+-1|0)>>>0<2?(D=p+(s*40|0)+8|0,(c[D>>2]|0)==(m|0)):0)break;s=s+1|0;if(s>>>0>=o>>>0){n=1;break b}}if(!((s|0)>-1&k>>>0>1)){n=1;break b}c[l>>2]=3;c[D>>2]=n;s=w;break}case 5:{n=c[a>>2]|0;q=0;do{p=n+(q*40|0)+20|0;if((c[p>>2]|0)!=0?(c[p>>2]=0,(c[n+(q*40|0)+24>>2]|0)==0):0)c[v>>2]=(c[v>>2]|0)+-1;q=q+1|0}while((q|0)!=16);d:do if(!d){l=c[u>>2]|0;m=r;while(1){d=0;s=2147483647;k=0;do{if(c[n+(d*40|0)+24>>2]|0){o=c[n+(d*40|0)+16>>2]|0;e=(o|0)<(s|0);s=e?o:s;k=e?n+(d*40|0)|0:k}d=d+1|0}while(d>>>0<=l>>>0);if(!k){r=m;d=0;break d}s=c[y>>2]|0;d=c[z>>2]|0;c[d+(s<<4)>>2]=c[k>>2];c[d+(s<<4)+12>>2]=c[k+36>>2];c[d+(s<<4)+4>>2]=c[k+28>>2];c[d+(s<<4)+8>>2]=c[k+32>>2];c[y>>2]=s+1;c[k+24>>2]=0;if(!(c[k+20>>2]|0))c[v>>2]=(c[v>>2]|0)+-1;if(!m)m=0;else{r=m;d=m;break}}}while(0);c[C>>2]=0;c[x>>2]=65535;c[A>>2]=0;c[B>>2]=1;e=0;s=w;break}case 0:{n=0;F=101;break b}default:{n=1;break b}}t=t+1|0;w=s}if(w){r=n;break}q=c[C>>2]|0;p=c[E>>2]|0}if(q>>>0

>>0){c[J+12>>2]=e;c[J+8>>2]=e;c[J+16>>2]=f;c[J+20>>2]=2;c[J+24>>2]=H;r=a+44|0;c[r>>2]=(c[r>>2]|0)+1;c[a+40>>2]=q+1;r=n}else r=1}while(0);c[J+36>>2]=g;c[J+28>>2]=h;c[J+32>>2]=j;if(!d){o=a+44|0;d=c[o>>2]|0;k=c[a+28>>2]|0;if(d>>>0>k>>>0){p=a+16|0;q=a+12|0;do{n=c[a>>2]|0;e=0;l=2147483647;m=0;do{if(c[n+(e*40|0)+24>>2]|0){C=c[n+(e*40|0)+16>>2]|0;D=(C|0)<(l|0);l=D?C:l;m=D?n+(e*40|0)|0:m}e=e+1|0}while(e>>>0<=k>>>0);if((m|0)!=0?(D=c[p>>2]|0,C=c[q>>2]|0,c[C+(D<<4)>>2]=c[m>>2],c[C+(D<<4)+12>>2]=c[m+36>>2],c[C+(D<<4)+4>>2]=c[m+28>>2],c[C+(D<<4)+8>>2]=c[m+32>>2],c[p>>2]=D+1,c[m+24>>2]=0,(c[m+20>>2]|0)==0):0){d=d+-1|0;c[o>>2]=d}}while(d>>>0>k>>>0)}}else{k=a+16|0;D=c[k>>2]|0;C=c[a+12>>2]|0;c[C+(D<<4)>>2]=I;c[C+(D<<4)+12>>2]=g;c[C+(D<<4)+4>>2]=h;c[C+(D<<4)+8>>2]=j;c[k>>2]=D+1;k=c[a+28>>2]|0}rc(c[a>>2]|0,k+1|0);D=r;i=K;return D|0}function ic(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;if((b>>>0<=16?(d=c[(c[a+4>>2]|0)+(b<<2)>>2]|0,(d|0)!=0):0)?(c[d+20>>2]|0)>>>0>1:0)d=c[d>>2]|0;else d=0;i=e;return d|0}function jc(a){a=a|0;var b=0;b=(c[a>>2]|0)+((c[a+28>>2]|0)*40|0)|0;c[a+8>>2]=b;return c[b>>2]|0}function kc(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,j=0;j=i;c[a+36>>2]=65535;e=e>>>0>1?e:1;c[a+24>>2]=e;h=a+28|0;c[h>>2]=(g|0)==0?d:e;c[a+32>>2]=f;c[a+56>>2]=g;c[a+44>>2]=0;c[a+40>>2]=0;c[a+48>>2]=0;g=fd(680)|0;c[a>>2]=g;if(!g){g=65535;i=j;return g|0}id(g,0,680);a:do if((c[h>>2]|0)!=-1){f=b*384|47;e=0;while(1){d=fd(f)|0;g=c[a>>2]|0;c[g+(e*40|0)+4>>2]=d;if(!d){g=65535;break}c[g+(e*40|0)>>2]=d+(0-d&15);e=e+1|0;if(e>>>0>=((c[h>>2]|0)+1|0)>>>0)break a}i=j;return g|0}while(0);g=a+4|0;c[g>>2]=fd(68)|0;f=fd((c[h>>2]<<4)+16|0)|0;c[a+12>>2]=f;g=c[g>>2]|0;if((g|0)==0|(f|0)==0){g=65535;i=j;return g|0}id(g,0,68);c[a+20>>2]=0;c[a+16>>2]=0;g=0;i=j;return g|0}function lc(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,j=0,k=0,l=0;l=i;h=c[a>>2]|0;if(h){k=a+28|0;if((c[k>>2]|0)!=-1){j=0;do{gd(c[h+(j*40|0)+4>>2]|0);h=c[a>>2]|0;c[h+(j*40|0)+4>>2]=0;j=j+1|0}while(j>>>0<((c[k>>2]|0)+1|0)>>>0)}}else h=0;gd(h);c[a>>2]=0;h=a+4|0;gd(c[h>>2]|0);c[h>>2]=0;h=a+12|0;gd(c[h>>2]|0);c[h>>2]=0;h=kc(a,b,d,e,f,g)|0;i=l;return h|0}function mc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;b=c[a>>2]|0;if(b){e=a+28|0;if((c[e>>2]|0)!=-1){d=0;do{gd(c[b+(d*40|0)+4>>2]|0);b=c[a>>2]|0;c[b+(d*40|0)+4>>2]=0;d=d+1|0}while(d>>>0<((c[e>>2]|0)+1|0)>>>0)}}else b=0;gd(b);c[a>>2]=0;b=a+4|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+12|0;gd(c[b>>2]|0);c[b>>2]=0;i=f;return}function nc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;b=c[a+40>>2]|0;if(!b){i=f;return}e=a+4|0;d=0;do{c[(c[e>>2]|0)+(d<<2)>>2]=(c[a>>2]|0)+(d*40|0);d=d+1|0}while(d>>>0>>0);i=f;return}function oc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=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;y=i;v=a+16|0;c[v>>2]=0;c[a+20>>2]=0;if(!e){b=0;i=y;return b|0}x=a+48|0;e=c[x>>2]|0;f=(e|0)==(b|0);a:do if(!f?(u=a+32|0,l=c[u>>2]|0,k=((e+1|0)>>>0)%(l>>>0)|0,(k|0)!=(b|0)):0){t=a+28|0;w=c[(c[a>>2]|0)+((c[t>>2]|0)*40|0)>>2]|0;r=a+40|0;p=a+24|0;o=a+44|0;q=a+56|0;s=a+12|0;n=k;while(1){k=c[r>>2]|0;if(!k)k=0;else{j=c[a>>2]|0;h=0;do{if(((c[j+(h*40|0)+20>>2]|0)+-1|0)>>>0<2){e=c[j+(h*40|0)+12>>2]|0;c[j+(h*40|0)+8>>2]=e-(e>>>0>n>>>0?l:0)}h=h+1|0}while((h|0)!=(k|0))}if(k>>>0>=(c[p>>2]|0)>>>0){if(!k){e=1;g=46;break}f=c[a>>2]|0;h=0;l=-1;j=0;while(1){if(((c[f+(h*40|0)+20>>2]|0)+-1|0)>>>0<2){e=c[f+(h*40|0)+8>>2]|0;m=(e|0)<(j|0)|(l|0)==-1;g=m?h:l;j=m?e:j}else g=l;h=h+1|0;if((h|0)==(k|0))break;else l=g}if((g|0)<=-1){e=1;g=46;break}l=k+-1|0;c[f+(g*40|0)+20>>2]=0;c[r>>2]=l;if(!(c[f+(g*40|0)+24>>2]|0)){c[o>>2]=(c[o>>2]|0)+-1;k=l}else k=l}l=c[o>>2]|0;m=c[t>>2]|0;if(l>>>0>=m>>>0){e=(c[q>>2]|0)==0;do if(e){g=c[a>>2]|0;f=0;j=2147483647;h=0;do{if(c[g+(f*40|0)+24>>2]|0){A=c[g+(f*40|0)+16>>2]|0;z=(A|0)<(j|0);j=z?A:j;h=z?g+(f*40|0)|0:h}f=f+1|0}while(f>>>0<=m>>>0);if((h|0)!=0?(f=c[v>>2]|0,g=c[s>>2]|0,c[g+(f<<4)>>2]=c[h>>2],c[g+(f<<4)+12>>2]=c[h+36>>2],c[g+(f<<4)+4>>2]=c[h+28>>2],c[g+(f<<4)+8>>2]=c[h+32>>2],c[v>>2]=f+1,c[h+24>>2]=0,(c[h+20>>2]|0)==0):0){l=l+-1|0;c[o>>2]=l}}while(l>>>0>=m>>>0)}e=c[a>>2]|0;c[e+(m*40|0)+20>>2]=1;c[e+(m*40|0)+12>>2]=n;c[e+(m*40|0)+8>>2]=n;c[e+(m*40|0)+16>>2]=0;c[e+(m*40|0)+24>>2]=0;c[o>>2]=l+1;c[r>>2]=k+1;rc(e,m+1|0);l=c[u>>2]|0;n=((n+1|0)>>>0)%(l>>>0)|0;if((n|0)==(b|0)){g=31;break}}if((g|0)==31){g=c[v>>2]|0;if(!g){g=41;break}e=c[s>>2]|0;h=c[t>>2]|0;j=c[a>>2]|0;l=j+(h*40|0)|0;k=c[l>>2]|0;f=0;while(1){if((c[e+(f<<4)>>2]|0)==(k|0))break;f=f+1|0;if(f>>>0>=g>>>0){g=41;break a}}if(!h){g=41;break}else e=0;while(1){f=j+(e*40|0)|0;e=e+1|0;if((c[f>>2]|0)==(w|0))break;if(e>>>0>=h>>>0){g=41;break a}}c[f>>2]=k;c[l>>2]=w;g=41;break}else if((g|0)==46){i=y;return e|0}}else g=39;while(0);if((g|0)==39)if(d)if(f){b=1;i=y;return b|0}else g=41;do if((g|0)==41){if(!d){e=c[x>>2]|0;break}c[x>>2]=b;b=0;i=y;return b|0}while(0);if((e|0)==(b|0)){b=0;i=y;return b|0}a=c[a+32>>2]|0;c[x>>2]=((b+-1+a|0)>>>0)%(a>>>0)|0;b=0;i=y;return b|0}function pc(a){a=a|0;var b=0,d=0,e=0;e=i;d=a+20|0;b=c[d>>2]|0;if(b>>>0>=(c[a+16>>2]|0)>>>0){b=0;i=e;return b|0}a=c[a+12>>2]|0;c[d>>2]=b+1;b=a+(b<<4)|0;i=e;return b|0}function qc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;k=i;f=c[a>>2]|0;if(!f){i=k;return}c[a+60>>2]=1;if(c[a+56>>2]|0){i=k;return}g=c[a+28>>2]|0;h=a+16|0;j=a+12|0;e=a+44|0;a=0;b=2147483647;d=0;while(1){if(c[f+(a*40|0)+24>>2]|0){m=c[f+(a*40|0)+16>>2]|0;l=(m|0)<(b|0);b=l?m:b;d=l?f+(a*40|0)|0:d}a=a+1|0;if(a>>>0<=g>>>0)continue;if(!d)break;l=c[h>>2]|0;b=c[j>>2]|0;c[b+(l<<4)>>2]=c[d>>2];c[b+(l<<4)+12>>2]=c[d+36>>2];c[b+(l<<4)+4>>2]=c[d+28>>2];c[b+(l<<4)+8>>2]=c[d+32>>2];c[h>>2]=l+1;c[d+24>>2]=0;if(c[d+20>>2]|0){a=0;b=2147483647;d=0;continue}c[e>>2]=(c[e>>2]|0)+-1;a=0;b=2147483647;d=0}i=k;return}function rc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=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;v=i;i=i+32|0;q=v+16|0;t=v;o=7;do{if(o>>>0>>0){n=o;do{m=a+(n*40|0)|0;l=c[m>>2]|0;m=c[m+4>>2]|0;p=c[a+(n*40|0)+8>>2]|0;k=a+(n*40|0)+12|0;s=c[k+4>>2]|0;r=q;c[r>>2]=c[k>>2];c[r+4>>2]=s;r=c[a+(n*40|0)+20>>2]|0;s=c[a+(n*40|0)+24>>2]|0;k=a+(n*40|0)+28|0;c[t+0>>2]=c[k+0>>2];c[t+4>>2]=c[k+4>>2];c[t+8>>2]=c[k+8>>2];a:do if(n>>>0>>0){d=n;u=8}else{f=(s|0)==0;j=r+-1|0;k=j>>>0<2;b:do if(!r){e=n;while(1){d=e-o|0;if(c[a+(d*40|0)+20>>2]|0){d=e;break b}if((c[a+(d*40|0)+24>>2]|0)!=0|f){d=e;break b}e=a+(e*40|0)+0|0;g=a+(d*40|0)+0|0;h=e+40|0;do{c[e>>2]=c[g>>2];e=e+4|0;g=g+4|0}while((e|0)<(h|0));if(d>>>0>>0){u=8;break a}else e=d}}else{d=n;while(1){f=d-o|0;e=c[a+(f*40|0)+20>>2]|0;do if(e){e=e+-1|0;if((e|j)>>>0<2){e=c[a+(f*40|0)+8>>2]|0;if((e|0)>(p|0))break b;d=a+(d*40|0)|0;if((e|0)<(p|0))break;else break a}if(e>>>0<2)break b;if(!k?(c[a+(f*40|0)+8>>2]|0)<=(p|0):0)break b;else u=16}else u=16;while(0);if((u|0)==16){u=0;d=a+(d*40|0)|0}e=d+0|0;g=a+(f*40|0)+0|0;h=e+40|0;do{c[e>>2]=c[g>>2];e=e+4|0;g=g+4|0}while((e|0)<(h|0));if(f>>>0>>0){d=f;u=8;break a}else d=f}}while(0);d=a+(d*40|0)|0}while(0);if((u|0)==8){u=0;d=a+(d*40|0)|0}k=d;c[k>>2]=l;c[k+4>>2]=m;c[d+8>>2]=p;k=q;l=c[k+4>>2]|0;m=d+12|0;c[m>>2]=c[k>>2];c[m+4>>2]=l;c[d+20>>2]=r;c[d+24>>2]=s;m=d+28|0;c[m+0>>2]=c[t+0>>2];c[m+4>>2]=c[t+4>>2];c[m+8>>2]=c[t+8>>2];n=n+1|0}while((n|0)!=(b|0))}o=o>>>1}while((o|0)!=0);i=v;return}function sc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;e=c[a+4>>2]|0;f=c[a+16>>2]|0;g=c[a+20>>2]|0;j=e<<2;k=b+256|0;h=16;a=c[a+12>>2]|0;d=b;while(1){m=c[d+4>>2]|0;c[a>>2]=c[d>>2];c[a+4>>2]=m;m=c[d+12>>2]|0;c[a+8>>2]=c[d+8>>2];c[a+12>>2]=m;h=h+-1|0;if(!h)break;else{a=a+(j<<2)|0;d=d+16|0}}j=e<<1&2147483646;h=c[b+260>>2]|0;c[f>>2]=c[k>>2];c[f+4>>2]=h;k=c[b+268>>2]|0;c[f+(j<<2)>>2]=c[b+264>>2];c[f+((j|1)<<2)>>2]=k;k=e<<2;h=c[b+276>>2]|0;c[f+(k<<2)>>2]=c[b+272>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+284>>2]|0;c[f+(k<<2)>>2]=c[b+280>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+292>>2]|0;c[f+(k<<2)>>2]=c[b+288>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+300>>2]|0;c[f+(k<<2)>>2]=c[b+296>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+308>>2]|0;c[f+(k<<2)>>2]=c[b+304>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+316>>2]|0;c[f+(k<<2)>>2]=c[b+312>>2];c[f+((k|1)<<2)>>2]=h;k=c[b+324>>2]|0;c[g>>2]=c[b+320>>2];c[g+4>>2]=k;k=c[b+332>>2]|0;c[g+(j<<2)>>2]=c[b+328>>2];c[g+((j|1)<<2)>>2]=k;k=e<<2;h=c[b+340>>2]|0;c[g+(k<<2)>>2]=c[b+336>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+348>>2]|0;c[g+(k<<2)>>2]=c[b+344>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+356>>2]|0;c[g+(k<<2)>>2]=c[b+352>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+364>>2]|0;c[g+(k<<2)>>2]=c[b+360>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+372>>2]|0;c[g+(k<<2)>>2]=c[b+368>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;j=c[b+380>>2]|0;c[g+(k<<2)>>2]=c[b+376>>2];c[g+((k|1)<<2)>>2]=j;i=l;return}function tc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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;y=i;r=c[b+4>>2]|0;s=Z(c[b+8>>2]|0,r)|0;w=(e>>>0)%(r>>>0)|0;x=c[b>>2]|0;u=e-w|0;b=(u<<8)+(w<<4)|0;v=s<<8;w=w<<3;p=r<<4;o=r<<2&1073741820;l=o<<1;m=l+o|0;n=0;do{k=c[3344+(n<<2)>>2]|0;j=c[3408+(n<<2)>>2]|0;e=(j<<4)+k|0;h=f+e|0;j=b+k+(Z(j,p)|0)|0;k=x+j|0;q=c[g+(n<<6)>>2]|0;if((q|0)==16777215){j=c[f+(e+16)>>2]|0;c[k>>2]=c[h>>2];c[k+(o<<2)>>2]=j;j=c[f+(e+48)>>2]|0;c[k+(l<<2)>>2]=c[f+(e+32)>>2];c[k+(m<<2)>>2]=j}else{A=d[f+(e+1)>>0]|0;z=c[g+(n<<6)+4>>2]|0;a[k>>0]=a[3472+(q+512+(d[h>>0]|0))>>0]|0;q=d[f+(e+2)>>0]|0;t=c[g+(n<<6)+8>>2]|0;a[x+(j+1)>>0]=a[3472+((A|512)+z)>>0]|0;k=d[f+(e+3)>>0]|0;h=c[g+(n<<6)+12>>2]|0;a[x+(j+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(j+3)>>0]=a[3472+(h+512+k)>>0]|0;k=j+p|0;h=d[f+(e+17)>>0]|0;j=c[g+(n<<6)+20>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+16>>2]|0)+512+(d[f+(e+16)>>0]|0))>>0]|0;q=d[f+(e+18)>>0]|0;t=c[g+(n<<6)+24>>2]|0;a[x+(k+1)>>0]=a[3472+((h|512)+j)>>0]|0;j=d[f+(e+19)>>0]|0;h=c[g+(n<<6)+28>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(h+512+j)>>0]|0;k=k+p|0;j=d[f+(e+33)>>0]|0;h=c[g+(n<<6)+36>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+32>>2]|0)+512+(d[f+(e+32)>>0]|0))>>0]|0;q=d[f+(e+34)>>0]|0;t=c[g+(n<<6)+40>>2]|0;a[x+(k+1)>>0]=a[3472+((j|512)+h)>>0]|0;h=d[f+(e+35)>>0]|0;j=c[g+(n<<6)+44>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(j+512+h)>>0]|0;k=k+p|0;h=d[f+(e+49)>>0]|0;j=c[g+(n<<6)+52>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+48>>2]|0)+512+(d[f+(e+48)>>0]|0))>>0]|0;q=d[f+(e+50)>>0]|0;t=c[g+(n<<6)+56>>2]|0;a[x+(k+1)>>0]=a[3472+((h|512)+j)>>0]|0;j=d[f+(e+51)>>0]|0;h=c[g+(n<<6)+60>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(h+512+j)>>0]|0}n=n+1|0}while((n|0)!=16);t=s<<6;s=r<<3&2147483640;r=f+256|0;f=f+320|0;l=w+v+(u<<6)|0;p=s>>>2;j=s>>>1;k=j+p|0;o=16;do{q=o&3;h=c[3344+(q<<2)>>2]|0;q=c[3408+(q<<2)>>2]|0;e=o>>>0>19;m=e?f:r;n=(q<<3)+h|0;b=m+n|0;q=l+(e?t:0)+h+(Z(q,s)|0)|0;h=x+q|0;e=c[g+(o<<6)>>2]|0;if((e|0)==16777215){z=c[m+(n+8)>>2]|0;c[h>>2]=c[b>>2];c[h+(p<<2)>>2]=z;z=c[m+(n+24)>>2]|0;c[h+(j<<2)>>2]=c[m+(n+16)>>2];c[h+(k<<2)>>2]=z}else{v=d[m+(n+1)>>0]|0;z=c[g+(o<<6)+4>>2]|0;a[h>>0]=a[3472+(e+512+(d[b>>0]|0))>>0]|0;w=d[m+(n+2)>>0]|0;u=c[g+(o<<6)+8>>2]|0;a[x+(q+1)>>0]=a[3472+((v|512)+z)>>0]|0;z=d[m+(n+3)>>0]|0;v=c[g+(o<<6)+12>>2]|0;a[x+(q+2)>>0]=a[3472+(u+512+w)>>0]|0;a[x+(q+3)>>0]=a[3472+(v+512+z)>>0]|0;z=q+s|0;v=d[m+(n+9)>>0]|0;w=c[g+(o<<6)+20>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+16>>2]|0)+512+(d[m+(n+8)>>0]|0))>>0]|0;u=d[m+(n+10)>>0]|0;q=c[g+(o<<6)+24>>2]|0;a[x+(z+1)>>0]=a[3472+((v|512)+w)>>0]|0;w=d[m+(n+11)>>0]|0;v=c[g+(o<<6)+28>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(v+512+w)>>0]|0;z=z+s|0;w=d[m+(n+17)>>0]|0;v=c[g+(o<<6)+36>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+32>>2]|0)+512+(d[m+(n+16)>>0]|0))>>0]|0;u=d[m+(n+18)>>0]|0;q=c[g+(o<<6)+40>>2]|0;a[x+(z+1)>>0]=a[3472+((w|512)+v)>>0]|0;v=d[m+(n+19)>>0]|0;w=c[g+(o<<6)+44>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(w+512+v)>>0]|0;z=z+s|0;v=d[m+(n+25)>>0]|0;w=c[g+(o<<6)+52>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+48>>2]|0)+512+(d[m+(n+24)>>0]|0))>>0]|0;u=d[m+(n+26)>>0]|0;q=c[g+(o<<6)+56>>2]|0;a[x+(z+1)>>0]=a[3472+((v|512)+w)>>0]|0;w=d[m+(n+27)>>0]|0;v=c[g+(o<<6)+60>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(v+512+w)>>0]|0}o=o+1|0}while((o|0)!=24);i=y;return}function uc(e,f){e=e|0;f=f|0;var g=0,h=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,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,_=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,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;bb=i;i=i+176|0;ia=bb+40|0;La=bb;ea=c[e+4>>2]|0;ka=e+8|0;Wa=c[ka>>2]|0;g=Z(Wa,ea)|0;if(!Wa){i=bb;return}Za=ia+24|0;_a=ia+16|0;$a=ia+8|0;la=ia+100|0;ma=ia+68|0;na=ia+36|0;oa=ia+4|0;Ma=ia+120|0;Na=ia+112|0;Pa=ia+104|0;Qa=ia+96|0;Ra=ia+88|0;Sa=ia+80|0;Ta=ia+72|0;Ua=ia+64|0;Va=ia+56|0;Wa=ia+48|0;Xa=ia+40|0;Ya=ia+32|0;pa=ia+124|0;qa=ia+116|0;ra=ia+108|0;sa=ia+92|0;ta=ia+84|0;ua=ia+76|0;va=ia+60|0;wa=ia+52|0;xa=ia+44|0;ya=ia+28|0;za=ia+20|0;Aa=ia+12|0;ha=La+28|0;ja=La+32|0;Ka=La+24|0;Da=ea<<4;Ja=0-Da|0;Ca=Ja<<1;Ha=Z(ea,-48)|0;Ia=ea<<5;Ea=Ja<<2;Ga=ea*48|0;Ba=ea<<6;ga=La+24|0;fa=La+12|0;Fa=g<<8;ba=g<<6;ca=ea<<3;W=Da|4;Y=La+16|0;$=La+20|0;da=La+12|0;X=La+4|0;_=La+8|0;U=0;aa=0;V=f;while(1){f=c[V+8>>2]|0;do if((f|0)!=1){T=V+200|0;n=c[T>>2]|0;do if(!n)g=1;else{if((f|0)==2?(c[V+4>>2]|0)!=(c[n+4>>2]|0):0){g=1;break}g=5}while(0);S=V+204|0;l=c[S>>2]|0;do if(l){if((f|0)==2?(c[V+4>>2]|0)!=(c[l+4>>2]|0):0)break;g=g|2}while(0);R=(g&2|0)==0;do if(R){c[Za>>2]=0;c[_a>>2]=0;c[$a>>2]=0;c[ia>>2]=0;m=0}else{if((c[V>>2]|0)>>>0<=5?(c[l>>2]|0)>>>0<=5:0){if((b[V+28>>1]|0)==0?(b[l+48>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[l+124>>2]|0)?(B=(b[V+132>>1]|0)-(b[l+172>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){h=(b[V+134>>1]|0)-(b[l+174>>1]|0)|0;h=(((h|0)>-1?h:0-h|0)|0)>3&1}else h=1;else h=2;c[ia>>2]=h;if((b[V+30>>1]|0)==0?(b[l+50>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[l+124>>2]|0)?(B=(b[V+136>>1]|0)-(b[l+176>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){j=(b[V+138>>1]|0)-(b[l+178>>1]|0)|0;j=(((j|0)>-1?j:0-j|0)|0)>3&1}else j=1;else j=2;c[$a>>2]=j;if((b[V+36>>1]|0)==0?(b[l+56>>1]|0)==0:0)if((c[V+120>>2]|0)==(c[l+128>>2]|0)?(B=(b[V+148>>1]|0)-(b[l+188>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){k=(b[V+150>>1]|0)-(b[l+190>>1]|0)|0;k=(((k|0)>-1?k:0-k|0)|0)>3&1}else k=1;else k=2;c[_a>>2]=k;if((b[V+38>>1]|0)==0?(b[l+58>>1]|0)==0:0)if((c[V+120>>2]|0)==(c[l+128>>2]|0)?(B=(b[V+152>>1]|0)-(b[l+192>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){f=(b[V+154>>1]|0)-(b[l+194>>1]|0)|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=1;else f=2;c[Za>>2]=f;m=(j|h|k|f|0)!=0&1;break}c[Za>>2]=4;c[_a>>2]=4;c[$a>>2]=4;c[ia>>2]=4;m=1}while(0);Q=(g&4|0)==0;do if(Q){c[la>>2]=0;c[ma>>2]=0;c[na>>2]=0;c[oa>>2]=0;k=c[V>>2]|0}else{k=c[V>>2]|0;if(k>>>0<=5?(c[n>>2]|0)>>>0<=5:0){if((b[V+28>>1]|0)==0?(b[n+38>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[n+120>>2]|0)?(B=(b[V+132>>1]|0)-(b[n+152>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){j=(b[V+134>>1]|0)-(b[n+154>>1]|0)|0;j=(((j|0)>-1?j:0-j|0)|0)>3&1}else j=1;else j=2;c[oa>>2]=j;if((b[V+32>>1]|0)==0?(b[n+42>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[n+120>>2]|0)?(B=(b[V+140>>1]|0)-(b[n+160>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){h=(b[V+142>>1]|0)-(b[n+162>>1]|0)|0;h=(((h|0)>-1?h:0-h|0)|0)>3&1}else h=1;else h=2;c[na>>2]=h;if((b[V+44>>1]|0)==0?(b[n+54>>1]|0)==0:0)if((c[V+124>>2]|0)==(c[n+128>>2]|0)?(B=(b[V+164>>1]|0)-(b[n+184>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){f=(b[V+166>>1]|0)-(b[n+186>>1]|0)|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=1;else f=2;c[ma>>2]=f;if((b[V+48>>1]|0)==0?(b[n+58>>1]|0)==0:0)if((c[V+124>>2]|0)==(c[n+128>>2]|0)?(B=(b[V+172>>1]|0)-(b[n+192>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){l=(b[V+174>>1]|0)-(b[n+194>>1]|0)|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=1;else l=2;c[la>>2]=l;if(m)break;m=(h|j|f|l|0)!=0&1;break}c[la>>2]=4;c[ma>>2]=4;c[na>>2]=4;c[oa>>2]=4;m=1}while(0);if(k>>>0<=5){do if((db(k)|0)!=1){f=c[V>>2]|0;if((f|0)==2){w=V+28|0;x=b[V+32>>1]|0;if(!(x<<16>>16))f=(b[w>>1]|0)!=0?2:0;else f=2;c[Ya>>2]=f;q=b[V+34>>1]|0;A=q<<16>>16==0;if(A)f=(b[V+30>>1]|0)!=0?2:0;else f=2;c[Xa>>2]=f;g=b[V+40>>1]|0;z=g<<16>>16==0;if(z)l=(b[V+36>>1]|0)!=0?2:0;else l=2;c[Wa>>2]=l;v=b[V+42>>1]|0;y=v<<16>>16==0;if(y)l=(b[V+38>>1]|0)!=0?2:0;else l=2;c[Va>>2]=l;h=b[V+48>>1]|0;if(!(h<<16>>16))l=(b[V+44>>1]|0)!=0?2:0;else l=2;c[Qa>>2]=l;k=b[V+50>>1]|0;B=k<<16>>16==0;if(B)l=(b[V+46>>1]|0)!=0?2:0;else l=2;c[Pa>>2]=l;p=b[V+56>>1]|0;f=p<<16>>16==0;if(f)n=(b[V+52>>1]|0)!=0?2:0;else n=2;c[Na>>2]=n;j=(b[V+58>>1]|0)==0;if(j)n=(b[V+54>>1]|0)!=0?2:0;else n=2;c[Ma>>2]=n;r=b[V+44>>1]|0;o=b[V+166>>1]|0;n=b[V+142>>1]|0;do if(!((r|x)<<16>>16)){u=(b[V+164>>1]|0)-(b[V+140>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){n=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){n=1;break}n=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else n=2;while(0);c[Ua>>2]=n;s=b[V+46>>1]|0;o=b[V+170>>1]|0;n=b[V+146>>1]|0;do if(!((s|q)<<16>>16)){u=(b[V+168>>1]|0)-(b[V+144>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[Ta>>2]=o;t=b[V+52>>1]|0;o=b[V+182>>1]|0;n=b[V+158>>1]|0;do if(!((t|g)<<16>>16)){u=(b[V+180>>1]|0)-(b[V+156>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Sa>>2]=o;u=b[V+54>>1]|0;o=b[V+186>>1]|0;n=b[V+162>>1]|0;do if(!((u|v)<<16>>16)){v=(b[V+184>>1]|0)-(b[V+160>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){o=1;break}v=o-n|0;if((((v|0)>-1?v:0-v|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Ra>>2]=o;l=b[V+30>>1]|0;if(!(l<<16>>16))o=(b[w>>1]|0)!=0?2:0;else o=2;c[Aa>>2]=o;n=b[V+36>>1]|0;if(!(n<<16>>16))o=l<<16>>16!=0?2:0;else o=2;c[za>>2]=o;if(!(b[V+38>>1]|0))o=n<<16>>16!=0?2:0;else o=2;c[ya>>2]=o;if(A)n=x<<16>>16!=0?2:0;else n=2;c[xa>>2]=n;if(z)l=q<<16>>16!=0?2:0;else l=2;c[wa>>2]=l;if(y)l=g<<16>>16!=0?2:0;else l=2;c[va>>2]=l;if(!(s<<16>>16))l=r<<16>>16!=0?2:0;else l=2;c[ua>>2]=l;if(!(t<<16>>16))l=s<<16>>16!=0?2:0;else l=2;c[ta>>2]=l;if(!(u<<16>>16))l=t<<16>>16!=0?2:0;else l=2;c[sa>>2]=l;if(B)h=h<<16>>16!=0?2:0;else h=2;c[ra>>2]=h;if(f)f=k<<16>>16!=0?2:0;else f=2;c[qa>>2]=f;if(j)f=p<<16>>16!=0?2:0;else f=2;c[pa>>2]=f;break}else if((f|0)==3){j=V+28|0;v=b[V+32>>1]|0;if(!(v<<16>>16))f=(b[j>>1]|0)!=0?2:0;else f=2;c[Ya>>2]=f;B=b[V+34>>1]|0;p=B<<16>>16==0;if(p)h=(b[V+30>>1]|0)!=0?2:0;else h=2;c[Xa>>2]=h;z=b[V+40>>1]|0;if(!(z<<16>>16))k=(b[V+36>>1]|0)!=0?2:0;else k=2;c[Wa>>2]=k;o=b[V+42>>1]|0;h=o<<16>>16==0;if(h)l=(b[V+38>>1]|0)!=0?2:0;else l=2;c[Va>>2]=l;f=b[V+44>>1]|0;if(!(f<<16>>16))l=v<<16>>16!=0?2:0;else l=2;c[Ua>>2]=l;A=b[V+46>>1]|0;g=A<<16>>16==0;if(g)l=B<<16>>16!=0?2:0;else l=2;c[Ta>>2]=l;y=b[V+52>>1]|0;if(!(y<<16>>16))l=z<<16>>16!=0?2:0;else l=2;c[Sa>>2]=l;k=b[V+54>>1]|0;q=k<<16>>16==0;if(q)l=o<<16>>16!=0?2:0;else l=2;c[Ra>>2]=l;r=b[V+48>>1]|0;if(!(r<<16>>16))n=f<<16>>16!=0?2:0;else n=2;c[Qa>>2]=n;x=b[V+50>>1]|0;s=x<<16>>16==0;if(s)n=A<<16>>16!=0?2:0;else n=2;c[Pa>>2]=n;w=b[V+56>>1]|0;if(!(w<<16>>16))o=y<<16>>16!=0?2:0;else o=2;c[Na>>2]=o;u=(b[V+58>>1]|0)==0;if(u)o=k<<16>>16!=0?2:0;else o=2;c[Ma>>2]=o;t=b[V+30>>1]|0;if(!(t<<16>>16))o=(b[j>>1]|0)!=0?2:0;else o=2;c[Aa>>2]=o;if(!(b[V+38>>1]|0))o=(b[V+36>>1]|0)!=0?2:0;else o=2;c[ya>>2]=o;if(p)n=v<<16>>16!=0?2:0;else n=2;c[xa>>2]=n;if(h)n=z<<16>>16!=0?2:0;else n=2;c[va>>2]=n;if(g)l=f<<16>>16!=0?2:0;else l=2;c[ua>>2]=l;if(q)l=y<<16>>16!=0?2:0;else l=2;c[sa>>2]=l;if(s)l=r<<16>>16!=0?2:0;else l=2;c[ra>>2]=l;if(u)l=w<<16>>16!=0?2:0;else l=2;c[pa>>2]=l;l=b[V+150>>1]|0;k=b[V+138>>1]|0;do if(!((b[V+36>>1]|t)<<16>>16)){v=(b[V+148>>1]|0)-(b[V+136>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){l=1;break}v=l-k|0;if((((v|0)>-1?v:0-v|0)|0)>3){l=1;break}l=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else l=2;while(0);c[za>>2]=l;l=b[V+158>>1]|0;k=b[V+146>>1]|0;do if(!((z|B)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+144>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}B=l-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}k=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else k=2;while(0);c[wa>>2]=k;l=b[V+182>>1]|0;k=b[V+170>>1]|0;do if(!((y|A)<<16>>16)){B=(b[V+180>>1]|0)-(b[V+168>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}B=l-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else f=2;while(0);c[ta>>2]=f;f=b[V+190>>1]|0;g=b[V+178>>1]|0;do if(!((w|x)<<16>>16)){B=(b[V+188>>1]|0)-(b[V+176>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}B=f-g|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else f=2;while(0);c[qa>>2]=f;break}else{K=b[V+32>>1]|0;z=b[V+28>>1]|0;P=b[V+142>>1]|0;q=b[V+134>>1]|0;if(!((z|K)<<16>>16)){B=(b[V+140>>1]|0)-(b[V+132>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)k=1;else{k=P-q|0;k=(((k|0)>-1?k:0-k|0)|0)>3&1}}else k=2;c[Ya>>2]=k;L=b[V+34>>1]|0;y=b[V+30>>1]|0;O=b[V+146>>1]|0;r=b[V+138>>1]|0;if(!((y|L)<<16>>16)){B=(b[V+144>>1]|0)-(b[V+136>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)l=1;else{l=O-r|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}}else l=2;c[Xa>>2]=l;M=b[V+40>>1]|0;x=b[V+36>>1]|0;N=b[V+158>>1]|0;s=b[V+150>>1]|0;if(!((x|M)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+148>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)n=1;else{n=N-s|0;n=(((n|0)>-1?n:0-n|0)|0)>3&1}}else n=2;c[Wa>>2]=n;n=b[V+42>>1]|0;B=b[V+38>>1]|0;J=b[V+162>>1]|0;A=b[V+154>>1]|0;if(!((B|n)<<16>>16)){w=(b[V+160>>1]|0)-(b[V+152>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3)o=1;else{o=J-A|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}}else o=2;c[Va>>2]=o;D=b[V+44>>1]|0;I=b[V+166>>1]|0;do if(!((D|K)<<16>>16)){w=(b[V+164>>1]|0)-(b[V+140>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3)o=1;else{w=I-P|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}}else o=2;while(0);c[Ua>>2]=o;E=b[V+46>>1]|0;H=b[V+170>>1]|0;do if(!((E|L)<<16>>16)){w=(b[V+168>>1]|0)-(b[V+144>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}w=H-O|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[Ta>>2]=o;F=b[V+52>>1]|0;G=b[V+182>>1]|0;do if(!((F|M)<<16>>16)){w=(b[V+180>>1]|0)-(b[V+156>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}w=G-N|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Sa>>2]=o;g=b[V+54>>1]|0;l=b[V+186>>1]|0;do if(!((g|n)<<16>>16)){w=(b[V+184>>1]|0)-(b[V+160>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}w=l-J|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else u=2;while(0);c[Ra>>2]=u;f=b[V+48>>1]|0;C=b[V+174>>1]|0;do if(!((f|D)<<16>>16)){w=(b[V+172>>1]|0)-(b[V+164>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=C-I|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Qa>>2]=u;h=b[V+50>>1]|0;k=b[V+178>>1]|0;do if(!((h|E)<<16>>16)){w=(b[V+176>>1]|0)-(b[V+168>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=k-H|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Pa>>2]=u;j=b[V+56>>1]|0;p=b[V+190>>1]|0;do if(!((j|F)<<16>>16)){w=(b[V+188>>1]|0)-(b[V+180>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=p-G|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Na>>2]=u;w=b[V+58>>1]|0;t=b[V+194>>1]|0;do if(!((w|g)<<16>>16)){v=(b[V+192>>1]|0)-(b[V+184>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){v=1;break}v=t-l|0;v=(((v|0)>-1?v:0-v|0)|0)>3&1}else v=2;while(0);c[Ma>>2]=v;do if(!((y|z)<<16>>16)){z=(b[V+136>>1]|0)-(b[V+132>>1]|0)|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}u=r-q|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Aa>>2]=u;do if(!((x|y)<<16>>16)){z=(b[V+148>>1]|0)-(b[V+136>>1]|0)|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}z=s-r|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}u=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else u=2;while(0);c[za>>2]=u;do if(!((B|x)<<16>>16)){B=(b[V+152>>1]|0)-(b[V+148>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){u=1;break}u=A-s|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[ya>>2]=u;do if(!((L|K)<<16>>16)){B=(b[V+144>>1]|0)-(b[V+140>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=O-P|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}else o=2;while(0);c[xa>>2]=o;do if(!((M|L)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+144>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}B=N-O|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[wa>>2]=o;do if(!((n|M)<<16>>16)){B=(b[V+160>>1]|0)-(b[V+156>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=J-N|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}else o=2;while(0);c[va>>2]=o;do if(!((E|D)<<16>>16)){B=(b[V+168>>1]|0)-(b[V+164>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}n=H-I|0;n=(((n|0)>-1?n:0-n|0)|0)>3&1}else n=2;while(0);c[ua>>2]=n;do if(!((F|E)<<16>>16)){B=(b[V+180>>1]|0)-(b[V+168>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}B=G-H|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}n=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else n=2;while(0);c[ta>>2]=n;do if(!((g|F)<<16>>16)){B=(b[V+184>>1]|0)-(b[V+180>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){l=1;break}l=l-G|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=2;while(0);c[sa>>2]=l;do if(!((h|f)<<16>>16)){B=(b[V+176>>1]|0)-(b[V+172>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){l=1;break}l=k-C|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=2;while(0);c[ra>>2]=l;do if(!((j|h)<<16>>16)){B=(b[V+188>>1]|0)-(b[V+176>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}B=p-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}k=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else k=2;while(0);c[qa>>2]=k;do if(!((w|j)<<16>>16)){B=(b[V+192>>1]|0)-(b[V+188>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=t-p|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=2;while(0);c[pa>>2]=f;break}}else vc(V,ia);while(0);if(!(m|c[Ya>>2]|c[Xa>>2]|c[Wa>>2]|c[Va>>2]|c[Ua>>2]|c[Ta>>2]|c[Sa>>2]|c[Ra>>2]|c[Qa>>2]|c[Pa>>2]|c[Na>>2]|c[Ma>>2]|c[Aa>>2]|c[za>>2]|c[ya>>2]|c[xa>>2]|c[wa>>2]|c[va>>2]|c[ua>>2]|c[ta>>2]|c[sa>>2]|c[ra>>2]|c[qa>>2]|c[pa>>2]))break}else{c[Ma>>2]=3;c[Na>>2]=3;c[Pa>>2]=3;c[Qa>>2]=3;c[Ra>>2]=3;c[Sa>>2]=3;c[Ta>>2]=3;c[Ua>>2]=3;c[Va>>2]=3;c[Wa>>2]=3;c[Xa>>2]=3;c[Ya>>2]=3;c[pa>>2]=3;c[qa>>2]=3;c[ra>>2]=3;c[sa>>2]=3;c[ta>>2]=3;c[ua>>2]=3;c[va>>2]=3;c[wa>>2]=3;c[xa>>2]=3;c[ya>>2]=3;c[za>>2]=3;c[Aa>>2]=3}J=V+20|0;g=c[J>>2]|0;L=V+12|0;k=Oa(0,51,(c[L>>2]|0)+g|0)|0;K=V+16|0;h=Oa(0,51,(c[K>>2]|0)+g|0)|0;j=d[6864+k>>0]|0;c[ha>>2]=j;h=d[6920+h>>0]|0;c[ja>>2]=h;k=6976+(k*3|0)|0;c[Ka>>2]=k;do if(!R){l=c[(c[S>>2]|0)+20>>2]|0;if((l|0)==(g|0)){c[X>>2]=j;c[_>>2]=h;c[La>>2]=k;break}else{A=(g+1+l|0)>>>1;B=Oa(0,51,(c[L>>2]|0)+A|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[X>>2]=d[6864+B>>0];c[_>>2]=d[6920+A>>0];c[La>>2]=6976+(B*3|0);break}}while(0);do if(!Q){f=c[(c[T>>2]|0)+20>>2]|0;if((f|0)==(g|0)){c[Y>>2]=c[ha>>2];c[$>>2]=c[ja>>2];c[da>>2]=c[Ka>>2];break}else{A=(g+1+f|0)>>>1;B=Oa(0,51,(c[L>>2]|0)+A|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[Y>>2]=d[6864+B>>0];c[$>>2]=d[6920+A>>0];c[da>>2]=6976+(B*3|0);break}}while(0);M=Z(aa,ea)|0;P=3;o=0;O=(c[e>>2]|0)+((M<<8)+(U<<4))|0;N=ia;while(1){l=c[N+4>>2]|0;if(l)wc(O,l,fa,Da);l=c[N+12>>2]|0;if(l)wc(O+4|0,l,ga,Da);k=N+16|0;m=c[N+20>>2]|0;if(m)wc(O+8|0,m,ga,Da);j=N+24|0;m=c[N+28>>2]|0;if(m)wc(O+12|0,m,ga,Da);n=c[N>>2]|0;l=N+8|0;m=c[l>>2]|0;a:do if(((n|0)==(m|0)?(n|0)==(c[k>>2]|0):0)?(n|0)==(c[j>>2]|0):0){if(!n)break;y=c[La+(o*12|0)+4>>2]|0;x=c[La+(o*12|0)+8>>2]|0;if(n>>>0<4){t=d[(c[La+(o*12|0)>>2]|0)+(n+-1)>>0]|0;k=0-t|0;j=t+1|0;f=O;h=16;while(1){o=f+Ca|0;s=d[o>>0]|0;u=f+Ja|0;r=d[u>>0]|0;q=d[f>>0]|0;m=f+Da|0;g=d[m>>0]|0;B=r-q|0;do if(((B|0)>-1?B:0-B|0)>>>0>>0){B=s-r|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=g-q|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;n=d[f+Ha>>0]|0;B=n-r|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[o>>0]=(Oa(k,t,((r+1+q|0)>>>1)-(s<<1)+n>>1)|0)+s;o=j}else o=t;n=d[f+Ia>>0]|0;B=n-q|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[m>>0]=(Oa(k,t,((r+1+q|0)>>>1)-(g<<1)+n>>1)|0)+g;o=o+1|0}A=Oa(0-o|0,o,s+4-g+(q-r<<2)>>3)|0;B=a[3472+((q|512)-A)>>0]|0;a[u>>0]=a[3472+(A+(r|512))>>0]|0;a[f>>0]=B}while(0);h=h+-1|0;if(!h)break a;else f=f+1|0}}n=(y>>>2)+2|0;t=O;u=16;while(1){m=t+Ca|0;f=d[m>>0]|0;l=t+Ja|0;g=d[l>>0]|0;p=d[t>>0]|0;k=t+Da|0;q=d[k>>0]|0;o=g-p|0;o=(o|0)>-1?o:0-o|0;b:do if(o>>>0>>0){B=f-g|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=q-p|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;j=t+Ha|0;r=d[j>>0]|0;h=t+Ia|0;s=d[h>>0]|0;do if(o>>>0>>0){B=r-g|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){B=g+f+p|0;a[l>>0]=(q+4+(B<<1)+r|0)>>>3;a[m>>0]=(B+2+r|0)>>>2;a[j>>0]=(B+4+(r*3|0)+(d[t+Ea>>0]<<1)|0)>>>3}else a[l>>0]=(g+2+(f<<1)+q|0)>>>2;B=s-p|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=p+g+q|0;a[t>>0]=(f+4+(B<<1)+s|0)>>>3;a[k>>0]=(B+2+s|0)>>>2;a[h>>0]=(B+4+(s*3|0)+(d[t+Ga>>0]<<1)|0)>>>3;break b}else a[l>>0]=(g+2+(f<<1)+q|0)>>>2;while(0);a[t>>0]=(f+2+p+(q<<1)|0)>>>2}while(0);u=u+-1|0;if(!u)break;else t=t+1|0}}else ab=311;while(0);do if((ab|0)==311){ab=0;if(n){xc(O,n,La+(o*12|0)|0,Da);m=c[l>>2]|0}if(m)xc(O+4|0,m,La+(o*12|0)|0,Da);m=c[k>>2]|0;if(m)xc(O+8|0,m,La+(o*12|0)|0,Da);l=c[j>>2]|0;if(!l)break;xc(O+12|0,l,La+(o*12|0)|0,Da)}while(0);if(!P)break;else{P=P+-1|0;o=2;O=O+Ba|0;N=N+32|0}}h=c[V+24>>2]|0;g=c[192+((Oa(0,51,(c[J>>2]|0)+h|0)|0)<<2)>>2]|0;m=Oa(0,51,(c[L>>2]|0)+g|0)|0;j=Oa(0,51,(c[K>>2]|0)+g|0)|0;k=d[6864+m>>0]|0;c[ha>>2]=k;j=d[6920+j>>0]|0;c[ja>>2]=j;m=6976+(m*3|0)|0;c[Ka>>2]=m;do if(!R){l=c[(c[S>>2]|0)+20>>2]|0;if((l|0)==(c[J>>2]|0)){c[X>>2]=k;c[_>>2]=j;c[La>>2]=m;break}else{A=(g+1+(c[192+((Oa(0,51,l+h|0)|0)<<2)>>2]|0)|0)>>>1;B=Oa(0,51,A+(c[L>>2]|0)|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[X>>2]=d[6864+B>>0];c[_>>2]=d[6920+A>>0];c[La>>2]=6976+(B*3|0);break}}while(0);do if(!Q){f=c[(c[T>>2]|0)+20>>2]|0;if((f|0)==(c[J>>2]|0)){c[Y>>2]=c[ha>>2];c[$>>2]=c[ja>>2];c[da>>2]=c[Ka>>2];break}else{A=(g+1+(c[192+((Oa(0,51,f+h|0)|0)<<2)>>2]|0)|0)>>>1;B=Oa(0,51,A+(c[L>>2]|0)|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[Y>>2]=d[6864+B>>0];c[$>>2]=d[6920+A>>0];c[da>>2]=6976+(B*3|0);break}}while(0);j=c[e>>2]|0;l=(U<<3)+Fa+(M<<6)|0;n=j+l|0;l=j+(l+ba)|0;j=0;h=ia;o=0;while(1){g=h+4|0;f=c[g>>2]|0;if(f){yc(n,f,fa,ca);yc(l,c[g>>2]|0,fa,ca)}g=h+36|0;f=c[g>>2]|0;if(f){yc(n+Da|0,f,fa,ca);yc(l+Da|0,c[g>>2]|0,fa,ca)}m=h+16|0;g=h+20|0;f=c[g>>2]|0;if(f){yc(n+4|0,f,ga,ca);yc(l+4|0,c[g>>2]|0,ga,ca)}g=h+52|0;f=c[g>>2]|0;if(f){yc(n+W|0,f,ga,ca);yc(l+W|0,c[g>>2]|0,ga,ca)}g=c[h>>2]|0;k=h+8|0;f=c[k>>2]|0;do if((g|0)==(f|0)){if((g|0)!=(c[m>>2]|0)){ab=342;break}if((g|0)!=(c[h+24>>2]|0)){ab=342;break}if(!g)break;B=La+(j*12|0)|0;zc(n,g,B,ca);zc(l,c[h>>2]|0,B,ca)}else ab=342;while(0);do if((ab|0)==342){ab=0;if(g){f=La+(j*12|0)|0;Ac(n,g,f,ca);Ac(l,c[h>>2]|0,f,ca);f=c[k>>2]|0}if(f){B=La+(j*12|0)|0;Ac(n+2|0,f,B,ca);Ac(l+2|0,c[k>>2]|0,B,ca)}f=c[m>>2]|0;if(f){B=La+(j*12|0)|0;Ac(n+4|0,f,B,ca);Ac(l+4|0,c[m>>2]|0,B,ca)}g=h+24|0;f=c[g>>2]|0;if(!f)break;B=La+(j*12|0)|0;Ac(n+6|0,f,B,ca);Ac(l+6|0,c[g>>2]|0,B,ca)}while(0);o=o+1|0;if((o|0)==2)break;else{n=n+Ia|0;l=l+Ia|0;j=2;h=h+64|0}}}while(0);f=U+1|0;g=(f|0)==(ea|0);aa=(g&1)+aa|0;if(aa>>>0>=(c[ka>>2]|0)>>>0)break;else{U=g?0:f;V=V+216|0}}i=bb;return}function vc(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=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;B=i;l=a+28|0;y=b[a+32>>1]|0;if(!(y<<16>>16))e=(b[l>>1]|0)!=0?2:0;else e=2;c[d+32>>2]=e;z=b[a+34>>1]|0;x=z<<16>>16==0;if(x)e=(b[a+30>>1]|0)!=0?2:0;else e=2;c[d+40>>2]=e;A=b[a+40>>1]|0;v=A<<16>>16==0;if(v)e=(b[a+36>>1]|0)!=0?2:0;else e=2;c[d+48>>2]=e;f=b[a+42>>1]|0;w=f<<16>>16==0;if(w)e=(b[a+38>>1]|0)!=0?2:0;else e=2;c[d+56>>2]=e;s=b[a+44>>1]|0;if(!(s<<16>>16))e=y<<16>>16!=0?2:0;else e=2;c[d+64>>2]=e;t=b[a+46>>1]|0;p=t<<16>>16==0;if(p)e=z<<16>>16!=0?2:0;else e=2;c[d+72>>2]=e;u=b[a+52>>1]|0;q=u<<16>>16==0;if(q)e=A<<16>>16!=0?2:0;else e=2;c[d+80>>2]=e;g=b[a+54>>1]|0;r=g<<16>>16==0;if(r)e=f<<16>>16!=0?2:0;else e=2;c[d+88>>2]=e;m=b[a+48>>1]|0;if(!(m<<16>>16))e=s<<16>>16!=0?2:0;else e=2;c[d+96>>2]=e;n=b[a+50>>1]|0;h=n<<16>>16==0;if(h)e=t<<16>>16!=0?2:0;else e=2;c[d+104>>2]=e;o=b[a+56>>1]|0;j=o<<16>>16==0;if(j)f=u<<16>>16!=0?2:0;else f=2;c[d+112>>2]=f;k=(b[a+58>>1]|0)==0;if(k)f=g<<16>>16!=0?2:0;else f=2;c[d+120>>2]=f;g=b[a+30>>1]|0;if(!(g<<16>>16))f=(b[l>>1]|0)!=0?2:0;else f=2;c[d+12>>2]=f;e=b[a+36>>1]|0;if(!(e<<16>>16))f=g<<16>>16!=0?2:0;else f=2;c[d+20>>2]=f;if(!(b[a+38>>1]|0))e=e<<16>>16!=0?2:0;else e=2;c[d+28>>2]=e;if(x)e=y<<16>>16!=0?2:0;else e=2;c[d+44>>2]=e;if(v)e=z<<16>>16!=0?2:0;else e=2;c[d+52>>2]=e;if(w)e=A<<16>>16!=0?2:0;else e=2;c[d+60>>2]=e;if(p)e=s<<16>>16!=0?2:0;else e=2;c[d+76>>2]=e;if(q)e=t<<16>>16!=0?2:0;else e=2;c[d+84>>2]=e;if(r)e=u<<16>>16!=0?2:0;else e=2;c[d+92>>2]=e;if(h)e=m<<16>>16!=0?2:0;else e=2;c[d+108>>2]=e;if(j)e=n<<16>>16!=0?2:0;else e=2;c[d+116>>2]=e;if(!k){y=2;z=d+124|0;c[z>>2]=y;i=B;return}y=o<<16>>16!=0?2:0;z=d+124|0;c[z>>2]=y;i=B;return}function wc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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;w=i;u=c[f+4>>2]|0;v=c[f+8>>2]|0;if(e>>>0<4){l=d[(c[f>>2]|0)+(e+-1)>>0]|0;n=0-l|0;m=l+1|0;k=4;while(1){f=b+-2|0;s=d[f>>0]|0;t=b+-1|0;r=d[t>>0]|0;q=d[b>>0]|0;j=b+1|0;h=d[j>>0]|0;o=r-q|0;if((((o|0)>-1?o:0-o|0)>>>0>>0?(o=s-r|0,((o|0)>-1?o:0-o|0)>>>0>>0):0)?(o=h-q|0,((o|0)>-1?o:0-o|0)>>>0>>0):0){e=d[b+-3>>0]|0;p=d[b+2>>0]|0;o=e-r|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){a[f>>0]=(Oa(n,l,((r+1+q|0)>>>1)-(s<<1)+e>>1)|0)+s;f=m}else f=l;o=p-q|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){a[j>>0]=(Oa(n,l,((r+1+q|0)>>>1)-(h<<1)+p>>1)|0)+h;f=f+1|0}j=Oa(0-f|0,f,s+4-h+(q-r<<2)>>3)|0;o=a[3472+((q|512)-j)>>0]|0;a[t>>0]=a[3472+((r|512)+j)>>0]|0;a[b>>0]=o}k=k+-1|0;if(!k)break;else b=b+g|0}i=w;return}t=(u>>>2)+2|0;s=4;while(1){k=b+-2|0;q=d[k>>0]|0;l=b+-1|0;r=d[l>>0]|0;m=d[b>>0]|0;e=b+1|0;n=d[e>>0]|0;f=r-m|0;f=(f|0)>-1?f:0-f|0;do if((f>>>0>>0?(o=q-r|0,((o|0)>-1?o:0-o|0)>>>0>>0):0)?(o=n-m|0,((o|0)>-1?o:0-o|0)>>>0>>0):0){h=b+-3|0;o=d[h>>0]|0;j=b+2|0;p=d[j>>0]|0;if(f>>>0>>0){f=o-r|0;if(((f|0)>-1?f:0-f|0)>>>0>>0){f=r+q+m|0;a[l>>0]=(n+4+(f<<1)+o|0)>>>3;a[k>>0]=(f+2+o|0)>>>2;a[h>>0]=(f+4+(o*3|0)+((d[b+-4>>0]|0)<<1)|0)>>>3}else a[l>>0]=(r+2+(q<<1)+n|0)>>>2;o=p-m|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){o=m+r+n|0;a[b>>0]=(q+4+(o<<1)+p|0)>>>3;a[e>>0]=(o+2+p|0)>>>2;a[j>>0]=(o+4+(p*3|0)+((d[b+3>>0]|0)<<1)|0)>>>3;break}}else a[l>>0]=(r+2+(q<<1)+n|0)>>>2;a[b>>0]=(q+2+m+(n<<1)|0)>>>2}while(0);s=s+-1|0;if(!s)break;else b=b+g|0}i=w;return}function xc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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=i;u=d[(c[f>>2]|0)+(e+-1)>>0]|0;w=0-g|0;v=w<<1;t=f+4|0;o=f+8|0;q=Z(g,-3)|0;s=0-u|0;p=u+1|0;r=g<<1;n=4;while(1){e=b+v|0;k=b+w|0;j=b+g|0;f=a[j>>0]|0;l=d[k>>0]|0;m=d[b>>0]|0;h=l-m|0;if((((h|0)>-1?h:0-h|0)>>>0<(c[t>>2]|0)>>>0?(y=d[e>>0]|0,h=y-l|0,x=c[o>>2]|0,((h|0)>-1?h:0-h|0)>>>0>>0):0)?(z=f&255,f=z-m|0,((f|0)>-1?f:0-f|0)>>>0>>0):0){f=d[b+q>>0]|0;h=f-l|0;if(((h|0)>-1?h:0-h|0)>>>0>>0){a[e>>0]=(Oa(s,u,((l+1+m|0)>>>1)-(y<<1)+f>>1)|0)+y;e=c[o>>2]|0;f=p}else{e=x;f=u}h=d[b+r>>0]|0;B=h-m|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[j>>0]=(Oa(s,u,((l+1+m|0)>>>1)-(z<<1)+h>>1)|0)+z;f=f+1|0}f=Oa(0-f|0,f,4-z+(m-l<<2)+y>>3)|0;e=a[3472+((m|512)-f)>>0]|0;a[k>>0]=a[3472+((l|512)+f)>>0]|0;a[b>>0]=e}n=n+-1|0;if(!n)break;else b=b+1|0}i=A;return} +function ya(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+15&-16;return b|0}function za(){return i|0}function Aa(a){a=a|0;i=a}function Ba(a,b){a=a|0;b=b|0;if(!m){m=a;n=b}}function Ca(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Da(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Ea(a){a=a|0;B=a}function Fa(){return B|0}function Ga(a,b,e,f){a=a|0;b=b|0;e=e|0;f=f|0;var g=0,h=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;k=i;g=d[8+b>>0]|0;j=d[64+b>>0]|0;b=c[120+(j*12|0)>>2]<>2]<>2]<>2]=Z(c[a>>2]|0,b)|0;a:do if(!(f&65436)){if(f&98){n=a+4|0;l=Z(c[n>>2]|0,h)|0;j=a+20|0;m=Z(c[j>>2]|0,b)|0;e=a+24|0;g=Z(c[e>>2]|0,h)|0;h=c[a>>2]|0;b=(l>>1)-g|0;g=l+(g>>1)|0;l=m+h+32|0;f=l+g>>6;c[a>>2]=f;m=h-m+32|0;h=m+b>>6;c[n>>2]=h;b=m-b>>6;c[a+8>>2]=b;g=l-g>>6;c[a+12>>2]=g;c[a+48>>2]=f;c[a+32>>2]=f;c[a+16>>2]=f;c[a+52>>2]=h;c[a+36>>2]=h;c[j>>2]=h;c[a+56>>2]=b;c[a+40>>2]=b;c[e>>2]=b;c[a+60>>2]=g;c[a+44>>2]=g;c[a+28>>2]=g;if((f+512|0)>>>0>1023|(h+512|0)>>>0>1023|(b+512|0)>>>0>1023|(g+512|0)>>>0>1023)g=1;else break;i=k;return g|0}g=(c[a>>2]|0)+32>>6;if((g+512|0)>>>0>1023){m=1;i=k;return m|0}else{c[a+60>>2]=g;c[a+56>>2]=g;c[a+52>>2]=g;c[a+48>>2]=g;c[a+44>>2]=g;c[a+40>>2]=g;c[a+36>>2]=g;c[a+32>>2]=g;c[a+28>>2]=g;c[a+24>>2]=g;c[a+20>>2]=g;c[a+16>>2]=g;c[a+12>>2]=g;c[a+8>>2]=g;c[a+4>>2]=g;c[a>>2]=g;break}}else{z=a+4|0;s=a+56|0;w=a+60|0;t=c[w>>2]|0;u=Z(c[z>>2]|0,h)|0;c[s>>2]=Z(c[s>>2]|0,h)|0;c[w>>2]=Z(t,g)|0;w=a+8|0;t=c[w>>2]|0;s=a+16|0;y=Z(c[a+20>>2]|0,b)|0;o=Z(c[s>>2]|0,g)|0;q=a+12|0;p=c[q>>2]|0;f=Z(c[a+32>>2]|0,h)|0;e=Z(c[a+24>>2]|0,h)|0;r=c[a+28>>2]|0;j=Z(c[a+48>>2]|0,g)|0;n=Z(c[a+36>>2]|0,h)|0;l=c[a+44>>2]|0;m=Z(c[a+40>>2]|0,g)|0;g=Z(c[a+52>>2]|0,h)|0;x=c[a>>2]|0;v=y+x|0;y=x-y|0;x=(u>>1)-e|0;u=(e>>1)+u|0;e=u+v|0;c[a>>2]=e;c[z>>2]=x+y;c[w>>2]=y-x;c[q>>2]=v-u;q=Z(h,r+t|0)|0;r=Z(t-r|0,h)|0;h=(o>>1)-j|0;o=(j>>1)+o|0;j=o+q|0;c[s>>2]=j;c[a+20>>2]=h+r;c[a+24>>2]=r-h;c[a+28>>2]=q-o;o=Z(b,l+p|0)|0;b=Z(p-l|0,b)|0;l=(f>>1)-g|0;f=(g>>1)+f|0;h=f+o|0;c[a+32>>2]=h;c[a+36>>2]=l+b;c[a+40>>2]=b-l;c[a+44>>2]=o-f;f=a+56|0;o=c[f>>2]|0;l=o+n|0;o=n-o|0;b=a+60|0;g=c[b>>2]|0;n=(m>>1)-g|0;m=(g>>1)+m|0;g=m+l|0;c[a+48>>2]=g;c[a+52>>2]=n+o;c[f>>2]=o-n;c[b>>2]=l-m;b=j;j=3;while(1){v=(b>>1)-g|0;g=(g>>1)+b|0;w=h+e+32|0;x=w+g>>6;c[a>>2]=x;b=e-h+32|0;y=b+v>>6;c[a+16>>2]=y;b=b-v>>6;c[a+32>>2]=b;g=w-g>>6;c[a+48>>2]=g;if((x+512|0)>>>0>1023|(y+512|0)>>>0>1023){g=1;b=14;break}if((b+512|0)>>>0>1023|(g+512|0)>>>0>1023){g=1;b=14;break}f=a+4|0;if(!j)break a;e=c[f>>2]|0;h=c[a+36>>2]|0;b=c[a+20>>2]|0;g=c[a+52>>2]|0;a=f;j=j+-1|0}if((b|0)==14){i=k;return g|0}}while(0);y=0;i=k;return y|0}function Ha(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=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;B=i;e=a[64+d>>0]|0;s=a[8+d>>0]|0;D=b+8|0;u=c[D>>2]|0;j=c[b+20>>2]|0;q=b+16|0;y=c[q>>2]|0;r=b+32|0;z=c[r>>2]|0;E=b+12|0;v=c[E>>2]|0;f=c[b+24>>2]|0;m=c[b+28>>2]|0;o=b+48|0;g=c[o>>2]|0;C=c[b+36>>2]|0;A=c[b+40>>2]|0;F=c[b+44>>2]|0;h=c[b+52>>2]|0;p=c[b>>2]|0;l=j+p|0;j=p-j|0;p=b+4|0;x=c[p>>2]|0;t=x-f|0;x=f+x|0;f=x+l|0;c[b>>2]=f;k=t+j|0;c[p>>2]=k;t=j-t|0;c[D>>2]=t;x=l-x|0;c[E>>2]=x;E=m+u|0;m=u-m|0;u=y-g|0;y=g+y|0;g=y+E|0;c[q>>2]=g;l=u+m|0;c[b+20>>2]=l;u=m-u|0;c[b+24>>2]=u;y=E-y|0;c[b+28>>2]=y;E=F+v|0;F=v-F|0;v=z-h|0;z=h+z|0;h=z+E|0;c[b+32>>2]=h;m=v+F|0;c[b+36>>2]=m;v=F-v|0;c[b+40>>2]=v;z=E-z|0;c[b+44>>2]=z;E=b+56|0;F=c[E>>2]|0;D=F+C|0;F=C-F|0;C=b+60|0;j=c[C>>2]|0;w=A-j|0;A=j+A|0;j=A+D|0;c[b+48>>2]=j;n=w+F|0;c[b+52>>2]=n;w=F-w|0;c[E>>2]=w;A=D-A|0;c[C>>2]=A;s=s&255;e=c[120+((e&255)*12|0)>>2]|0;if(d>>>0>11){d=e<>2]=Z(e+s|0,d)|0;c[q>>2]=Z(f+h|0,d)|0;c[r>>2]=Z(h-f|0,d)|0;c[o>>2]=Z(s-e|0,d)|0;r=m+k|0;e=k-m|0;q=l-n|0;s=n+l|0;c[p>>2]=Z(s+r|0,d)|0;c[b+20>>2]=Z(q+e|0,d)|0;c[b+36>>2]=Z(e-q|0,d)|0;c[b+52>>2]=Z(r-s|0,d)|0;s=v+t|0;t=t-v|0;v=u-w|0;w=w+u|0;c[b+8>>2]=Z(w+s|0,d)|0;c[b+24>>2]=Z(v+t|0,d)|0;c[b+40>>2]=Z(t-v|0,d)|0;c[b+56>>2]=Z(s-w|0,d)|0;w=z+x|0;v=x-z|0;x=y-A|0;y=A+y|0;c[b+12>>2]=Z(y+w|0,d)|0;c[b+28>>2]=Z(x+v|0,d)|0;c[b+44>>2]=Z(v-x|0,d)|0;c[b+60>>2]=Z(w-y|0,d)|0;i=B;return}else{C=(d+-6|0)>>>0<6?1:2;d=2-s|0;s=h+f|0;D=f-h|0;h=g-j|0;f=j+g|0;c[b>>2]=(Z(f+s|0,e)|0)+C>>d;c[q>>2]=(Z(h+D|0,e)|0)+C>>d;c[r>>2]=(Z(D-h|0,e)|0)+C>>d;c[o>>2]=(Z(s-f|0,e)|0)+C>>d;r=m+k|0;f=k-m|0;q=l-n|0;s=n+l|0;c[p>>2]=(Z(s+r|0,e)|0)+C>>d;c[b+20>>2]=(Z(q+f|0,e)|0)+C>>d;c[b+36>>2]=(Z(f-q|0,e)|0)+C>>d;c[b+52>>2]=(Z(r-s|0,e)|0)+C>>d;s=v+t|0;t=t-v|0;v=u-w|0;w=w+u|0;c[b+8>>2]=(Z(w+s|0,e)|0)+C>>d;c[b+24>>2]=(Z(v+t|0,e)|0)+C>>d;c[b+40>>2]=(Z(t-v|0,e)|0)+C>>d;c[b+56>>2]=(Z(s-w|0,e)|0)+C>>d;w=z+x|0;v=x-z|0;x=y-A|0;y=A+y|0;c[b+12>>2]=(Z(y+w|0,e)|0)+C>>d;c[b+28>>2]=(Z(x+v|0,e)|0)+C>>d;c[b+44>>2]=(Z(v-x|0,e)|0)+C>>d;c[b+60>>2]=(Z(w-y|0,e)|0)+C>>d;i=B;return}}function Ia(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;e=c[120+((d[64+b>>0]|0)*12|0)>>2]|0;if(b>>>0>5){e=e<<(d[8+b>>0]|0)+-1;b=0}else b=1;k=c[a>>2]|0;g=a+8|0;h=c[g>>2]|0;m=h+k|0;h=k-h|0;k=a+4|0;j=c[k>>2]|0;l=a+12|0;f=c[l>>2]|0;i=j-f|0;j=f+j|0;c[a>>2]=(Z(j+m|0,e)|0)>>b;c[k>>2]=(Z(m-j|0,e)|0)>>b;c[g>>2]=(Z(i+h|0,e)|0)>>b;c[l>>2]=(Z(h-i|0,e)|0)>>b;l=a+16|0;i=c[l>>2]|0;h=a+24|0;g=c[h>>2]|0;k=g+i|0;g=i-g|0;i=a+20|0;j=c[i>>2]|0;a=a+28|0;m=c[a>>2]|0;f=j-m|0;j=m+j|0;c[l>>2]=(Z(j+k|0,e)|0)>>b;c[i>>2]=(Z(k-j|0,e)|0)>>b;c[h>>2]=(Z(f+g|0,e)|0)>>b;c[a>>2]=(Z(g-f|0,e)|0)>>b;return}function Ja(a,b){a=a|0;b=b|0;var c=0,d=0;d=i;b=1<>>1}while((c|0)!=0&(c&a|0)==0);i=d;return b|0}function Ka(a){a=a|0;var b=0,d=0;d=i;b=8-(c[a+8>>2]|0)|0;a=jb(a,b)|0;if((a|0)==-1){a=1;i=d;return a|0}a=(a|0)!=(c[400+(b+-1<<2)>>2]|0)&1;i=d;return a|0}function La(a){a=a|0;var b=0,d=0,e=0,f=0;d=i;f=c[a+12>>2]<<3;e=c[a+16>>2]|0;b=f-e|0;if((f|0)==(e|0)){a=0;i=d;return a|0}if(b>>>0>8){a=1;i=d;return a|0}else{a=((kb(a)|0)>>>(32-b|0)|0)!=(1<>2]|0;do{d=d+1|0;if(d>>>0>=b>>>0)break}while((c[a+(d<<2)>>2]|0)!=(e|0));i=f;return ((d|0)==(b|0)?0:d)|0}function Na(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=c[a+4>>2]|0;f=(b>>>0)%(e>>>0)|0;d=b-f|0;b=Z(c[a+8>>2]|0,e)|0;e=c[a>>2]|0;c[a+12>>2]=e+((d<<8)+(f<<4));d=(f<<3)+(b<<8)+(d<<6)|0;c[a+16>>2]=e+d;c[a+20>>2]=e+(d+(b<<6));return}function Oa(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)>=(a|0))a=(c|0)>(b|0)?b:c;return a|0}function Pa(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=i;a:do if(((e>>>0>3?(a[b>>0]|0)==0:0)?(a[b+1>>0]|0)==0:0)?(h=a[b+2>>0]|0,(h&255)<2):0){b:do if((e|0)!=3){p=-3;q=3;k=b+3|0;j=2;while(1){if(h<<24>>24)if(h<<24>>24==1&j>>>0>1){o=q;h=0;m=0;l=0;break}else j=0;else j=j+1|0;l=q+1|0;if((l|0)==(e|0))break b;h=a[k>>0]|0;p=~q;q=l;k=k+1|0}while(1){r=a[k>>0]|0;n=o+1|0;j=r<<24>>24!=0;l=(j&1^1)+l|0;h=r<<24>>24==3&(l|0)==2?1:h;if(r<<24>>24==1&l>>>0>1){r=14;break}if(j){m=l>>>0>2?1:m;l=0}if((n|0)==(e|0)){r=18;break}else{o=n;k=k+1|0}}if((r|0)==14){n=p+o-l|0;c[f+12>>2]=n;j=q;l=l-(l>>>0<3?l:3)|0;break a}else if((r|0)==18){n=p+e-l|0;c[f+12>>2]=n;j=q;break a}}while(0);c[g>>2]=e;q=1;i=s;return q|0}else r=19;while(0);if((r|0)==19){c[f+12>>2]=e;n=e;h=1;j=0;m=0;l=0}k=b+j|0;c[f>>2]=k;c[f+4>>2]=k;c[f+8>>2]=0;c[f+16>>2]=0;o=f+12|0;c[g>>2]=l+j+n;if(m){q=1;i=s;return q|0}if(!h){q=0;i=s;return q|0}l=c[o>>2]|0;h=k;m=k;j=0;c:while(1){while(1){q=l;l=l+-1|0;if(!q){r=31;break c}k=a[h>>0]|0;if((j|0)!=2)break;if(k<<24>>24!=3){r=29;break}if(!l){h=1;r=32;break c}h=h+1|0;if((d[h>>0]|0)>3){h=1;r=32;break c}else j=0}if((r|0)==29){r=0;if((k&255)<3){h=1;r=32;break}else j=2}a[m>>0]=k;h=h+1|0;m=m+1|0;j=k<<24>>24==0?j+1|0:0}if((r|0)==31){c[o>>2]=m-h+(c[o>>2]|0);q=0;i=s;return q|0}else if((r|0)==32){i=s;return h|0}return 0}function Qa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;i=i+16|0;n=o;id(b,0,92);f=jb(a,8)|0;a:do if((((f|0)!=-1?(c[b>>2]=f,jb(a,1)|0,jb(a,1)|0,(jb(a,1)|0)!=-1):0)?(jb(a,5)|0)!=-1:0)?(e=jb(a,8)|0,(e|0)!=-1):0){m=b+4|0;c[m>>2]=e;f=b+8|0;d=nb(a,f)|0;if(!d)if((c[f>>2]|0)>>>0<=31){d=nb(a,n)|0;if(!d){f=c[n>>2]|0;if(f>>>0<=12){c[b+12>>2]=1<>2]|0;if(f>>>0<=2){c[b+16>>2]=f;b:do if(!f){d=nb(a,n)|0;if(d)break a;f=c[n>>2]|0;if(f>>>0>12){d=1;break a}c[b+20>>2]=1<>2]=(f|0)==1&1;d=ob(a,b+28|0)|0;if(d)break a;d=ob(a,b+32|0)|0;if(d)break a;h=b+36|0;d=nb(a,h)|0;if(d)break a;f=c[h>>2]|0;if(f>>>0>255){d=1;break a}if(!f){c[b+40>>2]=0;break}f=fd(f<<2)|0;g=b+40|0;c[g>>2]=f;if(!f){d=65535;break a}if(c[h>>2]|0){e=0;while(1){d=ob(a,f+(e<<2)|0)|0;e=e+1|0;if(d)break a;if(e>>>0>=(c[h>>2]|0)>>>0)break b;f=c[g>>2]|0}}}while(0);l=b+44|0;d=nb(a,l)|0;if(!d)if((c[l>>2]|0)>>>0<=16?(k=jb(a,1)|0,(k|0)!=-1):0){c[b+48>>2]=(k|0)==1&1;d=nb(a,n)|0;if(!d){e=b+52|0;c[e>>2]=(c[n>>2]|0)+1;d=nb(a,n)|0;if(!d){k=b+56|0;c[k>>2]=(c[n>>2]|0)+1;h=jb(a,1)|0;if((!((h|0)==0|(h|0)==-1)?(jb(a,1)|0)!=-1:0)?(j=jb(a,1)|0,(j|0)!=-1):0){j=(j|0)==1;c[b+60>>2]=j&1;if(j){j=b+64|0;d=nb(a,j)|0;if(d)break;f=b+68|0;d=nb(a,f)|0;if(d)break;h=b+72|0;d=nb(a,h)|0;if(d)break;g=b+76|0;d=nb(a,g)|0;if(d)break;e=c[e>>2]|0;if((c[j>>2]|0)>((e<<3)+~c[f>>2]|0)){d=1;break}f=c[k>>2]|0;if((c[h>>2]|0)>((f<<3)+~c[g>>2]|0)){d=1;break}}else{e=c[e>>2]|0;f=c[k>>2]|0}d=Z(f,e)|0;do switch(c[m>>2]|0){case 11:{f=396;e=345600;g=58;break}case 12:{f=396;e=912384;g=58;break}case 13:{f=396;e=912384;g=58;break}case 20:{f=396;e=912384;g=58;break}case 21:{f=792;e=1824768;g=58;break}case 22:{f=1620;e=3110400;g=58;break}case 30:{f=1620;e=3110400;g=58;break}case 31:{f=3600;e=6912e3;g=58;break}case 32:{f=5120;e=7864320;g=58;break}case 40:{f=8192;e=12582912;g=58;break}case 41:{f=8192;e=12582912;g=58;break}case 42:{f=8704;e=13369344;g=58;break}case 50:{f=22080;e=42393600;g=58;break}case 51:{f=36864;e=70778880;g=58;break}case 10:{f=99;e=152064;g=58;break}default:g=60}while(0);do if((g|0)==58){if(f>>>0>>0){g=60;break}e=(e>>>0)/((d*384|0)>>>0)|0;e=e>>>0<16?e:16;c[n>>2]=e;f=c[l>>2]|0;if(f>>>0>e>>>0){e=f;g=61}}while(0);if((g|0)==60){c[n>>2]=2147483647;e=c[l>>2]|0;g=61}if((g|0)==61)c[n>>2]=e;g=b+88|0;c[g>>2]=e;e=jb(a,1)|0;if((e|0)==-1){d=1;break}n=(e|0)==1;c[b+80>>2]=n&1;do if(n){e=fd(952)|0;f=b+84|0;c[f>>2]=e;if(!e){d=65535;break a}d=Ec(a,e)|0;if(d)break a;d=c[f>>2]|0;if(!(c[d+920>>2]|0))break;e=c[d+948>>2]|0;if((c[d+944>>2]|0)>>>0>e>>>0){d=1;break a}if(e>>>0<(c[l>>2]|0)>>>0){d=1;break a}if(e>>>0>(c[g>>2]|0)>>>0){d=1;break a}c[g>>2]=(e|0)==0?1:e}while(0);Ka(a)|0;d=0}else d=1}}}else d=1}else d=1}}else d=1}}else d=1}else d=1;while(0);i=o;return d|0}function Ra(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;j=i;if((c[a>>2]|0)!=(c[b>>2]|0)){d=1;i=j;return d|0}if((c[a+4>>2]|0)!=(c[b+4>>2]|0)){d=1;i=j;return d|0}if((c[a+12>>2]|0)!=(c[b+12>>2]|0)){d=1;i=j;return d|0}d=c[a+16>>2]|0;if((d|0)!=(c[b+16>>2]|0)){d=1;i=j;return d|0}if((c[a+44>>2]|0)!=(c[b+44>>2]|0)){d=1;i=j;return d|0}if((c[a+48>>2]|0)!=(c[b+48>>2]|0)){d=1;i=j;return d|0}if((c[a+52>>2]|0)!=(c[b+52>>2]|0)){d=1;i=j;return d|0}if((c[a+56>>2]|0)!=(c[b+56>>2]|0)){d=1;i=j;return d|0}h=c[a+60>>2]|0;if((h|0)!=(c[b+60>>2]|0)){d=1;i=j;return d|0}if((c[a+80>>2]|0)!=(c[b+80>>2]|0)){d=1;i=j;return d|0}a:do if(!d){if((c[a+20>>2]|0)!=(c[b+20>>2]|0)){d=1;i=j;return d|0}}else if((d|0)==1){if((c[a+24>>2]|0)!=(c[b+24>>2]|0)){d=1;i=j;return d|0}if((c[a+28>>2]|0)!=(c[b+28>>2]|0)){d=1;i=j;return d|0}if((c[a+32>>2]|0)!=(c[b+32>>2]|0)){d=1;i=j;return d|0}d=c[a+36>>2]|0;if((d|0)!=(c[b+36>>2]|0)){d=1;i=j;return d|0}if(d){e=c[a+40>>2]|0;f=c[b+40>>2]|0;g=0;while(1){if((c[e+(g<<2)>>2]|0)!=(c[f+(g<<2)>>2]|0)){d=1;break}g=g+1|0;if(g>>>0>=d>>>0)break a}i=j;return d|0}}while(0);if(h){if((c[a+64>>2]|0)!=(c[b+64>>2]|0)){d=1;i=j;return d|0}if((c[a+68>>2]|0)!=(c[b+68>>2]|0)){d=1;i=j;return d|0}if((c[a+72>>2]|0)!=(c[b+72>>2]|0)){d=1;i=j;return d|0}if((c[a+76>>2]|0)!=(c[b+76>>2]|0)){d=1;i=j;return d|0}}d=0;i=j;return d|0}function Sa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;i=i+16|0;j=l+4|0;k=l;id(b,0,72);d=nb(a,b)|0;if(d){i=l;return d|0}if((c[b>>2]|0)>>>0>255){d=1;i=l;return d|0}e=b+4|0;d=nb(a,e)|0;if(d){i=l;return d|0}if((c[e>>2]|0)>>>0>31){d=1;i=l;return d|0}if(jb(a,1)|0){d=1;i=l;return d|0}d=jb(a,1)|0;if((d|0)==-1){d=1;i=l;return d|0}c[b+8>>2]=(d|0)==1&1;d=nb(a,j)|0;if(d){i=l;return d|0}d=(c[j>>2]|0)+1|0;h=b+12|0;c[h>>2]=d;if(d>>>0>8){d=1;i=l;return d|0}a:do if(d>>>0>1){d=b+16|0;e=nb(a,d)|0;if(e){d=e;i=l;return d|0}d=c[d>>2]|0;if(d>>>0>6){d=1;i=l;return d|0}switch(d|0){case 5:case 4:case 3:{d=jb(a,1)|0;if((d|0)==-1){d=1;i=l;return d|0}c[b+32>>2]=(d|0)==1&1;d=nb(a,j)|0;if(!d){c[b+36>>2]=(c[j>>2]|0)+1;break a}else{i=l;return d|0}}case 0:{d=fd(c[h>>2]<<2)|0;f=b+20|0;c[f>>2]=d;if(!d){d=65535;i=l;return d|0}if(!(c[h>>2]|0))break a;else e=0;while(1){d=nb(a,j)|0;if(d)break;c[(c[f>>2]|0)+(e<<2)>>2]=(c[j>>2]|0)+1;e=e+1|0;if(e>>>0>=(c[h>>2]|0)>>>0)break a}i=l;return d|0}case 2:{e=b+24|0;c[e>>2]=fd((c[h>>2]<<2)+-4|0)|0;d=fd((c[h>>2]<<2)+-4|0)|0;g=b+28|0;c[g>>2]=d;if((c[e>>2]|0)==0|(d|0)==0){d=65535;i=l;return d|0}if((c[h>>2]|0)==1)break a;else f=0;while(1){d=nb(a,j)|0;if(d){e=46;break}c[(c[e>>2]|0)+(f<<2)>>2]=c[j>>2];d=nb(a,j)|0;if(d){e=46;break}c[(c[g>>2]|0)+(f<<2)>>2]=c[j>>2];f=f+1|0;if(f>>>0>=((c[h>>2]|0)+-1|0)>>>0)break a}if((e|0)==46){i=l;return d|0}break}case 6:{d=nb(a,j)|0;if(d){i=l;return d|0}e=(c[j>>2]|0)+1|0;d=b+40|0;c[d>>2]=e;e=fd(e<<2)|0;g=b+44|0;c[g>>2]=e;if(!e){d=65535;i=l;return d|0}f=c[432+((c[h>>2]|0)+-1<<2)>>2]|0;if(!(c[d>>2]|0))break a;else e=0;while(1){m=jb(a,f)|0;c[(c[g>>2]|0)+(e<<2)>>2]=m;e=e+1|0;if(m>>>0>=(c[h>>2]|0)>>>0){d=1;break}if(e>>>0>=(c[d>>2]|0)>>>0)break a}i=l;return d|0}default:break a}}while(0);d=nb(a,j)|0;if(d){a=d;i=l;return a|0}d=c[j>>2]|0;if(d>>>0>31){a=1;i=l;return a|0}c[b+48>>2]=d+1;d=nb(a,j)|0;if(d){a=d;i=l;return a|0}if((c[j>>2]|0)>>>0>31){a=1;i=l;return a|0}if(jb(a,1)|0){a=1;i=l;return a|0}if((jb(a,2)|0)>>>0>2){a=1;i=l;return a|0}d=ob(a,k)|0;if(d){a=d;i=l;return a|0}d=(c[k>>2]|0)+26|0;if(d>>>0>51){a=1;i=l;return a|0}c[b+52>>2]=d;d=ob(a,k)|0;if(d){a=d;i=l;return a|0}if(((c[k>>2]|0)+26|0)>>>0>51){a=1;i=l;return a|0}d=ob(a,k)|0;if(d){a=d;i=l;return a|0}d=c[k>>2]|0;if((d+12|0)>>>0>24){a=1;i=l;return a|0}c[b+56>>2]=d;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+60>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+64>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+68>>2]=(d|0)==1&1;Ka(a)|0;a=0;i=l;return a|0}function Ta(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,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;w=i;i=i+32|0;s=w+20|0;q=w+16|0;o=w+12|0;l=w+8|0;v=w+4|0;t=w;id(b,0,988);u=Z(c[d+56>>2]|0,c[d+52>>2]|0)|0;k=nb(a,v)|0;if(k){f=k;i=w;return f|0}n=c[v>>2]|0;c[b>>2]=n;if(n>>>0>=u>>>0){f=1;i=w;return f|0}k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;m=b+4|0;c[m>>2]=k;if((k|0)==5|(k|0)==0)j=5;else if(!((k|0)==7|(k|0)==2)){f=1;i=w;return f|0}if((j|0)==5){if((c[f>>2]|0)==5){f=1;i=w;return f|0}if(!(c[d+44>>2]|0)){f=1;i=w;return f|0}}k=nb(a,v)|0;if(k){f=k;i=w;return f|0}n=c[v>>2]|0;c[b+8>>2]=n;if((n|0)!=(c[e>>2]|0)){f=1;i=w;return f|0}n=d+12|0;k=c[n>>2]|0;j=0;while(1)if(!(k>>>j))break;else j=j+1|0;k=jb(a,j+-1|0)|0;if((k|0)==-1){f=1;i=w;return f|0}j=(c[f>>2]|0)==5;if(j&(k|0)!=0){f=1;i=w;return f|0}c[b+12>>2]=k;if(j){k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;c[b+16>>2]=k;if(k>>>0>65535){f=1;i=w;return f|0}}g=d+16|0;k=c[g>>2]|0;if(!k){h=d+20|0;k=c[h>>2]|0;j=0;while(1)if(!(k>>>j))break;else j=j+1|0;k=jb(a,j+-1|0)|0;if((k|0)==-1){f=1;i=w;return f|0}j=b+20|0;c[j>>2]=k;do if(c[e+8>>2]|0){k=ob(a,t)|0;if(!k){c[b+24>>2]=c[t>>2];break}else{f=k;i=w;return f|0}}while(0);if((c[f>>2]|0)==5){k=c[j>>2]|0;if(k>>>0>(c[h>>2]|0)>>>1>>>0){f=1;i=w;return f|0}j=c[b+24>>2]|0;if((k|0)!=(((j|0)>0?0:0-j|0)|0)){f=1;i=w;return f|0}}k=c[g>>2]|0}if((k|0)==1?(c[d+24>>2]|0)==0:0){k=ob(a,t)|0;if(k){f=k;i=w;return f|0}k=b+28|0;c[k>>2]=c[t>>2];do if(c[e+8>>2]|0){j=ob(a,t)|0;if(!j){c[b+32>>2]=c[t>>2];break}else{f=j;i=w;return f|0}}while(0);if((c[f>>2]|0)==5?(j=c[k>>2]|0,k=(c[d+32>>2]|0)+j+(c[b+32>>2]|0)|0,(((j|0)<(k|0)?j:k)|0)!=0):0){f=1;i=w;return f|0}}if(c[e+68>>2]|0){k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;c[b+36>>2]=k;if(k>>>0>127){f=1;i=w;return f|0}}k=c[m>>2]|0;if((k|0)==5|(k|0)==0){k=jb(a,1)|0;if((k|0)==-1){f=1;i=w;return f|0}c[b+40>>2]=k;do if(!k){k=c[e+48>>2]|0;if(k>>>0>16){f=1;i=w;return f|0}else{c[b+44>>2]=k;break}}else{k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;if(k>>>0>15){f=1;i=w;return f|0}else{c[b+44>>2]=k+1;break}}while(0);k=c[m>>2]|0}do if((k|0)==5|(k|0)==0){g=c[b+44>>2]|0;j=c[n>>2]|0;k=jb(a,1)|0;if((k|0)==-1){f=1;i=w;return f|0}c[b+68>>2]=k;if(k){h=0;a:while(1){if(h>>>0>g>>>0){r=1;j=110;break}k=nb(a,l)|0;if(k){r=k;j=110;break}k=c[l>>2]|0;if(k>>>0>3){r=1;j=110;break}c[b+(h*12|0)+72>>2]=k;do if(k>>>0<2){k=nb(a,o)|0;if(k){r=k;j=110;break a}k=c[o>>2]|0;if(k>>>0>=j>>>0){r=1;j=110;break a}c[b+(h*12|0)+76>>2]=k+1}else{if((k|0)!=2)break;k=nb(a,o)|0;if(k){r=k;j=110;break a}c[b+(h*12|0)+80>>2]=c[o>>2]}while(0);if((c[l>>2]|0)==3){j=61;break}else h=h+1|0}if((j|0)==61){if(!h)r=1;else break;i=w;return r|0}else if((j|0)==110){i=w;return r|0}}}while(0);do if(c[f+4>>2]|0){n=c[d+44>>2]|0;f=(c[f>>2]|0)==5;k=jb(a,1)|0;j=(k|0)==-1;if(f){if(j){f=1;i=w;return f|0}c[b+276>>2]=k;g=jb(a,1)|0;if((g|0)==-1){f=1;i=w;return f|0}c[b+280>>2]=g;if((n|0)!=0|(g|0)==0)break;else r=1;i=w;return r|0}if(j){f=1;i=w;return f|0}c[b+284>>2]=k;if(k){j=(n<<1)+2|0;h=0;d=0;g=0;l=0;m=0;while(1){if(h>>>0>j>>>0){r=1;j=110;break}k=nb(a,q)|0;if(k){r=k;j=110;break}k=c[q>>2]|0;if(k>>>0>6){r=1;j=110;break}c[b+(h*20|0)+288>>2]=k;if((k&-3|0)==1){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+292>>2]=(c[s>>2]|0)+1;k=c[q>>2]|0}if((k|0)==2){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+296>>2]=c[s>>2];k=c[q>>2]|0}if((k|0)==3|(k|0)==6){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+300>>2]=c[s>>2];k=c[q>>2]|0}if((k|0)==4){k=nb(a,s)|0;if(k){r=k;j=110;break}k=c[s>>2]|0;if(k>>>0>n>>>0){r=1;j=110;break}if(!k)c[b+(h*20|0)+304>>2]=65535;else c[b+(h*20|0)+304>>2]=k+-1;k=c[q>>2]|0;p=g+1|0}else p=g;l=((k|0)==5&1)+l|0;d=((k|0)!=0&k>>>0<4&1)+d|0;m=((k|0)==6&1)+m|0;if(!k){j=90;break}else{h=h+1|0;g=p}}if((j|0)==90){if(p>>>0>1|l>>>0>1|m>>>0>1){f=1;i=w;return f|0}if((d|0)!=0&(l|0)!=0)r=1;else break;i=w;return r|0}else if((j|0)==110){i=w;return r|0}}}while(0);g=ob(a,t)|0;if(g){f=g;i=w;return f|0}f=c[t>>2]|0;c[b+48>>2]=f;f=f+(c[e+52>>2]|0)|0;c[t>>2]=f;if(f>>>0>51){f=1;i=w;return f|0}do if(c[e+60>>2]|0){g=nb(a,v)|0;if(g){f=g;i=w;return f|0}g=c[v>>2]|0;c[b+52>>2]=g;if(g>>>0>2){f=1;i=w;return f|0}if((g|0)==1)break;g=ob(a,t)|0;if(g){f=g;i=w;return f|0}g=c[t>>2]|0;if((g+6|0)>>>0>12){f=1;i=w;return f|0}c[b+56>>2]=g<<1;g=ob(a,t)|0;if(g){f=g;i=w;return f|0}g=c[t>>2]|0;if((g+6|0)>>>0>12){f=1;i=w;return f|0}else{c[b+60>>2]=g<<1;break}}while(0);do if((c[e+12>>2]|0)>>>0>1?((c[e+16>>2]|0)+-3|0)>>>0<3:0){k=e+36|0;j=c[k>>2]|0;j=(((u>>>0)%(j>>>0)|0|0)==0?1:2)+((u>>>0)/(j>>>0)|0)|0;h=0;while(1){g=h+1|0;if(!(-1<>2]=g;if((g|0)==-1){f=1;i=w;return f|0}c[b+64>>2]=g;f=c[k>>2]|0;if(g>>>0>(((u+-1+f|0)>>>0)/(f>>>0)|0)>>>0)r=1;else break;i=w;return r|0}while(0);f=0;i=w;return f|0}function Ua(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;i=i+32|0;e=f+20|0;d=f;c[d+0>>2]=c[a+0>>2];c[d+4>>2]=c[a+4>>2];c[d+8>>2]=c[a+8>>2];c[d+12>>2]=c[a+12>>2];c[d+16>>2]=c[a+16>>2];a=nb(d,e)|0;if(!a){a=nb(d,e)|0;if(!a){a=nb(d,e)|0;if(!a){a=c[e>>2]|0;if(a>>>0>255)a=1;else{c[b>>2]=a;a=0}}}}i=f;return a|0}function Va(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+32|0;e=g+20|0;f=g;c[f+0>>2]=c[a+0>>2];c[f+4>>2]=c[a+4>>2];c[f+8>>2]=c[a+8>>2];c[f+12>>2]=c[a+12>>2];c[f+16>>2]=c[a+16>>2];a=nb(f,e)|0;if(a){i=g;return a|0}a=nb(f,e)|0;if(a){i=g;return a|0}a=nb(f,e)|0;if(!a)a=0;else{i=g;return a|0}while(1)if(!(b>>>a))break;else a=a+1|0;a=jb(f,a+-1|0)|0;if((a|0)==-1){a=1;i=g;return a|0}c[d>>2]=a;a=0;i=g;return a|0}function Wa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;h=i;i=i+32|0;f=h+20|0;g=h;if((d|0)!=5){d=1;i=h;return d|0};c[g+0>>2]=c[a+0>>2];c[g+4>>2]=c[a+4>>2];c[g+8>>2]=c[a+8>>2];c[g+12>>2]=c[a+12>>2];c[g+16>>2]=c[a+16>>2];d=nb(g,f)|0;if(d){i=h;return d|0}d=nb(g,f)|0;if(d){i=h;return d|0}d=nb(g,f)|0;if(!d)d=0;else{i=h;return d|0}while(1)if(!(b>>>d))break;else d=d+1|0;if((jb(g,d+-1|0)|0)==-1){d=1;i=h;return d|0}d=nb(g,e)|0;i=h;return d|0}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,j=0,k=0;k=i;i=i+32|0;h=k+20|0;j=k;c[j+0>>2]=c[a+0>>2];c[j+4>>2]=c[a+4>>2];c[j+8>>2]=c[a+8>>2];c[j+12>>2]=c[a+12>>2];c[j+16>>2]=c[a+16>>2];a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=c[b+12>>2]|0;f=0;while(1)if(!(a>>>f))break;else f=f+1|0;if((jb(j,f+-1|0)|0)==-1){f=1;i=k;return f|0}if((d|0)==5?(g=nb(j,h)|0,(g|0)!=0):0){f=g;i=k;return f|0}f=c[b+20>>2]|0;a=0;while(1)if(!(f>>>a))break;else a=a+1|0;f=jb(j,a+-1|0)|0;if((f|0)==-1){f=1;i=k;return f|0}c[e>>2]=f;f=0;i=k;return f|0}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,j=0,k=0;k=i;i=i+32|0;h=k+20|0;j=k;c[j+0>>2]=c[a+0>>2];c[j+4>>2]=c[a+4>>2];c[j+8>>2]=c[a+8>>2];c[j+12>>2]=c[a+12>>2];c[j+16>>2]=c[a+16>>2];a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=c[b+12>>2]|0;f=0;while(1)if(!(a>>>f))break;else f=f+1|0;if((jb(j,f+-1|0)|0)==-1){f=1;i=k;return f|0}if((d|0)==5?(g=nb(j,h)|0,(g|0)!=0):0){f=g;i=k;return f|0}f=c[b+20>>2]|0;a=0;while(1)if(!(f>>>a))break;else a=a+1|0;if((jb(j,a+-1|0)|0)==-1){f=1;i=k;return f|0}f=ob(j,e)|0;i=k;return f|0}function Za(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,j=0,k=0,l=0,m=0;m=i;i=i+32|0;j=m+20|0;l=m;c[l+0>>2]=c[a+0>>2];c[l+4>>2]=c[a+4>>2];c[l+8>>2]=c[a+8>>2];c[l+12>>2]=c[a+12>>2];c[l+16>>2]=c[a+16>>2];g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=c[b+12>>2]|0;a=0;while(1)if(!(g>>>a))break;else a=a+1|0;if((jb(l,a+-1|0)|0)==-1){l=1;i=m;return l|0}if((d|0)==5?(h=nb(l,j)|0,(h|0)!=0):0){l=h;i=m;return l|0}g=ob(l,f)|0;if(g){l=g;i=m;return l|0}if((e|0)!=0?(k=ob(l,f+4|0)|0,(k|0)!=0):0){l=k;i=m;return l|0}l=0;i=m;return l|0}function _a(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,j=0,k=0,l=0,m=0,n=0,o=0;m=i;i=i+32|0;l=m+24|0;j=m+20|0;k=m;c[k+0>>2]=c[b+0>>2];c[k+4>>2]=c[b+4>>2];c[k+8>>2]=c[b+8>>2];c[k+12>>2]=c[b+12>>2];c[k+16>>2]=c[b+16>>2];f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=c[d+12>>2]|0;b=0;while(1)if(!(f>>>b))break;else b=b+1|0;if((jb(k,b+-1|0)|0)==-1){n=1;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}g=d+16|0;f=c[g>>2]|0;if(!f){b=c[d+20>>2]|0;f=0;while(1)if(!(b>>>f))break;else f=f+1|0;if((jb(k,f+-1|0)|0)==-1){n=1;i=m;return n|0}if((c[e+8>>2]|0)!=0?(h=ob(k,j)|0,(h|0)!=0):0){n=h;i=m;return n|0}f=c[g>>2]|0}if((f|0)==1?(c[d+24>>2]|0)==0:0){f=ob(k,j)|0;if(f){n=f;i=m;return n|0}if((c[e+8>>2]|0)!=0?(n=ob(k,j)|0,(n|0)!=0):0){i=m;return n|0}}if((c[e+68>>2]|0)!=0?(o=nb(k,l)|0,(o|0)!=0):0){n=o;i=m;return n|0}n=jb(k,1)|0;c[a>>2]=n;n=(n|0)==-1&1;i=m;return n|0}function $a(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=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;C=i;i=i+448|0;p=C+8|0;x=C+4|0;v=C;p=p+(0-p&15)|0;n=c[b+3376>>2]|0;j=c[e>>2]|0;c[x>>2]=0;y=b+1192|0;c[y>>2]=(c[y>>2]|0)+1;q=b+1200|0;c[q>>2]=0;o=b+12|0;c[v>>2]=(c[e+48>>2]|0)+(c[(c[o>>2]|0)+52>>2]|0);w=e+36|0;r=b+1212|0;s=e+52|0;t=e+56|0;u=e+60|0;z=e+4|0;l=e+44|0;h=b+1220|0;m=b+1172|0;B=b+1176|0;k=n+12|0;A=0;f=0;while(1){e=c[r>>2]|0;if((c[w>>2]|0)==0?(c[e+(j*216|0)+196>>2]|0)!=0:0){f=1;e=22;break}g=c[(c[o>>2]|0)+56>>2]|0;F=c[s>>2]|0;E=c[t>>2]|0;D=c[u>>2]|0;c[e+(j*216|0)+4>>2]=c[y>>2];c[e+(j*216|0)+8>>2]=F;c[e+(j*216|0)+12>>2]=E;c[e+(j*216|0)+16>>2]=D;c[e+(j*216|0)+24>>2]=g;e=c[z>>2]|0;if((e|0)!=2?!((e|0)==7|(f|0)!=0):0){f=nb(a,x)|0;if(f){e=22;break}e=c[x>>2]|0;if(e>>>0>((c[B>>2]|0)-j|0)>>>0){f=1;e=22;break}if(!e)f=0;else{id(k,0,164);c[n>>2]=0;f=1}}e=c[x>>2]|0;if(!e){f=bb(a,n,(c[r>>2]|0)+(j*216|0)|0,c[z>>2]|0,c[l>>2]|0)|0;if(!f)g=0;else{e=22;break}}else{c[x>>2]=e+-1;g=f}f=gb((c[r>>2]|0)+(j*216|0)|0,n,d,h,v,j,c[(c[o>>2]|0)+64>>2]|0,p)|0;if(f){e=22;break}A=((c[(c[r>>2]|0)+(j*216|0)+196>>2]|0)==1&1)+A|0;if(!(La(a)|0))e=(c[x>>2]|0)!=0;else e=1;f=c[z>>2]|0;if((f|0)==7|(f|0)==2)c[q>>2]=j;j=Ma(c[m>>2]|0,c[B>>2]|0,j)|0;if(!((j|0)!=0|e^1)){f=1;e=22;break}if(!e){e=20;break}else f=g}if((e|0)==20){e=b+1196|0;f=(c[e>>2]|0)+A|0;if(f>>>0>(c[B>>2]|0)>>>0){y=1;i=C;return y|0}c[e>>2]=f;y=0;i=C;return y|0}else if((e|0)==22){i=C;return f|0}return 0}function ab(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;h=c[a+1192>>2]|0;d=c[a+1200>>2]|0;j=a+1212|0;a:do if(!d)d=b;else{e=a+16|0;f=0;do{do{d=d+-1|0;if(d>>>0<=b>>>0)break a}while((c[(c[j>>2]|0)+(d*216|0)+4>>2]|0)!=(h|0));f=f+1|0;g=c[(c[e>>2]|0)+52>>2]|0}while(f>>>0<(g>>>0>10?g:10)>>>0)}while(0);g=a+1172|0;b=a+1176|0;while(1){e=c[j>>2]|0;if((c[e+(d*216|0)+4>>2]|0)!=(h|0)){d=11;break}f=e+(d*216|0)+196|0;e=c[f>>2]|0;if(!e){d=11;break}c[f>>2]=e+-1;d=Ma(c[g>>2]|0,c[b>>2]|0,d)|0;if(!d){d=11;break}}if((d|0)==11){i=k;return}}function bb(a,d,e,f,g){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=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;B=i;i=i+32|0;u=B+20|0;v=B+16|0;q=B+12|0;p=B+8|0;z=B+4|0;y=B;id(d,0,2088);l=nb(a,z)|0;m=c[z>>2]|0;do if((f|0)==2|(f|0)==7){m=m+6|0;if(m>>>0>31|(l|0)!=0){e=1;i=B;return e|0}else{c[d>>2]=m;o=m;break}}else{m=m+1|0;if(m>>>0>31|(l|0)!=0){e=1;i=B;return e|0}else{c[d>>2]=m;o=m;break}}while(0);a:do if((o|0)!=31){b:do if(o>>>0>=6){o=(o|0)!=6;p=o&1;if(!p){c[v>>2]=0;q=0;while(1){f=kb(a)|0;c[u>>2]=f;t=f>>>31;c[d+(q<<2)+12>>2]=t;if(!t){c[d+(q<<2)+76>>2]=f>>>28&7;m=f<<4;n=1}else{m=f<<1;n=0}f=q|1;t=m>>>31;c[d+(f<<2)+12>>2]=t;if(!t){c[d+(f<<2)+76>>2]=m>>>28&7;l=m<<4;n=n+1|0}else l=m<<1;m=f+1|0;t=l>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=l>>>28&7;m=l<<4;n=n+1|0}else m=l<<1;l=q|3;t=m>>>31;c[d+(l<<2)+12>>2]=t;if(!t){c[d+(l<<2)+76>>2]=m>>>28&7;f=m<<4;n=n+1|0}else f=m<<1;m=l+1|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=l+2|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=l+3|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=q|7;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;m=f<<4;n=n+1|0}else m=f<<1;c[u>>2]=m;if((lb(a,(n*3|0)+8|0)|0)==-1){w=1;t=68;break b}t=(c[v>>2]|0)+1|0;c[v>>2]=t;if((t|0)<2)q=q+8|0;else{t=52;break}}}else if((p|0)==1)t=52;if((t|0)==52){v=(nb(a,u)|0)!=0;l=c[u>>2]|0;if(v|l>>>0>3){w=1;t=68;break}c[d+140>>2]=l}if(o){v=c[d>>2]|0;s=v+-7|0;u=s>>>2;c[d+4>>2]=(s>>>0>11?u+268435453|0:u)<<4|(v>>>0>18?15:0)}else{x=p;t=70}}else{if((o|0)==0|(o|0)==1){r=v;s=u}else if(!((o|0)==3|(o|0)==2)){f=0;do{l=(nb(a,q)|0)!=0;m=c[q>>2]|0;if(l|m>>>0>3){n=1;t=96;break}c[d+(f<<2)+176>>2]=m;f=f+1|0}while(f>>>0<4);if((t|0)==96){i=B;return n|0}c:do if(g>>>0>1&(o|0)!=5){m=g>>>0>2&1;f=0;while(1){if(qb(a,q,m)|0){n=1;t=96;break}n=c[q>>2]|0;if(n>>>0>=g>>>0){n=1;t=96;break}c[d+(f<<2)+192>>2]=n;f=f+1|0;if(f>>>0>=4){h=0;break c}}if((t|0)==96){i=B;return n|0}}else h=0;while(0);d:while(1){n=c[d+(h<<2)+176>>2]|0;if(!n)n=0;else if((n|0)==2|(n|0)==1)n=1;else n=3;c[q>>2]=n;m=0;while(1){n=ob(a,p)|0;if(n){t=96;break d}b[d+(h<<4)+(m<<2)+208>>1]=c[p>>2];n=ob(a,p)|0;if(n){t=96;break d}b[d+(h<<4)+(m<<2)+210>>1]=c[p>>2];t=c[q>>2]|0;c[q>>2]=t+-1;if(!t)break;else m=m+1|0}h=h+1|0;if(h>>>0>=4){x=2;t=70;break b}}if((t|0)==96){i=B;return n|0}}else{r=v;s=u}if(g>>>0>1){if((o|0)==0|(o|0)==1)n=0;else if((o|0)==3|(o|0)==2)n=1;else n=3;l=g>>>0>2&1;f=0;while(1){if(qb(a,u,l)|0){w=1;t=68;break b}m=c[u>>2]|0;if(m>>>0>=g>>>0){w=1;t=68;break b}c[d+(f<<2)+144>>2]=m;if(!n)break;else{n=n+-1|0;f=f+1|0}}}if((o|0)==0|(o|0)==1){l=0;m=0}else if((o|0)==3|(o|0)==2){l=1;m=0}else{l=3;m=0}while(1){f=ob(a,v)|0;if(f){w=f;t=68;break b}b[d+(m<<2)+160>>1]=c[v>>2];f=ob(a,v)|0;if(f){w=f;t=68;break b}b[d+(m<<2)+162>>1]=c[v>>2];if(!l){x=2;t=70;break}else{l=l+-1|0;m=m+1|0}}}while(0);if((t|0)==68){e=w;i=B;return e|0}do if((t|0)==70){h=pb(a,z,(x|0)==0&1)|0;if(!h){z=c[z>>2]|0;c[d+4>>2]=z;if(!z)break a;else break}else{e=h;i=B;return e|0}}while(0);z=(ob(a,y)|0)!=0;h=c[y>>2]|0;if(z|(h|0)<-26|(h|0)>25){e=1;i=B;return e|0}c[d+8>>2]=h;l=c[d+4>>2]|0;o=d+272|0;e:do if((c[d>>2]|0)>>>0>=7){h=rb(a,d+1864|0,ib(e,0,o)|0,16)|0;if(!(h&15)){b[d+320>>1]=h>>>4&255;h=0;m=3;while(1){n=l>>>1;if(!(l&1))h=h+4|0;else{f=3;while(1){l=rb(a,d+(h<<6)+332|0,ib(e,h,o)|0,15)|0;c[d+(h<<2)+1992>>2]=l>>>15;if(l&15){j=l;break e}b[d+(h<<1)+272>>1]=l>>>4&255;h=h+1|0;if(!f)break;else f=f+-1|0}}if(!m){k=h;A=n;t=87;break}else{l=n;m=m+-1|0}}}else j=h}else{h=0;m=3;while(1){n=l>>>1;if(!(l&1))h=h+4|0;else{f=3;while(1){l=rb(a,d+(h<<6)+328|0,ib(e,h,o)|0,16)|0;c[d+(h<<2)+1992>>2]=l>>>16;if(l&15){j=l;break e}b[d+(h<<1)+272>>1]=l>>>4&255;h=h+1|0;if(!f)break;else f=f+-1|0}}if(!m){k=h;A=n;t=87;break}else{l=n;m=m+-1|0}}}while(0);f:do if((t|0)==87){if(A&3){j=rb(a,d+1928|0,-1,4)|0;if(j&15)break;b[d+322>>1]=j>>>4&255;j=rb(a,d+1944|0,-1,4)|0;if(j&15)break;b[d+324>>1]=j>>>4&255}if(!(A&2))j=0;else{h=7;while(1){j=rb(a,d+(k<<6)+332|0,ib(e,k,o)|0,15)|0;if(j&15)break f;b[d+(k<<1)+272>>1]=j>>>4&255;c[d+(k<<2)+1992>>2]=j>>>15;if(!h){j=0;break}else{k=k+1|0;h=h+-1|0}}}}while(0);c[a+16>>2]=((c[a+4>>2]|0)-(c[a>>2]|0)<<3)+(c[a+8>>2]|0);if(j){e=j;i=B;return e|0}}else{while(1){if(mb(a)|0)break;if(jb(a,1)|0){n=1;t=96;break}}if((t|0)==96){i=B;return n|0}k=0;j=d+328|0;while(1){h=jb(a,8)|0;c[z>>2]=h;if((h|0)==-1){n=1;break}c[j>>2]=h;k=k+1|0;if(k>>>0>=384)break a;else j=j+4|0}i=B;return n|0}while(0);e=0;i=B;return e|0}function cb(a){a=a|0;if(a>>>0<6)a=2;else a=(a|0)!=6&1;return a|0}function db(a){a=a|0;var b=0;b=i;if((a|0)==0|(a|0)==1)a=1;else if((a|0)==3|(a|0)==2)a=2;else a=4;i=b;return a|0}function eb(a){a=a|0;var b=0;b=i;if(!a)a=1;else if((a|0)==2|(a|0)==1)a=2;else a=4;i=b;return a|0}function fb(a){a=a|0;return a+1&3|0}function gb(d,e,f,g,h,j,k,l){d=d|0;e=e|0;f=f|0;g=g|0;h=h|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;v=i;s=c[e>>2]|0;c[d>>2]=s;o=d+196|0;c[o>>2]=(c[o>>2]|0)+1;Na(f,j);if((s|0)==31){m=d+28|0;c[d+20>>2]=0;if((c[o>>2]|0)>>>0>1){b[m>>1]=16;b[d+30>>1]=16;b[d+32>>1]=16;b[d+34>>1]=16;b[d+36>>1]=16;b[d+38>>1]=16;b[d+40>>1]=16;b[d+42>>1]=16;b[d+44>>1]=16;b[d+46>>1]=16;b[d+48>>1]=16;b[d+50>>1]=16;b[d+52>>1]=16;b[d+54>>1]=16;b[d+56>>1]=16;b[d+58>>1]=16;b[d+60>>1]=16;b[d+62>>1]=16;b[d+64>>1]=16;b[d+66>>1]=16;b[d+68>>1]=16;b[d+70>>1]=16;b[d+72>>1]=16;b[d+74>>1]=16;t=0;i=v;return t|0}o=23;h=e+328|0;n=l;while(1){b[m>>1]=16;a[n>>0]=c[h>>2];a[n+1>>0]=c[h+4>>2];a[n+2>>0]=c[h+8>>2];a[n+3>>0]=c[h+12>>2];a[n+4>>0]=c[h+16>>2];a[n+5>>0]=c[h+20>>2];a[n+6>>0]=c[h+24>>2];a[n+7>>0]=c[h+28>>2];a[n+8>>0]=c[h+32>>2];a[n+9>>0]=c[h+36>>2];a[n+10>>0]=c[h+40>>2];a[n+11>>0]=c[h+44>>2];a[n+12>>0]=c[h+48>>2];a[n+13>>0]=c[h+52>>2];a[n+14>>0]=c[h+56>>2];a[n+15>>0]=c[h+60>>2];if(!o)break;else{o=o+-1|0;h=h+64|0;n=n+16|0;m=m+2|0}}sc(f,l);t=0;i=v;return t|0}m=d+28|0;if(s){hd(m,e+272|0,54);n=c[e+8>>2]|0;o=c[h>>2]|0;do if(n){o=o+n|0;c[h>>2]=o;if((o|0)<0){o=o+52|0;c[h>>2]=o;break}if((o|0)>51){o=o+-52|0;c[h>>2]=o}}while(0);r=d+20|0;c[r>>2]=o;n=e+328|0;h=e+1992|0;a:do if((c[d>>2]|0)>>>0<7){q=15;o=m;while(1){if(b[o>>1]|0){if(Ga(n,c[r>>2]|0,0,c[h>>2]|0)|0){m=1;break}}else c[n>>2]=16777215;n=n+64|0;o=o+2|0;h=h+4|0;if(!q)break a;else q=q+-1|0}i=v;return m|0}else{if(!(b[d+76>>1]|0)){q=464;p=15;o=m}else{Ha(e+1864|0,o);q=464;p=15;o=m}while(1){m=c[e+(c[q>>2]<<2)+1864>>2]|0;q=q+4|0;c[n>>2]=m;if((m|0)==0?(b[o>>1]|0)==0:0)c[n>>2]=16777215;else u=18;if((u|0)==18?(u=0,(Ga(n,c[r>>2]|0,1,c[h>>2]|0)|0)!=0):0){m=1;break}n=n+64|0;o=o+2|0;h=h+4|0;if(!p)break a;else p=p+-1|0}i=v;return m|0}while(0);q=c[192+((Oa(0,51,(c[d+24>>2]|0)+(c[r>>2]|0)|0)|0)<<2)>>2]|0;if((b[d+78>>1]|0)==0?(b[d+80>>1]|0)==0:0){p=e+1928|0;m=7}else{p=e+1928|0;Ia(p,q);m=7}while(1){r=c[p>>2]|0;p=p+4|0;c[n>>2]=r;if((r|0)==0?(b[o>>1]|0)==0:0)c[n>>2]=16777215;else u=31;if((u|0)==31?(u=0,(Ga(n,q,1,c[h>>2]|0)|0)!=0):0){m=1;u=39;break}if(!m)break;else{n=n+64|0;h=h+4|0;m=m+-1|0;o=o+2|0}}if((u|0)==39){i=v;return m|0}if(s>>>0>=6){o=Mb(d,e,f,j,k,l)|0;if(o){t=o;i=v;return t|0}}else u=37}else{id(m,0,54);c[d+20>>2]=c[h>>2];u=37}if((u|0)==37?(t=Sb(d,e,g,j,f,l)|0,(t|0)!=0):0){i=v;return t|0}t=0;i=v;return t|0}function hb(a){a=a|0;return a|0}function ib(d,e,f){d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0;k=i;l=vb(e)|0;g=wb(e)|0;h=a[l+4>>0]|0;j=a[g+4>>0]|0;g=(c[g>>2]|0)==4;if((c[l>>2]|0)==4){e=b[f+((h&255)<<1)>>1]|0;if(g){e=e+1+(b[f+((j&255)<<1)>>1]|0)>>1;i=k;return e|0}g=d+204|0;if(!(zb(d,c[g>>2]|0)|0)){i=k;return e|0}e=e+1+(b[(c[g>>2]|0)+((j&255)<<1)+28>>1]|0)>>1;i=k;return e|0}if(g){e=b[f+((j&255)<<1)>>1]|0;g=d+200|0;if(!(zb(d,c[g>>2]|0)|0)){i=k;return e|0}e=e+1+(b[(c[g>>2]|0)+((h&255)<<1)+28>>1]|0)>>1;i=k;return e|0}g=d+200|0;if(!(zb(d,c[g>>2]|0)|0)){h=0;f=0}else{h=b[(c[g>>2]|0)+((h&255)<<1)+28>>1]|0;f=1}g=d+204|0;if(!(zb(d,c[g>>2]|0)|0)){e=h;i=k;return e|0}e=b[(c[g>>2]|0)+((j&255)<<1)+28>>1]|0;if(!f){i=k;return e|0}e=h+1+e>>1;i=k;return e|0}function jb(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;n=a+4|0;j=c[n>>2]|0;m=c[a+12>>2]<<3;o=a+16|0;l=c[o>>2]|0;g=m-l|0;if((g|0)>31){e=a+8|0;g=c[e>>2]|0;f=(d[j+1>>0]|0)<<16|(d[j>>0]|0)<<24|(d[j+2>>0]|0)<<8|(d[j+3>>0]|0);if(!g)h=e;else{h=e;f=(d[j+4>>0]|0)>>>(8-g|0)|f<0){e=c[h>>2]|0;k=e+24|0;f=(d[j>>0]|0)<0){e=g;g=k;do{j=j+1|0;g=g+-8|0;f=(d[j>>0]|0)<0)}}else f=0}e=l+b|0;c[o>>2]=e;c[h>>2]=e&7;if(e>>>0>m>>>0){n=-1;i=p;return n|0}c[n>>2]=(c[a>>2]|0)+(e>>>3);n=f>>>(32-b|0);i=p;return n|0}function kb(a){a=a|0;var b=0,e=0,f=0,g=0,h=0;g=i;f=c[a+4>>2]|0;e=(c[a+12>>2]<<3)-(c[a+16>>2]|0)|0;if((e|0)>31){b=c[a+8>>2]|0;a=(d[f+1>>0]|0)<<16|(d[f>>0]|0)<<24|(d[f+2>>0]|0)<<8|(d[f+3>>0]|0);if(!b){b=a;i=g;return b|0}b=(d[f+4>>0]|0)>>>(8-b|0)|a<>2]|0;a=h+24|0;b=(d[f>>0]|0)<>0]|0)<0);i=g;return b|0}function lb(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;e=a+16|0;b=(c[e>>2]|0)+b|0;c[e>>2]=b;c[a+8>>2]=b&7;if(b>>>0>c[a+12>>2]<<3>>>0){b=-1;i=d;return b|0}c[a+4>>2]=(c[a>>2]|0)+(b>>>3);b=0;i=d;return b|0}function mb(a){a=a|0;return (c[a+8>>2]|0)==0|0}function nb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=i;d=kb(a)|0;do if((d|0)>=0){if(d>>>0>1073741823){if((lb(a,3)|0)==-1){d=1;break}c[b>>2]=(d>>>29&1)+1;d=0;break}if(d>>>0>536870911){if((lb(a,5)|0)==-1){d=1;break}c[b>>2]=(d>>>27&3)+3;d=0;break}if(d>>>0>268435455){if((lb(a,7)|0)==-1){d=1;break}c[b>>2]=(d>>>25&7)+7;d=0;break}d=Ja(d,28)|0;e=d+4|0;if((e|0)!=32){lb(a,d+5|0)|0;d=jb(a,e)|0;if((d|0)==-1){d=1;break}c[b>>2]=(1<>2]=0;lb(a,32)|0;if((jb(a,1)|0)==1?(f=kb(a)|0,(lb(a,32)|0)!=-1):0)if((f|0)==1){c[b>>2]=-1;d=1;break}else if(!f){c[b>>2]=-1;d=0;break}else{d=1;break}else d=1}else{lb(a,1)|0;c[b>>2]=0;d=0}while(0);i=g;return d|0}function ob(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;f=e;c[f>>2]=0;d=nb(a,f)|0;a=c[f>>2]|0;d=(d|0)==0;if((a|0)==-1)if(d)a=1;else{c[b>>2]=-2147483648;a=0}else if(d){d=(a+1|0)>>>1;c[b>>2]=(a&1|0)!=0?d:0-d|0;a=0}else a=1;i=e;return a|0}function pb(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0;g=i;i=i+16|0;f=g;if(nb(a,f)|0){f=1;i=g;return f|0}f=c[f>>2]|0;if(f>>>0>47){f=1;i=g;return f|0}c[b>>2]=d[((e|0)==0?576:528)+f>>0];f=0;i=g;return f|0}function qb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=i;if(!d){d=jb(a,1)|0;c[b>>2]=d;if((d|0)==-1)d=1;else{c[b>>2]=d^1;d=0}}else d=nb(a,b)|0;i=e;return d|0}function rb(a,b,f,g){a=a|0;b=b|0;f=f|0;g=g|0;var h=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,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0;O=i;i=i+128|0;M=O+64|0;N=O;n=kb(a)|0;p=n>>>16;do if(f>>>0<2)if((n|0)>=0){if(n>>>0>201326591){o=e[1264+(n>>>26<<1)>>1]|0;k=25;break}if(n>>>0>16777215){o=e[1328+(n>>>22<<1)>>1]|0;k=25;break}if(n>>>0>2097151){o=e[1424+((n>>>18)+-8<<1)>>1]|0;k=25;break}else{o=e[1536+(p<<1)>>1]|0;k=25;break}}else q=1;else if(f>>>0<4){if((n|0)<0){q=(p&16384|0)!=0?2:2082;break}if(n>>>0>268435455){o=e[1600+(n>>>26<<1)>>1]|0;k=25;break}if(n>>>0>33554431){o=e[1664+(n>>>23<<1)>>1]|0;k=25;break}else{o=e[1728+(n>>>18<<1)>>1]|0;k=25;break}}else{if(f>>>0<8){f=n>>>26;if((f+-8|0)>>>0<56){o=e[1984+(f<<1)>>1]|0;k=25;break}o=e[2112+(n>>>22<<1)>>1]|0;k=25;break}if(f>>>0<17){o=e[2368+(n>>>26<<1)>>1]|0;k=25;break}f=n>>>29;if(f){o=e[2496+(f<<1)>>1]|0;k=25;break}o=e[2512+(n>>>24<<1)>>1]|0;k=25;break}while(0);if((k|0)==25)if(!o){C=1;i=O;return C|0}else q=o;o=q&31;f=n<>>11&31;if(I>>>0>g>>>0){C=1;i=O;return C|0}v=q>>>5&63;do if(I){if(!v)o=0;else{do if(p>>>0>>0)if((lb(a,o)|0)==-1){C=1;i=O;return C|0}else{p=32;f=kb(a)|0;break}while(0);n=f>>>(32-v|0);f=f<>2]=(o&n|0)!=0?-1:1;o=o>>>1;k=k+1|0}while((o|0)!=0);p=p-v|0;o=k}u=v>>>0<3;a:do if(o>>>0>>0){t=o;s=I>>>0>10&u&1;b:while(1){if(p>>>0<16){if((lb(a,32-p|0)|0)==-1){J=1;k=127;break}r=32;f=kb(a)|0}else r=p;do if((f|0)>=0)if(f>>>0<=1073741823)if(f>>>0<=536870911)if(f>>>0<=268435455)if(f>>>0<=134217727)if(f>>>0<=67108863)if(f>>>0<=33554431)if(f>>>0<=16777215)if(f>>>0<=8388607)if(f>>>0>4194303){H=9;k=59}else{if(f>>>0>2097151){H=10;k=59;break}if(f>>>0>1048575){H=11;k=59;break}if(f>>>0>524287){H=12;k=59;break}if(f>>>0>262143){H=13;k=59;break}if(f>>>0>131071){p=14;o=f<<15;n=r+-15|0;q=s;k=(s|0)!=0?s:4}else{if(f>>>0<65536){J=1;k=127;break b}p=15;o=f<<16;n=r+-16|0;q=(s|0)!=0?s:1;k=12}G=p<>>0>>0){if((lb(a,32-y|0)|0)==-1){J=1;k=127;break}o=32;f=kb(a)|0}else{o=y;f=B}E=o-x|0;F=f<>>(32-x|0))+G|0;C=z;D=w}s=(t|0)==(v|0)&u?A+2|0:A;o=(s+2|0)>>>1;n=D?1:C;c[M+(t<<2)>>2]=(s&1|0)==0?o:0-o|0;t=t+1|0;if(t>>>0>=I>>>0){l=E;m=F;break a}else{p=E;f=F;s=((o|0)>(3<>>0<6&1)+n|0}}if((k|0)==127){i=O;return J|0}}else{l=p;m=f}while(0);if(I>>>0>>0){do if(l>>>0<9)if((lb(a,32-l|0)|0)==-1){C=1;i=O;return C|0}else{l=32;m=kb(a)|0;break}while(0);k=m>>>23;c:do if((g|0)==4)if((m|0)>=0)if((I|0)!=3)if(m>>>0<=1073741823)if((I|0)==2)k=34;else k=m>>>0>536870911?35:51;else k=18;else k=17;else k=1;else{do switch(I|0){case 8:{k=d[1056+(m>>>26)>>0]|0;break}case 9:{k=d[1120+(m>>>26)>>0]|0;break}case 2:{k=d[736+(m>>>26)>>0]|0;break}case 1:{if(m>>>0>268435455)k=d[672+(m>>>27)>>0]|0;else k=d[704+k>>0]|0;break}case 13:{k=d[1248+(m>>>29)>>0]|0;break}case 14:{k=d[1256+(m>>>30)>>0]|0;break}case 3:{k=d[800+(m>>>26)>>0]|0;break}case 4:{k=d[864+(m>>>27)>>0]|0;break}case 5:{k=d[896+(m>>>27)>>0]|0;break}case 10:{k=d[1184+(m>>>27)>>0]|0;break}case 6:{k=d[928+(m>>>26)>>0]|0;break}case 7:{k=d[992+(m>>>26)>>0]|0;break}case 11:{k=d[1216+(m>>>28)>>0]|0;break}case 12:{k=d[1232+(m>>>28)>>0]|0;break}default:{k=m>>31&16|1;break c}}while(0);if(!k){C=1;i=O;return C|0}}while(0);n=k&15;l=l-n|0;m=m<>>4&15}else n=0;p=I+-1|0;f=(p|0)==0;if(f){c[b+(n<<2)>>2]=c[M+(p<<2)>>2];K=l;h=1<>2]=1;L=l;j=0}else{if(l>>>0<11){if((lb(a,32-l|0)|0)==-1){J=1;k=127;break}l=32;k=kb(a)|0}switch(n|0){case 4:{m=d[648+(k>>>29)>>0]|0;break}case 5:{m=d[656+(k>>>29)>>0]|0;break}case 6:{m=d[664+(k>>>29)>>0]|0;break}case 1:{m=d[624+(k>>>31)>>0]|0;break}case 2:{m=d[632+(k>>>30)>>0]|0;break}case 3:{m=d[640+(k>>>30)>>0]|0;break}default:{do if(k>>>0<=536870911)if(k>>>0<=268435455)if(k>>>0<=134217727)if(k>>>0<=67108863)if(k>>>0<=33554431)if(k>>>0>16777215)m=184;else{if(k>>>0>8388607){m=201;break}if(k>>>0>4194303){m=218;break}m=k>>>0<2097152?0:235}else m=167;else m=150;else m=133;else m=116;else m=k>>>29<<4^115;while(0);if((m>>>4&15)>>>0>n>>>0){J=1;k=127;break d}}}if(!m){J=1;k=127;break}C=m&15;j=m>>>4&15;c[N+(o<<2)>>2]=j+1;L=l-C|0;k=k<>>0>=p>>>0){k=122;break}else{l=L;n=j}}if((k|0)==122){c[b+(j<<2)>>2]=c[M+(p<<2)>>2];h=1<>2]|0)+j|0;h=1<>2]=c[M+(k<<2)>>2];if(!k){K=L;break}else k=k+-1|0}}else if((k|0)==127){i=O;return J|0}}else{K=p;h=0}while(0);if(lb(a,32-K|0)|0){C=1;i=O;return C|0}C=h<<16|I<<4;i=O;return C|0}function sb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;a:do if((jb(a,1)|0)!=-1?(e=b+4|0,c[e>>2]=jb(a,2)|0,d=jb(a,5)|0,c[b>>2]=d,(d+-2|0)>>>0>=3):0){switch(d|0){case 6:case 9:case 10:case 11:case 12:{if(c[e>>2]|0){d=1;break a}break}case 5:case 7:case 8:{if(!(c[e>>2]|0)){d=1;break a}switch(d|0){case 6:case 9:case 10:case 11:case 12:{d=1;break a}default:{}}break}default:{}}d=0}else d=1;while(0);i=f;return d|0}function tb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;if(!d){i=o;return}m=b+-1|0;j=1-b|0;k=~b;g=0;h=0;l=0;while(1){f=(g|0)!=0;if(f)c[a+(h*216|0)+200>>2]=a+((h+-1|0)*216|0);else c[a+(h*216|0)+200>>2]=0;e=(l|0)!=0;if(e){c[a+(h*216|0)+204>>2]=a+((h-b|0)*216|0);if(g>>>0>>0)c[a+(h*216|0)+208>>2]=a+((j+h|0)*216|0);else n=10}else{c[a+(h*216|0)+204>>2]=0;n=10}if((n|0)==10){n=0;c[a+(h*216|0)+208>>2]=0}if(e&f)c[a+(h*216|0)+212>>2]=a+((h+k|0)*216|0);else c[a+(h*216|0)+212>>2]=0;e=g+1|0;f=(e|0)==(b|0);h=h+1|0;if((h|0)==(d|0))break;else{g=f?0:e;l=(f&1)+l|0}}i=o;return}function ub(a,b){a=a|0;b=b|0;var d=0;d=i;switch(b|0){case 1:{a=c[a+204>>2]|0;break}case 3:{a=c[a+212>>2]|0;break}case 4:break;case 2:{a=c[a+208>>2]|0;break}case 0:{a=c[a+200>>2]|0;break}default:a=0}i=d;return a|0}function vb(a){a=a|0;return 3152+(a<<3)|0}function wb(a){a=a|0;return 2960+(a<<3)|0}function xb(a){a=a|0;return 2768+(a<<3)|0}function yb(a){a=a|0;return 2576+(a<<3)|0}function zb(a,b){a=a|0;b=b|0;var d=0;d=i;if(!b){i=d;return 0}else{i=d;return (c[a+4>>2]|0)==(c[b+4>>2]|0)|0}return 0}function Ab(a){a=a|0;var b=0;b=i;id(a,0,3388);c[a+8>>2]=32;c[a+4>>2]=256;c[a+1332>>2]=1;i=b;return}function Bb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;f=c[b+8>>2]|0;g=a+(f<<2)+20|0;e=c[g>>2]|0;do if(!e){d=fd(92)|0;c[g>>2]=d;if(!d){d=65535;i=h;return d|0}}else{d=a+8|0;if((f|0)!=(c[d>>2]|0)){gd(c[e+40>>2]|0);c[(c[g>>2]|0)+40>>2]=0;gd(c[(c[g>>2]|0)+84>>2]|0);c[(c[g>>2]|0)+84>>2]=0;break}f=a+16|0;if(Ra(b,c[f>>2]|0)|0){gd(c[(c[g>>2]|0)+40>>2]|0);c[(c[g>>2]|0)+40>>2]=0;gd(c[(c[g>>2]|0)+84>>2]|0);c[(c[g>>2]|0)+84>>2]=0;c[d>>2]=33;c[a+4>>2]=257;c[f>>2]=0;c[a+12>>2]=0;break}d=b+40|0;gd(c[d>>2]|0);c[d>>2]=0;d=b+84|0;gd(c[d>>2]|0);c[d>>2]=0;d=0;i=h;return d|0}while(0);f=(c[g>>2]|0)+0|0;d=b+0|0;e=f+92|0;do{c[f>>2]=c[d>>2];f=f+4|0;d=d+4|0}while((f|0)<(e|0));d=0;i=h;return d|0}function Cb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;f=c[b>>2]|0;g=a+(f<<2)+148|0;d=c[g>>2]|0;do if(!d){d=fd(72)|0;c[g>>2]=d;if(!d){d=65535;i=h;return d|0}}else{e=a+4|0;if((f|0)!=(c[e>>2]|0)){gd(c[d+20>>2]|0);c[(c[g>>2]|0)+20>>2]=0;gd(c[(c[g>>2]|0)+24>>2]|0);c[(c[g>>2]|0)+24>>2]=0;gd(c[(c[g>>2]|0)+28>>2]|0);c[(c[g>>2]|0)+28>>2]=0;gd(c[(c[g>>2]|0)+44>>2]|0);c[(c[g>>2]|0)+44>>2]=0;break}if((c[b+4>>2]|0)!=(c[a+8>>2]|0)){c[e>>2]=257;d=c[g>>2]|0}gd(c[d+20>>2]|0);c[(c[g>>2]|0)+20>>2]=0;gd(c[(c[g>>2]|0)+24>>2]|0);c[(c[g>>2]|0)+24>>2]=0;gd(c[(c[g>>2]|0)+28>>2]|0);c[(c[g>>2]|0)+28>>2]=0;gd(c[(c[g>>2]|0)+44>>2]|0);c[(c[g>>2]|0)+44>>2]=0}while(0);f=(c[g>>2]|0)+0|0;d=b+0|0;e=f+72|0;do{c[f>>2]=c[d>>2];f=f+4|0;d=d+4|0}while((f|0)<(e|0));d=0;i=h;return d|0}function Db(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;o=a+(b<<2)+148|0;f=c[o>>2]|0;if(!f){o=1;i=q;return o|0}n=c[f+4>>2]|0;g=c[a+(n<<2)+20>>2]|0;if(!g){o=1;i=q;return o|0}l=c[g+52>>2]|0;m=Z(c[g+56>>2]|0,l)|0;h=c[f+12>>2]|0;a:do if(h>>>0>1){g=c[f+16>>2]|0;if((g|0)==2){k=c[f+24>>2]|0;j=c[f+28>>2]|0;h=h+-1|0;e=0;while(1){f=c[k+(e<<2)>>2]|0;g=c[j+(e<<2)>>2]|0;if(!(f>>>0<=g>>>0&g>>>0>>0)){e=1;g=33;break}e=e+1|0;if(((f>>>0)%(l>>>0)|0)>>>0>((g>>>0)%(l>>>0)|0)>>>0){e=1;g=33;break}if(e>>>0>=h>>>0)break a}if((g|0)==33){i=q;return e|0}}else if(!g){g=c[f+20>>2]|0;f=0;while(1){if((c[g+(f<<2)>>2]|0)>>>0>m>>>0){e=1;break}f=f+1|0;if(f>>>0>=h>>>0)break a}i=q;return e|0}else{if((g+-3|0)>>>0<3){if((c[f+36>>2]|0)>>>0>m>>>0)e=1;else break;i=q;return e|0}if((g|0)!=6)break;if((c[f+40>>2]|0)>>>0>>0)e=1;else break;i=q;return e|0}}while(0);f=a+4|0;g=c[f>>2]|0;do if((g|0)!=256){e=a+3380|0;if(!(c[e>>2]|0)){if((g|0)==(b|0))break;g=a+8|0;if((n|0)==(c[g>>2]|0)){c[f>>2]=b;c[a+12>>2]=c[o>>2];break}if(!d){o=1;i=q;return o|0}else{c[f>>2]=b;o=c[o>>2]|0;c[a+12>>2]=o;o=c[o+4>>2]|0;c[g>>2]=o;o=c[a+(o<<2)+20>>2]|0;c[a+16>>2]=o;n=c[o+52>>2]|0;o=c[o+56>>2]|0;c[a+1176>>2]=Z(o,n)|0;c[a+1340>>2]=n;c[a+1344>>2]=o;c[e>>2]=1;break}}c[e>>2]=0;e=a+1212|0;gd(c[e>>2]|0);c[e>>2]=0;f=a+1172|0;gd(c[f>>2]|0);c[f>>2]=0;g=a+1176|0;c[e>>2]=fd((c[g>>2]|0)*216|0)|0;o=fd(c[g>>2]<<2)|0;c[f>>2]=o;f=c[e>>2]|0;if((f|0)==0|(o|0)==0){o=65535;i=q;return o|0}id(f,0,(c[g>>2]|0)*216|0);f=a+16|0;tb(c[e>>2]|0,c[(c[f>>2]|0)+52>>2]|0,c[g>>2]|0);f=c[f>>2]|0;do if((c[a+1216>>2]|0)==0?(c[f+16>>2]|0)!=2:0){if(((c[f+80>>2]|0)!=0?(p=c[f+84>>2]|0,(c[p+920>>2]|0)!=0):0)?(c[p+944>>2]|0)==0:0){e=1;break}e=0}else e=1;while(0);o=Z(c[f+56>>2]|0,c[f+52>>2]|0)|0;e=lc(a+1220|0,o,c[f+88>>2]|0,c[f+44>>2]|0,c[f+12>>2]|0,e)|0;if(e){o=e;i=q;return o|0}}else{c[f>>2]=b;o=c[o>>2]|0;c[a+12>>2]=o;o=c[o+4>>2]|0;c[a+8>>2]=o;o=c[a+(o<<2)+20>>2]|0;c[a+16>>2]=o;n=c[o+52>>2]|0;o=c[o+56>>2]|0;c[a+1176>>2]=Z(o,n)|0;c[a+1340>>2]=n;c[a+1344>>2]=o;c[a+3380>>2]=1}while(0);o=0;i=q;return o|0}function Eb(a){a=a|0;var b=0,d=0,e=0;e=i;c[a+1196>>2]=0;c[a+1192>>2]=0;d=c[a+1176>>2]|0;if(!d){i=e;return}a=c[a+1212>>2]|0;b=0;do{c[a+(b*216|0)+4>>2]=0;c[a+(b*216|0)+196>>2]=0;b=b+1|0}while(b>>>0>>0);i=e;return}function Fb(a){a=a|0;return (c[a+1188>>2]|0)==0|0}function Gb(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;if(!(c[a+1404>>2]|0)){if((c[a+1196>>2]|0)==(c[a+1176>>2]|0)){a=1;i=f;return a|0}}else{e=c[a+1176>>2]|0;if(!e){a=1;i=f;return a|0}a=c[a+1212>>2]|0;b=0;d=0;do{d=((c[a+(b*216|0)+196>>2]|0)!=0&1)+d|0;b=b+1|0}while(b>>>0>>0);if((d|0)==(e|0)){a=1;i=f;return a|0}}a=0;i=f;return a|0}function Hb(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;e=c[a+16>>2]|0;Kb(c[a+1172>>2]|0,c[a+12>>2]|0,b,c[e+52>>2]|0,c[e+56>>2]|0);i=d;return}function Ib(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;i=i+32|0;g=t+24|0;j=t+20|0;k=t+16|0;n=t+12|0;r=t+8|0;q=t;c[e>>2]=0;switch(c[b>>2]|0){case 5:case 1:{s=d+1300|0;h=d+1332|0;if(c[h>>2]|0){c[e>>2]=1;c[h>>2]=0}h=Ua(a,g)|0;if(h){o=h;i=t;return o|0}l=c[d+(c[g>>2]<<2)+148>>2]|0;if(!l){o=65520;i=t;return o|0}h=c[l+4>>2]|0;m=c[d+(h<<2)+20>>2]|0;if(!m){o=65520;i=t;return o|0}g=c[d+8>>2]|0;if(!((g|0)==32|(h|0)==(g|0))?(c[b>>2]|0)!=5:0){o=65520;i=t;return o|0}g=c[d+1304>>2]|0;h=c[b+4>>2]|0;if((g|0)!=(h|0)?(g|0)==0|(h|0)==0:0)c[e>>2]=1;h=(c[b>>2]|0)==5;if((c[s>>2]|0)==5){if(!h)f=16}else if(h)f=16;if((f|0)==16)c[e>>2]=1;g=m+12|0;if(Va(a,c[g>>2]|0,j)|0){o=1;i=t;return o|0}f=d+1308|0;h=c[j>>2]|0;if((c[f>>2]|0)!=(h|0)){c[f>>2]=h;c[e>>2]=1}if((c[b>>2]|0)==5){if(Wa(a,c[g>>2]|0,5,k)|0){o=1;i=t;return o|0}if((c[s>>2]|0)==5){h=d+1312|0;f=c[h>>2]|0;g=c[k>>2]|0;if((f|0)==(g|0))g=f;else c[e>>2]=1}else{g=c[k>>2]|0;h=d+1312|0}c[h>>2]=g}g=c[m+16>>2]|0;if((g|0)==1){if(!(c[m+24>>2]|0)){h=l+8|0;g=Za(a,m,c[b>>2]|0,c[h>>2]|0,q)|0;if(g){o=g;i=t;return o|0}f=d+1324|0;g=c[q>>2]|0;if((c[f>>2]|0)!=(g|0)){c[f>>2]=g;c[e>>2]=1}if((c[h>>2]|0)!=0?(p=d+1328|0,o=c[q+4>>2]|0,(c[p>>2]|0)!=(o|0)):0){c[p>>2]=o;c[e>>2]=1}}}else if(!g){if(Xa(a,m,c[b>>2]|0,n)|0){o=1;i=t;return o|0}f=d+1316|0;g=c[n>>2]|0;if((c[f>>2]|0)!=(g|0)){c[f>>2]=g;c[e>>2]=1}if(c[l+8>>2]|0){f=Ya(a,m,c[b>>2]|0,r)|0;if(f){o=f;i=t;return o|0}g=d+1320|0;f=c[r>>2]|0;if((c[g>>2]|0)!=(f|0)){c[g>>2]=f;c[e>>2]=1}}}n=b;a=c[n+4>>2]|0;o=s;c[o>>2]=c[n>>2];c[o+4>>2]=a;o=0;i=t;return o|0}case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 16:case 17:case 18:{c[e>>2]=1;o=0;i=t;return o|0}default:{o=0;i=t;return o|0}}return 0}function Jb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;n=i;l=0;a:while(1){b=c[a+(l<<2)+148>>2]|0;b:do if((b|0)!=0?(k=c[a+(c[b+4>>2]<<2)+20>>2]|0,(k|0)!=0):0){j=c[k+52>>2]|0;m=Z(c[k+56>>2]|0,j)|0;f=c[b+12>>2]|0;if(f>>>0<=1){b=0;d=18;break a}d=c[b+16>>2]|0;if((d|0)==2){h=c[b+24>>2]|0;g=c[b+28>>2]|0;f=f+-1|0;e=0;while(1){b=c[h+(e<<2)>>2]|0;d=c[g+(e<<2)>>2]|0;if(!(b>>>0<=d>>>0&d>>>0>>0))break b;e=e+1|0;if(((b>>>0)%(j>>>0)|0)>>>0>((d>>>0)%(j>>>0)|0)>>>0)break b;if(e>>>0>=f>>>0){b=0;d=18;break a}}}else if(d){if((d+-3|0)>>>0<3)if((c[b+36>>2]|0)>>>0>m>>>0)break;else{b=0;d=18;break a}if((d|0)!=6){b=0;d=18;break a}if((c[b+40>>2]|0)>>>0>>0)break;else{b=0;d=18;break a}}else{d=c[b+20>>2]|0;b=0;while(1){if((c[d+(b<<2)>>2]|0)>>>0>m>>>0)break b;b=b+1|0;if(b>>>0>=f>>>0){b=0;d=18;break a}}}}while(0);l=l+1|0;if(l>>>0>=256){b=1;d=18;break}}if((d|0)==18){i=n;return b|0}return 0}function Kb(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,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;v=i;t=Z(f,e)|0;o=c[b+12>>2]|0;if((o|0)==1){id(a,0,t<<2);i=v;return}k=c[b+16>>2]|0;if((k+-3|0)>>>0<3){d=Z(c[b+36>>2]|0,d)|0;d=d>>>0>>0?d:t;if((k&-2|0)==4){n=(c[b+32>>2]|0)==0?d:t-d|0;u=d}else{n=0;u=d}}else{n=0;u=0}switch(k|0){case 0:{l=c[b+20>>2]|0;if(!t){i=v;return}else{h=0;j=0}while(1){while(1)if(h>>>0>>0)break;else h=0;b=l+(h<<2)|0;d=c[b>>2]|0;a:do if(!d)d=0;else{k=0;do{g=k+j|0;if(g>>>0>=t>>>0)break a;c[a+(g<<2)>>2]=h;k=k+1|0;d=c[b>>2]|0}while(k>>>0>>0)}while(0);j=d+j|0;if(j>>>0>=t>>>0)break;else h=h+1|0}i=v;return}case 4:{h=c[b+32>>2]|0;if(!t){i=v;return}d=1-h|0;g=0;do{c[a+(g<<2)>>2]=g>>>0>>0?h:d;g=g+1|0}while((g|0)!=(t|0));i=v;return}case 1:{if(!t){i=v;return}else h=0;do{c[a+(h<<2)>>2]=((((Z((h>>>0)/(e>>>0)|0,o)|0)>>>1)+((h>>>0)%(e>>>0)|0)|0)>>>0)%(o>>>0)|0;h=h+1|0}while((h|0)!=(t|0));i=v;return}case 2:{n=c[b+24>>2]|0;m=c[b+28>>2]|0;h=o+-1|0;if(t){d=0;do{c[a+(d<<2)>>2]=h;d=d+1|0}while((d|0)!=(t|0))}if(!h){i=v;return}g=o+-2|0;while(1){j=c[n+(g<<2)>>2]|0;d=(j>>>0)/(e>>>0)|0;j=(j>>>0)%(e>>>0)|0;h=c[m+(g<<2)>>2]|0;l=(h>>>0)/(e>>>0)|0;h=(h>>>0)%(e>>>0)|0;b:do if(d>>>0<=l>>>0){if(j>>>0>h>>>0)while(1){d=d+1|0;if(d>>>0>l>>>0)break b}do{k=Z(d,e)|0;b=j;do{c[a+(b+k<<2)>>2]=g;b=b+1|0}while(b>>>0<=h>>>0);d=d+1|0}while(d>>>0<=l>>>0)}while(0);if(!g)break;else g=g+-1|0}i=v;return}case 5:{d=c[b+32>>2]|0;if(!e){i=v;return}k=1-d|0;if(!f){i=v;return}else{g=0;j=0}while(1){h=0;b=j;while(1){m=a+((Z(h,e)|0)+g<<2)|0;c[m>>2]=b>>>0>>0?d:k;h=h+1|0;if((h|0)==(f|0))break;else b=b+1|0}g=g+1|0;if((g|0)==(e|0))break;else j=j+f|0}i=v;return}case 3:{m=c[b+32>>2]|0;if(t){d=0;do{c[a+(d<<2)>>2]=1;d=d+1|0}while((d|0)!=(t|0))}l=(e-m|0)>>>1;n=(f-m|0)>>>1;if(!u){i=v;return}t=m<<1;r=t+-1|0;s=e+-1|0;t=1-t|0;q=f+-1|0;o=n;p=0;g=l;f=l;k=n;b=l;j=m+-1|0;d=n;while(1){n=a+((Z(d,e)|0)+b<<2)|0;l=(c[n>>2]|0)==1;h=l&1;if(l)c[n>>2]=0;do if(!((j|0)==-1&(b|0)==(g|0))){if((j|0)==1&(b|0)==(f|0)){b=f+1|0;b=(b|0)<(s|0)?b:s;n=o;l=g;f=b;j=0;m=t;break}if((m|0)==-1&(d|0)==(k|0)){d=k+-1|0;d=(d|0)>0?d:0;n=o;l=g;k=d;j=t;m=0;break}if((m|0)==1&(d|0)==(o|0)){d=o+1|0;d=(d|0)<(q|0)?d:q;n=d;l=g;j=r;m=0;break}else{n=o;l=g;b=b+j|0;d=d+m|0;break}}else{b=g+-1|0;b=(b|0)>0?b:0;n=o;l=b;j=0;m=r}while(0);p=h+p|0;if(p>>>0>=u>>>0)break;else{o=n;g=l}}i=v;return}default:{if(!t){i=v;return}g=c[b+44>>2]|0;h=0;do{c[a+(h<<2)>>2]=c[g+(h<<2)>>2];h=h+1|0}while((h|0)!=(t|0));i=v;return}}}function Lb(){return 3472}function Mb(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,j=0,k=0;k=i;i=i+80|0;h=k+32|0;j=k;Nb(d,h,j,e);if((cb(c[a>>2]|0)|0)==1){e=Ob(a,g,b+328|0,h,j,f)|0;if(e){i=k;return e|0}}else{e=Pb(a,g,b,h,j,f)|0;if(e){i=k;return e|0}}e=Qb(a,g+256|0,b+1352|0,h+21|0,j+16|0,c[b+140>>2]|0,f)|0;if(e){i=k;return e|0}if((c[a+196>>2]|0)>>>0>1){e=0;i=k;return e|0}sc(d,g);e=0;i=k;return e|0}function Nb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=i;if(!f){i=s;return}p=c[b+4>>2]|0;q=Z(c[b+8>>2]|0,p)|0;n=(f>>>0)/(p>>>0)|0;g=Z(n,p)|0;o=f-g|0;k=p<<4;h=c[b>>2]|0;j=(o<<4)+(Z(p<<8,n)|0)|0;r=(n|0)!=0;if(r){m=j-(k|1)|0;a[d>>0]=a[h+m>>0]|0;a[d+1>>0]=a[h+(m+1)>>0]|0;a[d+2>>0]=a[h+(m+2)>>0]|0;a[d+3>>0]=a[h+(m+3)>>0]|0;a[d+4>>0]=a[h+(m+4)>>0]|0;a[d+5>>0]=a[h+(m+5)>>0]|0;a[d+6>>0]=a[h+(m+6)>>0]|0;a[d+7>>0]=a[h+(m+7)>>0]|0;a[d+8>>0]=a[h+(m+8)>>0]|0;a[d+9>>0]=a[h+(m+9)>>0]|0;a[d+10>>0]=a[h+(m+10)>>0]|0;a[d+11>>0]=a[h+(m+11)>>0]|0;a[d+12>>0]=a[h+(m+12)>>0]|0;a[d+13>>0]=a[h+(m+13)>>0]|0;a[d+14>>0]=a[h+(m+14)>>0]|0;a[d+15>>0]=a[h+(m+15)>>0]|0;a[d+16>>0]=a[h+(m+16)>>0]|0;a[d+17>>0]=a[h+(m+17)>>0]|0;a[d+18>>0]=a[h+(m+18)>>0]|0;a[d+19>>0]=a[h+(m+19)>>0]|0;a[d+20>>0]=a[h+(m+20)>>0]|0;m=d+21|0}else m=d;l=(g|0)!=(f|0);if(l){j=j+-1|0;a[e>>0]=a[h+j>>0]|0;j=j+k|0;a[e+1>>0]=a[h+j>>0]|0;j=j+k|0;a[e+2>>0]=a[h+j>>0]|0;j=j+k|0;a[e+3>>0]=a[h+j>>0]|0;j=j+k|0;a[e+4>>0]=a[h+j>>0]|0;j=j+k|0;a[e+5>>0]=a[h+j>>0]|0;j=j+k|0;a[e+6>>0]=a[h+j>>0]|0;j=j+k|0;a[e+7>>0]=a[h+j>>0]|0;j=j+k|0;a[e+8>>0]=a[h+j>>0]|0;j=j+k|0;a[e+9>>0]=a[h+j>>0]|0;j=j+k|0;a[e+10>>0]=a[h+j>>0]|0;j=j+k|0;a[e+11>>0]=a[h+j>>0]|0;j=j+k|0;a[e+12>>0]=a[h+j>>0]|0;j=j+k|0;a[e+13>>0]=a[h+j>>0]|0;j=j+k|0;a[e+14>>0]=a[h+j>>0]|0;a[e+15>>0]=a[h+(j+k)>>0]|0;e=e+16|0}d=p<<3&2147483640;f=c[b>>2]|0;g=(Z(n<<3,d)|0)+(q<<8)+(o<<3)|0;if(r){b=g-(d|1)|0;a[m>>0]=a[f+b>>0]|0;a[m+1>>0]=a[f+(b+1)>>0]|0;a[m+2>>0]=a[f+(b+2)>>0]|0;a[m+3>>0]=a[f+(b+3)>>0]|0;a[m+4>>0]=a[f+(b+4)>>0]|0;a[m+5>>0]=a[f+(b+5)>>0]|0;a[m+6>>0]=a[f+(b+6)>>0]|0;a[m+7>>0]=a[f+(b+7)>>0]|0;a[m+8>>0]=a[f+(b+8)>>0]|0;b=b+(q<<6)|0;a[m+9>>0]=a[f+b>>0]|0;a[m+10>>0]=a[f+(b+1)>>0]|0;a[m+11>>0]=a[f+(b+2)>>0]|0;a[m+12>>0]=a[f+(b+3)>>0]|0;a[m+13>>0]=a[f+(b+4)>>0]|0;a[m+14>>0]=a[f+(b+5)>>0]|0;a[m+15>>0]=a[f+(b+6)>>0]|0;a[m+16>>0]=a[f+(b+7)>>0]|0;a[m+17>>0]=a[f+(b+8)>>0]|0}if(!l){i=s;return}m=g+-1|0;a[e>>0]=a[f+m>>0]|0;m=m+d|0;a[e+1>>0]=a[f+m>>0]|0;m=m+d|0;a[e+2>>0]=a[f+m>>0]|0;m=m+d|0;a[e+3>>0]=a[f+m>>0]|0;m=m+d|0;a[e+4>>0]=a[f+m>>0]|0;m=m+d|0;a[e+5>>0]=a[f+m>>0]|0;m=m+d|0;a[e+6>>0]=a[f+m>>0]|0;m=m+d|0;a[e+7>>0]=a[f+m>>0]|0;m=m+(d+((q<<6)-(p<<6)))|0;a[e+8>>0]=a[f+m>>0]|0;m=m+d|0;a[e+9>>0]=a[f+m>>0]|0;m=m+d|0;a[e+10>>0]=a[f+m>>0]|0;m=m+d|0;a[e+11>>0]=a[f+m>>0]|0;m=m+d|0;a[e+12>>0]=a[f+m>>0]|0;m=m+d|0;a[e+13>>0]=a[f+m>>0]|0;m=m+d|0;a[e+14>>0]=a[f+m>>0]|0;a[e+15>>0]=a[f+(m+d)>>0]|0;i=s;return}function Ob(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var 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;z=i;k=b+200|0;l=zb(b,c[k>>2]|0)|0;o=(j|0)!=0;if((l|0)!=0&o){n=(cb(c[c[k>>2]>>2]|0)|0)==2;n=n?0:l}else n=l;j=b+204|0;l=zb(b,c[j>>2]|0)|0;if((l|0)!=0&o){p=(cb(c[c[j>>2]>>2]|0)|0)==2;p=p?0:l}else p=l;j=b+212|0;l=zb(b,c[j>>2]|0)|0;if((l|0)!=0&o){r=(cb(c[c[j>>2]>>2]|0)|0)==2;l=r?0:l}j=fb(c[b>>2]|0)|0;if(!j){if(!p){r=1;i=z;return r|0}b=g+1|0;m=g+2|0;s=g+3|0;t=g+4|0;u=g+5|0;v=g+6|0;w=g+7|0;x=g+8|0;y=g+9|0;h=g+10|0;l=g+11|0;j=g+12|0;k=g+13|0;q=g+14|0;r=g+15|0;p=g+16|0;o=e;n=0;while(1){a[o>>0]=a[b>>0]|0;a[o+1>>0]=a[m>>0]|0;a[o+2>>0]=a[s>>0]|0;a[o+3>>0]=a[t>>0]|0;a[o+4>>0]=a[u>>0]|0;a[o+5>>0]=a[v>>0]|0;a[o+6>>0]=a[w>>0]|0;a[o+7>>0]=a[x>>0]|0;a[o+8>>0]=a[y>>0]|0;a[o+9>>0]=a[h>>0]|0;a[o+10>>0]=a[l>>0]|0;a[o+11>>0]=a[j>>0]|0;a[o+12>>0]=a[k>>0]|0;a[o+13>>0]=a[q>>0]|0;a[o+14>>0]=a[r>>0]|0;a[o+15>>0]=a[p>>0]|0;n=n+1|0;if((n|0)==16)break;else o=o+16|0}}else if((j|0)==2){l=g+1|0;k=(n|0)!=0;j=(p|0)!=0;do if(!(k&j)){if(k){k=((d[h>>0]|0)+8+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)+(d[h+4>>0]|0)+(d[h+5>>0]|0)+(d[h+6>>0]|0)+(d[h+7>>0]|0)+(d[h+8>>0]|0)+(d[h+9>>0]|0)+(d[h+10>>0]|0)+(d[h+11>>0]|0)+(d[h+12>>0]|0)+(d[h+13>>0]|0)+(d[h+14>>0]|0)+(d[h+15>>0]|0)|0)>>>4;break}if(j)k=((d[l>>0]|0)+8+(d[g+2>>0]|0)+(d[g+3>>0]|0)+(d[g+4>>0]|0)+(d[g+5>>0]|0)+(d[g+6>>0]|0)+(d[g+7>>0]|0)+(d[g+8>>0]|0)+(d[g+9>>0]|0)+(d[g+10>>0]|0)+(d[g+11>>0]|0)+(d[g+12>>0]|0)+(d[g+13>>0]|0)+(d[g+14>>0]|0)+(d[g+15>>0]|0)+(d[g+16>>0]|0)|0)>>>4;else k=128}else{j=0;k=0;do{r=j;j=j+1|0;k=(d[g+j>>0]|0)+k+(d[h+r>>0]|0)|0}while((j|0)!=16);k=(k+16|0)>>>5}while(0);nd(e|0,k&255|0,256)|0}else if((j|0)==1)if(!n){r=1;i=z;return r|0}else{k=e;j=0;while(1){r=h+j|0;a[k>>0]=a[r>>0]|0;a[k+1>>0]=a[r>>0]|0;a[k+2>>0]=a[r>>0]|0;a[k+3>>0]=a[r>>0]|0;a[k+4>>0]=a[r>>0]|0;a[k+5>>0]=a[r>>0]|0;a[k+6>>0]=a[r>>0]|0;a[k+7>>0]=a[r>>0]|0;a[k+8>>0]=a[r>>0]|0;a[k+9>>0]=a[r>>0]|0;a[k+10>>0]=a[r>>0]|0;a[k+11>>0]=a[r>>0]|0;a[k+12>>0]=a[r>>0]|0;a[k+13>>0]=a[r>>0]|0;a[k+14>>0]=a[r>>0]|0;a[k+15>>0]=a[r>>0]|0;j=j+1|0;if((j|0)==16)break;else k=k+16|0}}else{if(!((n|0)!=0&(p|0)!=0&(l|0)!=0)){r=1;i=z;return r|0}j=d[g+16>>0]|0;m=d[h+15>>0]|0;o=d[g>>0]|0;p=(((d[g+9>>0]|0)-(d[g+7>>0]|0)+((d[g+10>>0]|0)-(d[g+6>>0]|0)<<1)+(((d[g+11>>0]|0)-(d[g+5>>0]|0)|0)*3|0)+((d[g+12>>0]|0)-(d[g+4>>0]|0)<<2)+(((d[g+13>>0]|0)-(d[g+3>>0]|0)|0)*5|0)+(((d[g+14>>0]|0)-(d[g+2>>0]|0)|0)*6|0)+(((d[g+15>>0]|0)-(d[g+1>>0]|0)|0)*7|0)+(j-o<<3)|0)*5|0)+32>>6;o=(((d[h+8>>0]|0)-(d[h+6>>0]|0)+(m-o<<3)+((d[h+9>>0]|0)-(d[h+5>>0]|0)<<1)+(((d[h+10>>0]|0)-(d[h+4>>0]|0)|0)*3|0)+((d[h+11>>0]|0)-(d[h+3>>0]|0)<<2)+(((d[h+12>>0]|0)-(d[h+2>>0]|0)|0)*5|0)+(((d[h+13>>0]|0)-(d[h+1>>0]|0)|0)*6|0)+(((d[h+14>>0]|0)-(d[h>>0]|0)|0)*7|0)|0)*5|0)+32>>6;j=(m+j<<4)+16|0;m=0;do{k=j+(Z(m+-7|0,o)|0)|0;n=m<<4;b=0;do{l=k+(Z(b+-7|0,p)|0)>>5;if((l|0)<0)l=0;else l=(l|0)>255?-1:l&255;a[e+(b+n)>>0]=l;b=b+1|0}while((b|0)!=16);m=m+1|0}while((m|0)!=16)}Rb(e,f,0);Rb(e,f+64|0,1);Rb(e,f+128|0,2);Rb(e,f+192|0,3);Rb(e,f+256|0,4);Rb(e,f+320|0,5);Rb(e,f+384|0,6);Rb(e,f+448|0,7);Rb(e,f+512|0,8);Rb(e,f+576|0,9);Rb(e,f+640|0,10);Rb(e,f+704|0,11);Rb(e,f+768|0,12);Rb(e,f+832|0,13);Rb(e,f+896|0,14);Rb(e,f+960|0,15);r=0;i=z;return r|0}function Pb(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var 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,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0;N=i;M=(j|0)!=0;L=0;a:while(1){l=vb(L)|0;n=c[l+4>>2]|0;l=ub(b,c[l>>2]|0)|0;j=zb(b,l)|0;if((j|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;j=E?0:j}o=wb(L)|0;m=c[o+4>>2]|0;o=ub(b,c[o>>2]|0)|0;k=zb(b,o)|0;if((k|0)!=0&M){E=(cb(c[o>>2]|0)|0)==2;k=E?0:k}G=(j|0)!=0;H=(k|0)!=0;I=G&H;if(I){if(!(cb(c[l>>2]|0)|0))n=d[l+(n&255)+82>>0]|0;else n=2;if(!(cb(c[o>>2]|0)|0))j=d[o+(m&255)+82>>0]|0;else j=2;j=n>>>0>>0?n:j}else j=2;if(!(c[f+(L<<2)+12>>2]|0)){E=c[f+(L<<2)+76>>2]|0;j=(E>>>0>=j>>>0&1)+E|0}a[b+L+82>>0]=j;l=c[(xb(L)|0)>>2]|0;l=ub(b,l)|0;m=zb(b,l)|0;if((m|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;m=E?0:m}l=c[(yb(L)|0)>>2]|0;l=ub(b,l)|0;n=zb(b,l)|0;if((n|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;n=E?0:n}J=c[3344+(L<<2)>>2]|0;K=c[3408+(L<<2)>>2]|0;r=(1285>>>L&1|0)!=0;if(r){o=h+K|0;l=h+(K+1)|0;p=h+(K+2)|0;q=h+(K+3)|0}else{q=(K<<4)+J|0;o=e+(q+-1)|0;l=e+(q+15)|0;p=e+(q+31)|0;q=e+(q+47)|0}A=a[o>>0]|0;y=a[l>>0]|0;F=a[p>>0]|0;E=a[q>>0]|0;do if(!(51>>>L&1)){x=K+-1|0;w=(x<<4)+J|0;o=a[e+w>>0]|0;q=a[e+(w+1)>>0]|0;s=a[e+(w+2)>>0]|0;u=a[e+(w+3)>>0]|0;t=a[e+(w+4)>>0]|0;l=a[e+(w+5)>>0]|0;v=a[e+(w+6)>>0]|0;p=a[e+(w+7)>>0]|0;if(r){D=v;C=u;u=p;B=q;z=s;v=h+x|0;break}else{D=v;C=u;u=p;B=q;z=s;v=e+(w+-1)|0;break}}else{D=a[g+(J+7)>>0]|0;C=a[g+(J+4)>>0]|0;t=a[g+(J+5)>>0]|0;l=a[g+(J+6)>>0]|0;o=a[g+(J+1)>>0]|0;u=a[g+(J+8)>>0]|0;B=a[g+(J+2)>>0]|0;z=a[g+(J+3)>>0]|0;v=g+J|0}while(0);v=a[v>>0]|0;switch(j|0){case 4:{if(!(I&(n|0)!=0)){k=1;j=51;break a}j=o&255;o=v&255;q=A&255;s=j+2|0;D=(s+q+(o<<1)|0)>>>2;u=D&255;k=B&255;o=o+2|0;v=((j<<1)+k+o|0)>>>2&255;j=z&255;s=((k<<1)+j+s|0)>>>2&255;z=y&255;o=(z+(q<<1)+o|0)>>>2;t=o&255;A=F&255;B=(q+2+(z<<1)+A|0)>>>2;q=u;p=t;n=B&255;m=v;l=s;j=((C&255)+2+k+(j<<1)|0)>>>2&255;k=u;r=v;o=(z+2+(A<<1)+(E&255)|0)>>>2&255|B<<8&65280|D<<24|o<<16&16711680;break}case 6:{if(!(I&(n|0)!=0)){k=1;j=51;break a}l=v&255;s=A&255;u=s+1|0;r=(u+l|0)>>>1&255;C=y&255;v=((s<<1)+2+C+l|0)>>>2&255;u=(u+C|0)>>>1&255;D=F&255;s=s+2|0;y=(s+(C<<1)+D|0)>>>2;A=(C+1+D|0)>>>1;E=E&255;j=o&255;s=(s+j+(l<<1)|0)>>>2&255;k=B&255;q=r;p=u;n=A&255;m=s;l=(k+2+(j<<1)+l|0)>>>2&255;j=((z&255)+2+(k<<1)+j|0)>>>2&255;k=v;t=y&255;o=y<<24|A<<16&16711680|(D+1+E|0)>>>1&255|C+2+(D<<1)+E<<6&65280;break}case 2:{do if(!I){if(G){j=((A&255)+2+(y&255)+(F&255)+(E&255)|0)>>>2;break}if(H)j=((C&255)+2+(z&255)+(B&255)+(o&255)|0)>>>2;else j=128}else j=((A&255)+4+(y&255)+(F&255)+(E&255)+(C&255)+(z&255)+(B&255)+(o&255)|0)>>>3;while(0);o=Z(j&255,16843009)|0;n=o&255;t=o>>>8&255;u=o>>>16&255;v=o>>>24&255;q=n;p=n;m=t;l=u;j=v;k=t;r=u;s=v;break}case 0:{if(!k){k=1;j=51;break a}q=o;p=o;n=o;m=B;l=z;j=C;k=B;r=z;s=C;t=B;u=z;v=C;o=(z&255)<<16|(C&255)<<24|(B&255)<<8|o&255;break}case 1:{if(!G){k=1;j=51;break a}j=Z(A&255,16843009)|0;s=Z(y&255,16843009)|0;v=Z(F&255,16843009)|0;q=j&255;p=s&255;n=v&255;m=j>>>8&255;l=j>>>16&255;j=j>>>24&255;k=s>>>8&255;r=s>>>16&255;s=s>>>24&255;t=v>>>8&255;u=v>>>16&255;v=v>>>24&255;o=Z(E&255,16843009)|0;break}case 7:{if(!k){k=1;j=51;break a}A=(m|0)==0;n=o&255;p=B&255;z=z&255;m=(z+1+p|0)>>>1&255;o=C&255;u=o+1|0;v=(u+z|0)>>>1&255;B=(A?C:t)&255;u=(u+B|0)>>>1&255;j=z+2|0;y=o+2|0;z=(y+p+(z<<1)|0)>>>2;o=(j+(o<<1)+B|0)>>>2;E=(A?C:l)&255;y=(y+E+(B<<1)|0)>>>2;q=(p+1+n|0)>>>1&255;p=(j+n+(p<<1)|0)>>>2&255;n=m;l=v;j=u;k=z&255;r=o&255;s=y&255;t=v;v=(B+1+E|0)>>>1&255;o=y<<16&16711680|z&255|(B+2+((A?C:D)&255)+(E<<1)|0)>>>2<<24|o<<8&65280;break}case 3:{if(!k){k=1;j=51;break a}n=(m|0)==0;q=B&255;m=z&255;p=m+2|0;k=C&255;B=k+2|0;m=(B+q+(m<<1)|0)>>>2&255;v=(n?C:t)&255;k=(p+(k<<1)+v|0)>>>2&255;E=(n?C:l)&255;B=(B+E+(v<<1)|0)>>>2;t=B&255;A=(n?C:D)&255;D=(v+2+A+(E<<1)|0)>>>2;v=D&255;C=(n?C:u)&255;E=(E+2+C+(A<<1)|0)>>>2;q=(p+(o&255)+(q<<1)|0)>>>2&255;p=m;n=k;l=k;j=t;r=t;s=v;u=v;v=E&255;o=(A+2+(C*3|0)|0)>>>2<<24|B&255|D<<8&65280|E<<16&16711680;break}case 5:{if(!(I&(n|0)!=0)){k=1;j=51;break a}n=v&255;u=o&255;t=(u+1+n|0)>>>1&255;x=B&255;E=(x+2+(u<<1)+n|0)>>>2;B=A&255;A=u+2|0;o=(A+B+(n<<1)|0)>>>2;u=(x+1+u|0)>>>1&255;s=z&255;A=((x<<1)+s+A|0)>>>2;v=(s+1+x|0)>>>1&255;C=C&255;D=y&255;q=t;p=o&255;n=(D+2+(B<<1)+n|0)>>>2&255;m=u;l=v;j=(C+1+s|0)>>>1&255;k=E&255;r=A&255;s=(C+2+x+(s<<1)|0)>>>2&255;o=A<<24|(B+2+(F&255)+(D<<1)|0)>>>2&255|E<<16&16711680|o<<8&65280;break}default:{if(!G){k=1;j=51;break a}s=A&255;j=y&255;m=F&255;l=(j+1+m|0)>>>1&255;o=E&255;k=(j+2+(m<<1)+o|0)>>>2&255;r=(m+1+o|0)>>>1&255;t=(m+2+(o*3|0)|0)>>>2&255;q=(s+1+j|0)>>>1&255;p=l;n=r;m=(s+2+(j<<1)+m|0)>>>2&255;j=k;s=t;u=E;v=E;o=o<<8|o|o<<16|o<<24}}E=(K<<4)+J|0;c[e+E>>2]=(l&255)<<16|(j&255)<<24|(m&255)<<8|q&255;c[e+(E+16)>>2]=(r&255)<<16|(s&255)<<24|(k&255)<<8|p&255;c[e+(E+32)>>2]=(u&255)<<16|(v&255)<<24|(t&255)<<8|n&255;c[e+(E+48)>>2]=o;Rb(e,f+(L<<6)+328|0,L);L=L+1|0;if(L>>>0>=16){k=0;j=51;break}}if((j|0)==51){i=N;return k|0}return 0}function Qb(b,e,f,g,h,j,k){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var 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;y=i;m=b+200|0;l=zb(b,c[m>>2]|0)|0;n=(k|0)!=0;if((l|0)!=0&n){o=(cb(c[c[m>>2]>>2]|0)|0)==2;l=o?0:l}m=b+204|0;k=zb(b,c[m>>2]|0)|0;if((k|0)!=0&n){o=(cb(c[c[m>>2]>>2]|0)|0)==2;o=o?0:k}else o=k;m=b+212|0;k=zb(b,c[m>>2]|0)|0;if((k|0)!=0&n){n=(cb(c[c[m>>2]>>2]|0)|0)==2;k=n?0:k}w=(l|0)!=0;x=(o|0)!=0;v=w&x;u=v&(k|0)!=0;t=(l|0)==0;s=(o|0)==0;p=g;q=16;r=0;while(1){if((j|0)==1){if(t){l=1;k=29;break}else{n=e;b=8;m=h}while(1){b=b+-1|0;a[n>>0]=a[m>>0]|0;a[n+1>>0]=a[m>>0]|0;a[n+2>>0]=a[m>>0]|0;a[n+3>>0]=a[m>>0]|0;a[n+4>>0]=a[m>>0]|0;a[n+5>>0]=a[m>>0]|0;a[n+6>>0]=a[m>>0]|0;a[n+7>>0]=a[m>>0]|0;if(!b)break;else{n=n+8|0;m=m+1|0}}}else if((j|0)==2){if(s){l=1;k=29;break}else{n=p;b=e;m=8}while(1){n=n+1|0;m=m+-1|0;a[b>>0]=a[n>>0]|0;a[b+8>>0]=a[n>>0]|0;a[b+16>>0]=a[n>>0]|0;a[b+24>>0]=a[n>>0]|0;a[b+32>>0]=a[n>>0]|0;a[b+40>>0]=a[n>>0]|0;a[b+48>>0]=a[n>>0]|0;a[b+56>>0]=a[n>>0]|0;if(!m)break;else b=b+1|0}}else if(!j){m=p+1|0;do if(!v){if(x){n=((d[m>>0]|0)+2+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)|0)>>>2;b=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2;break}if(w){b=((d[h>>0]|0)+2+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)|0)>>>2;n=b}else{n=128;b=128}}else{n=((d[m>>0]|0)+4+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)+(d[h>>0]|0)+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)|0)>>>3;b=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2}while(0);n=n&255;o=b&255;nd(e|0,n|0,4)|0;nd(e+4|0,o|0,4)|0;nd(e+8|0,n|0,4)|0;nd(e+12|0,o|0,4)|0;nd(e+16|0,n|0,4)|0;nd(e+20|0,o|0,4)|0;g=e+32|0;nd(e+24|0,n|0,4)|0;nd(e+28|0,o|0,4)|0;if(w){o=d[h+4>>0]|0;n=d[h+5>>0]|0;b=d[h+6>>0]|0;m=d[h+7>>0]|0;k=(o+2+n+b+m|0)>>>2;if(x){l=k;n=(o+4+n+b+m+(d[p+5>>0]|0)+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>3}else{l=k;n=k}}else if(x){l=((d[m>>0]|0)+2+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)|0)>>>2;n=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2}else{l=128;n=128}b=l&255;o=n&255;nd(g|0,b|0,4)|0;nd(e+36|0,o|0,4)|0;nd(e+40|0,b|0,4)|0;nd(e+44|0,o|0,4)|0;nd(e+48|0,b|0,4)|0;nd(e+52|0,o|0,4)|0;nd(e+56|0,b|0,4)|0;nd(e+60|0,o|0,4)|0}else{if(!u){l=1;k=29;break}n=d[p+8>>0]|0;b=d[h+7>>0]|0;l=d[p>>0]|0;k=(((d[p+5>>0]|0)-(d[p+3>>0]|0)+((d[p+6>>0]|0)-(d[p+2>>0]|0)<<1)+(((d[p+7>>0]|0)-(d[p+1>>0]|0)|0)*3|0)+(n-l<<2)|0)*17|0)+16>>5;l=(((d[h+4>>0]|0)-(d[h+2>>0]|0)+(b-l<<2)+((d[h+5>>0]|0)-(d[h+1>>0]|0)<<1)+(((d[h+6>>0]|0)-(d[h>>0]|0)|0)*3|0)|0)*17|0)+16>>5;o=Z(k,-3)|0;n=(b+n<<4)+16+(Z(l,-3)|0)|0;b=e;m=8;while(1){m=m+-1|0;g=n+o|0;a[b>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+1>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+2>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+3>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+4>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+5>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+6>>0]=a[(g>>5)+3984>>0]|0;a[b+7>>0]=a[(g+k>>5)+3984>>0]|0;if(!m)break;else{n=n+l|0;b=b+8|0}}}Rb(e,f,q);g=q|1;Rb(e,f+64|0,g);Rb(e,f+128|0,g+1|0);Rb(e,f+192|0,q|3);r=r+1|0;if(r>>>0>=2){l=0;k=29;break}else{p=p+9|0;q=q+4|0;e=e+64|0;h=h+8|0;f=f+256|0}}if((k|0)==29){i=y;return l|0}return 0}function Rb(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;h=i;g=c[e>>2]|0;if((g|0)==16777215){i=h;return}m=f>>>0<16;l=m?16:8;m=m?f:f&3;m=(Z(c[3408+(m<<2)>>2]|0,l)|0)+(c[3344+(m<<2)>>2]|0)|0;n=b+m|0;p=c[e+4>>2]|0;j=b+(m+1)|0;f=d[j>>0]|0;a[n>>0]=a[3472+(g+512+(d[n>>0]|0))>>0]|0;n=c[e+8>>2]|0;k=b+(m+2)|0;o=d[k>>0]|0;a[j>>0]=a[3472+(p+512+f)>>0]|0;g=b+(m+3)|0;j=a[3472+((c[e+12>>2]|0)+512+(d[g>>0]|0))>>0]|0;a[k>>0]=a[3472+(n+512+o)>>0]|0;a[g>>0]=j;g=m+l|0;m=b+g|0;j=c[e+20>>2]|0;k=b+(g+1)|0;o=d[k>>0]|0;a[m>>0]=a[3472+((c[e+16>>2]|0)+512+(d[m>>0]|0))>>0]|0;m=c[e+24>>2]|0;n=b+(g+2)|0;f=d[n>>0]|0;a[k>>0]=a[3472+(j+512+o)>>0]|0;k=b+(g+3)|0;o=a[3472+((c[e+28>>2]|0)+512+(d[k>>0]|0))>>0]|0;a[n>>0]=a[3472+(m+512+f)>>0]|0;a[k>>0]=o;g=g+l|0;k=b+g|0;o=c[e+36>>2]|0;n=b+(g+1)|0;f=d[n>>0]|0;a[k>>0]=a[3472+((c[e+32>>2]|0)+512+(d[k>>0]|0))>>0]|0;k=c[e+40>>2]|0;m=b+(g+2)|0;j=d[m>>0]|0;a[n>>0]=a[3472+(o+512+f)>>0]|0;n=b+(g+3)|0;f=a[3472+((c[e+44>>2]|0)+512+(d[n>>0]|0))>>0]|0;a[m>>0]=a[3472+(k+512+j)>>0]|0;a[n>>0]=f;g=g+l|0;l=b+g|0;n=c[e+52>>2]|0;f=b+(g+1)|0;m=d[f>>0]|0;a[l>>0]=a[3472+((c[e+48>>2]|0)+512+(d[l>>0]|0))>>0]|0;l=c[e+56>>2]|0;j=b+(g+2)|0;k=d[j>>0]|0;a[f>>0]=a[3472+(n+512+m)>>0]|0;g=b+(g+3)|0;f=a[3472+((c[e+60>>2]|0)+512+(d[g>>0]|0))>>0]|0;a[j>>0]=a[3472+(l+512+k)>>0]|0;a[g>>0]=f;i=h;return} +function yc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;q=i;l=b+-1|0;k=a[b+1>>0]|0;m=d[l>>0]|0;n=d[b>>0]|0;r=m-n|0;p=f+4|0;do if((((r|0)>-1?r:0-r|0)>>>0<(c[p>>2]|0)>>>0?(o=d[b+-2>>0]|0,r=o-m|0,j=c[f+8>>2]|0,((r|0)>-1?r:0-r|0)>>>0>>0):0)?(h=k&255,k=h-n|0,((k|0)>-1?k:0-k|0)>>>0>>0):0)if(e>>>0<4){k=d[(c[f>>2]|0)+(e+-1)>>0]|0;k=Oa(~k,k+1|0,4-h+(n-m<<2)+o>>3)|0;o=a[3472+((n|512)-k)>>0]|0;a[l>>0]=a[3472+((m|512)+k)>>0]|0;a[b>>0]=o;break}else{a[l>>0]=(m+2+h+(o<<1)|0)>>>2;a[b>>0]=(n+2+(h<<1)+o|0)>>>2;break}while(0);l=b+g|0;m=b+(g+-1)|0;o=d[m>>0]|0;n=d[l>>0]|0;k=o-n|0;if(((k|0)>-1?k:0-k|0)>>>0>=(c[p>>2]|0)>>>0){i=q;return}k=d[b+(g+-2)>>0]|0;p=k-o|0;j=c[f+8>>2]|0;if(((p|0)>-1?p:0-p|0)>>>0>=j>>>0){i=q;return}h=d[b+(g+1)>>0]|0;g=h-n|0;if(((g|0)>-1?g:0-g|0)>>>0>=j>>>0){i=q;return}if(e>>>0<4){b=d[(c[f>>2]|0)+(e+-1)>>0]|0;b=Oa(~b,b+1|0,4-h+(n-o<<2)+k>>3)|0;g=a[3472+((n|512)-b)>>0]|0;a[m>>0]=a[3472+((o|512)+b)>>0]|0;a[l>>0]=g;i=q;return}else{a[m>>0]=(o+2+h+(k<<1)|0)>>>2;a[l>>0]=(n+2+(h<<1)+k|0)>>>2;i=q;return}}function zc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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;v=i;if(e>>>0<4){n=d[(c[f>>2]|0)+(e+-1)>>0]|0;h=n+1|0;q=0-g|0;e=f+4|0;p=q<<1;o=f+8|0;n=~n;j=8;while(1){m=b+q|0;f=a[b+g>>0]|0;l=d[m>>0]|0;k=d[b>>0]|0;r=l-k|0;if((((r|0)>-1?r:0-r|0)>>>0<(c[e>>2]|0)>>>0?(t=d[b+p>>0]|0,r=t-l|0,s=c[o>>2]|0,((r|0)>-1?r:0-r|0)>>>0>>0):0)?(u=f&255,f=u-k|0,((f|0)>-1?f:0-f|0)>>>0>>0):0){r=Oa(n,h,4-u+(k-l<<2)+t>>3)|0;f=a[3472+((k|512)-r)>>0]|0;a[m>>0]=a[3472+((l|512)+r)>>0]|0;a[b>>0]=f}j=j+-1|0;if(!j)break;else b=b+1|0}i=v;return}else{o=0-g|0;m=f+4|0;n=o<<1;f=f+8|0;l=8;while(1){h=b+o|0;e=a[b+g>>0]|0;j=d[h>>0]|0;k=d[b>>0]|0;s=j-k|0;if((((s|0)>-1?s:0-s|0)>>>0<(c[m>>2]|0)>>>0?(p=d[b+n>>0]|0,s=p-j|0,q=c[f>>2]|0,((s|0)>-1?s:0-s|0)>>>0>>0):0)?(r=e&255,e=r-k|0,((e|0)>-1?e:0-e|0)>>>0>>0):0){a[h>>0]=(j+2+r+(p<<1)|0)>>>2;a[b>>0]=(k+2+(r<<1)+p|0)>>>2}l=l+-1|0;if(!l)break;else b=b+1|0}i=v;return}}function Ac(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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=i;r=d[(c[f>>2]|0)+(e+-1)>>0]|0;s=r+1|0;l=0-g|0;h=f+4|0;q=l<<1;e=f+8|0;r=~r;l=b+l|0;m=a[b+g>>0]|0;k=d[l>>0]|0;j=d[b>>0]|0;u=k-j|0;f=c[h>>2]|0;if((((u|0)>-1?u:0-u|0)>>>0>>0?(o=d[b+q>>0]|0,u=o-k|0,n=c[e>>2]|0,((u|0)>-1?u:0-u|0)>>>0>>0):0)?(p=m&255,m=p-j|0,((m|0)>-1?m:0-m|0)>>>0>>0):0){p=Oa(r,s,4-p+(j-k<<2)+o>>3)|0;f=a[3472+((j|512)-p)>>0]|0;a[l>>0]=a[3472+((k|512)+p)>>0]|0;a[b>>0]=f;f=c[h>>2]|0}m=b+1|0;j=b+(1-g)|0;k=d[j>>0]|0;l=d[m>>0]|0;p=k-l|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}h=d[b+(q|1)>>0]|0;p=h-k|0;f=c[e>>2]|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}e=d[b+(g+1)>>0]|0;p=e-l|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}o=Oa(r,s,4-e+(l-k<<2)+h>>3)|0;p=a[3472+((l|512)-o)>>0]|0;a[j>>0]=a[3472+((k|512)+o)>>0]|0;a[m>>0]=p;i=t;return}function Bc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;p=c[b+4>>2]|0;q=c[b+8>>2]|0;if(!((d|0)==0|(d|0)==5)?(c[a+3384>>2]|0)==0:0)f=0;else{g=a+1220|0;e=0;do{f=ic(g,e)|0;e=e+1|0}while(e>>>0<16&(f|0)==0)}l=a+1176|0;n=c[l>>2]|0;if(n){m=c[a+1212>>2]|0;e=0;j=0;g=0;do{if(c[m+(j*216|0)+196>>2]|0)break;j=j+1|0;e=e+1|0;o=(e|0)==(p|0);g=(o&1)+g|0;e=o?0:e}while(j>>>0>>0);if((j|0)!=(n|0)){o=a+1212|0;n=c[o>>2]|0;j=Z(g,p)|0;if(e){l=a+1204|0;h=e;do{h=h+-1|0;m=h+j|0;Cc(n+(m*216|0)|0,b,g,h,d,f);c[n+(m*216|0)+196>>2]=1;c[l>>2]=(c[l>>2]|0)+1}while((h|0)!=0)}e=e+1|0;if(e>>>0

>>0){m=a+1204|0;do{l=e+j|0;k=n+(l*216|0)+196|0;if(!(c[k>>2]|0)){Cc(n+(l*216|0)|0,b,g,e,d,f);c[k>>2]=1;c[m>>2]=(c[m>>2]|0)+1}e=e+1|0}while((e|0)!=(p|0))}if(g){if(p){n=g+-1|0;h=Z(n,p)|0;e=a+1204|0;l=0-p|0;k=0;do{m=n;j=(c[o>>2]|0)+((k+h|0)*216|0)|0;while(1){Cc(j,b,m,k,d,f);c[j+196>>2]=1;c[e>>2]=(c[e>>2]|0)+1;if(!m)break;else{m=m+-1|0;j=j+(l*216|0)|0}}k=k+1|0}while((k|0)!=(p|0))}}else g=0;g=g+1|0;if(g>>>0>=q>>>0){i=r;return 0}m=a+1204|0;if(!p){i=r;return 0}do{e=c[o>>2]|0;l=Z(g,p)|0;k=0;do{h=k+l|0;j=e+(h*216|0)+196|0;if(!(c[j>>2]|0)){Cc(e+(h*216|0)|0,b,g,k,d,f);c[j>>2]=1;c[m>>2]=(c[m>>2]|0)+1}k=k+1|0}while((k|0)!=(p|0));g=g+1|0}while((g|0)!=(q|0));i=r;return 0}}if((d|0)==2|(d|0)==7)if((c[a+3384>>2]|0)==0|(f|0)==0)g=13;else g=14;else if(!f)g=13;else g=14;if((g|0)==13)id(c[b>>2]|0,128,Z(p*384|0,q)|0);else if((g|0)==14)hd(c[b>>2]|0,f,Z(p*384|0,q)|0);g=c[l>>2]|0;c[a+1204>>2]=g;if(!g){i=r;return 0}e=c[a+1212>>2]|0;f=0;do{c[e+(f*216|0)+8>>2]=1;f=f+1|0}while(f>>>0>>0);i=r;return 0}function Cc(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var 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,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,_=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;sa=i;i=i+480|0;qa=sa+96|0;ra=sa+32|0;m=sa+24|0;n=sa;na=c[e+4>>2]|0;u=c[e+8>>2]|0;Na(e,(Z(na,f)|0)+g|0);p=c[e>>2]|0;k=f<<4;l=g<<4;o=(Z(f<<8,na)|0)+l|0;c[b+20>>2]=40;c[b+8>>2]=0;c[b>>2]=6;c[b+12>>2]=0;c[b+16>>2]=0;c[b+24>>2]=0;do if((h|0)==2|(h|0)==7)id(qa,0,384);else{c[m>>2]=0;c[n+4>>2]=na;c[n+8>>2]=u;c[n>>2]=j;if(!j){id(qa,0,384);break}dc(qa,m,n,l,k,0,0,16,16);sc(e,qa);i=sa;return}while(0);id(ra,0,64);if((f|0)!=0?(c[b+((0-na|0)*216|0)+196>>2]|0)!=0:0){v=o-(na<<4)|0;E=v|1;D=v|3;E=(d[p+E>>0]|0)+(d[p+v>>0]|0)+(d[p+(E+1)>>0]|0)+(d[p+D>>0]|0)|0;$=v|7;D=(d[p+(D+2)>>0]|0)+(d[p+(D+1)>>0]|0)+(d[p+(D+3)>>0]|0)+(d[p+$>>0]|0)|0;F=(d[p+($+2)>>0]|0)+(d[p+($+1)>>0]|0)+(d[p+($+3)>>0]|0)+(d[p+($+4)>>0]|0)|0;v=(d[p+($+6)>>0]|0)+(d[p+($+5)>>0]|0)+(d[p+($+7)>>0]|0)+(d[p+(v|15)>>0]|0)|0;$=D+E|0;c[ra>>2]=F+$+(c[ra>>2]|0)+v;s=ra+4|0;c[s>>2]=$-F-v+(c[s>>2]|0);s=1}else{E=0;D=0;F=0;v=0;s=0}if((u+-1|0)!=(f|0)?(c[b+(na*216|0)+196>>2]|0)!=0:0){z=o+(na<<8)|0;w=z|1;x=z|3;w=(d[p+w>>0]|0)+(d[p+z>>0]|0)+(d[p+(w+1)>>0]|0)+(d[p+x>>0]|0)|0;r=z|7;x=(d[p+(x+2)>>0]|0)+(d[p+(x+1)>>0]|0)+(d[p+(x+3)>>0]|0)+(d[p+r>>0]|0)|0;y=(d[p+(r+2)>>0]|0)+(d[p+(r+1)>>0]|0)+(d[p+(r+3)>>0]|0)+(d[p+(r+4)>>0]|0)|0;z=(d[p+(r+6)>>0]|0)+(d[p+(r+5)>>0]|0)+(d[p+(r+7)>>0]|0)+(d[p+(z|15)>>0]|0)|0;r=x+w|0;c[ra>>2]=y+r+(c[ra>>2]|0)+z;t=ra+4|0;c[t>>2]=r-y-z+(c[t>>2]|0);t=1;r=s+1|0}else{t=0;w=0;x=0;y=0;z=0;r=s}if((g|0)!=0?(c[b+-20>>2]|0)!=0:0){_=o+-1|0;$=na<<4;j=na<<5;ma=na*48|0;C=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;h=na<<6;_=_+h|0;B=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;_=_+h|0;A=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;h=_+h|0;ma=(d[p+(h+$)>>0]|0)+(d[p+h>>0]|0)+(d[p+(h+j)>>0]|0)+(d[p+(h+ma)>>0]|0)|0;h=B+C|0;c[ra>>2]=A+h+(c[ra>>2]|0)+ma;j=ra+16|0;c[j>>2]=h-A-ma+(c[j>>2]|0);j=r+1|0;h=1}else{j=r;C=0;B=0;A=0;ma=0;h=0}do if((na+-1|0)!=(g|0)?(c[b+412>>2]|0)!=0:0){$=o+16|0;n=na<<4;m=na<<5;o=na*48|0;b=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;q=na<<6;$=$+q|0;l=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;$=$+q|0;k=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;q=$+q|0;o=(d[p+(q+n)>>0]|0)+(d[p+q>>0]|0)+(d[p+(q+m)>>0]|0)+(d[p+(q+o)>>0]|0)|0;p=j+1|0;q=h+1|0;j=l+b|0;c[ra>>2]=k+j+(c[ra>>2]|0)+o;m=ra+16|0;j=j-k-o+(c[m>>2]|0)|0;c[m>>2]=j;m=(r|0)==0;n=(h|0)!=0;if(!(m&n)){if(!m){m=1;j=p;h=q;l=21;break}}else c[ra+4>>2]=A+ma+B+C-b-l-k-o>>5;m=1;o=(s|0)!=0;b=(t|0)!=0;h=q;l=27}else l=17;while(0);if((l|0)==17){n=(h|0)!=0;if(!r){m=0;p=j;l=23}else{m=0;l=21}}if((l|0)==21){p=ra+4|0;c[p>>2]=c[p>>2]>>r+3;p=j;l=23}do if((l|0)==23){j=(h|0)==0;o=(s|0)!=0;b=(t|0)!=0;if(j&o&b){c[ra+16>>2]=F+v+D+E-z-y-x-w>>5;pa=m;h=p;oa=n;o=1;b=1;break}if(j){pa=m;h=p;oa=n}else{j=c[ra+16>>2]|0;l=27}}while(0);if((l|0)==27){c[ra+16>>2]=j>>h+3;pa=m;h=p;oa=n}if((h|0)==1)c[ra>>2]=c[ra>>2]>>4;else if((h|0)==2)c[ra>>2]=c[ra>>2]>>5;else if((h|0)==3)c[ra>>2]=(c[ra>>2]|0)*21>>10;else c[ra>>2]=c[ra>>2]>>6;Dc(ra);n=0;j=qa;m=ra;while(1){h=c[m+((n>>>2&3)<<2)>>2]|0;if((h|0)<0)h=0;else h=(h|0)>255?-1:h&255;a[j>>0]=h;h=n+1|0;if((h|0)==256)break;else{n=h;j=j+1|0;m=(h&63|0)==0?m+16|0:m}}ta=Z(u,na)|0;V=na<<3;Y=0-V|0;G=Y|1;_=G+1|0;$=Y|3;aa=$+1|0;ba=$+2|0;ca=$+3|0;da=Y|7;W=ra+4|0;ka=na<<6;H=ka|1;ea=H+1|0;fa=ka|3;ga=fa+1|0;ha=fa+2|0;ia=fa+3|0;ja=ka|7;I=V+-1|0;U=na<<4;J=U+-1|0;K=J+V|0;L=J+U|0;M=L+V|0;N=L+U|0;O=N+V|0;X=ra+16|0;P=V+8|0;Q=U|8;R=Q+V|0;S=Q+U|0;T=S+V|0;U=S+U|0;V=U+V|0;la=ta<<6;q=E;p=D;h=F;t=v;n=w;j=x;l=y;u=z;F=0;m=C;k=B;r=A;s=ma;E=(c[e>>2]|0)+((Z(f<<6,na)|0)+(g<<3)+(ta<<8))|0;while(1){id(ra,0,64);if(o){q=(d[E+G>>0]|0)+(d[E+Y>>0]|0)|0;p=(d[E+$>>0]|0)+(d[E+_>>0]|0)|0;z=(d[E+ba>>0]|0)+(d[E+aa>>0]|0)|0;A=(d[E+da>>0]|0)+(d[E+ca>>0]|0)|0;t=p+q|0;c[ra>>2]=z+t+(c[ra>>2]|0)+A;c[W>>2]=t-z-A+(c[W>>2]|0);t=1}else{z=h;A=t;t=0}if(b){B=(d[E+H>>0]|0)+(d[E+ka>>0]|0)|0;C=(d[E+fa>>0]|0)+(d[E+ea>>0]|0)|0;D=(d[E+ha>>0]|0)+(d[E+ga>>0]|0)|0;u=(d[E+ja>>0]|0)+(d[E+ia>>0]|0)|0;h=C+B|0;c[ra>>2]=D+h+(c[ra>>2]|0)+u;c[W>>2]=h-D-u+(c[W>>2]|0);h=t+1|0}else{B=n;C=j;D=l;h=t}if(oa){v=(d[E+I>>0]|0)+(d[E+-1>>0]|0)|0;w=(d[E+K>>0]|0)+(d[E+J>>0]|0)|0;x=(d[E+M>>0]|0)+(d[E+L>>0]|0)|0;y=(d[E+O>>0]|0)+(d[E+N>>0]|0)|0;t=w+v|0;c[ra>>2]=x+t+(c[ra>>2]|0)+y;c[X>>2]=t-x-y+(c[X>>2]|0);t=h+1|0;s=1}else{t=h;v=m;w=k;x=r;y=s;s=0}do if(pa){l=(d[E+P>>0]|0)+(d[E+8>>0]|0)|0;m=(d[E+R>>0]|0)+(d[E+Q>>0]|0)|0;j=(d[E+T>>0]|0)+(d[E+S>>0]|0)|0;n=(d[E+V>>0]|0)+(d[E+U>>0]|0)|0;t=t+1|0;s=s+1|0;k=m+l|0;c[ra>>2]=j+k+(c[ra>>2]|0)+n;k=k-j-n+(c[X>>2]|0)|0;c[X>>2]=k;r=(h|0)==0;if(!(r&oa))if(r){l=54;break}else{l=49;break}else{c[W>>2]=x+y+w+v-l-m-j-n>>4;l=54;break}}else if(!h){r=s;l=50}else l=49;while(0);if((l|0)==49){c[W>>2]=c[W>>2]>>h+2;r=s;l=50}do if((l|0)==50){l=0;s=(r|0)==0;if(s&o&b){c[X>>2]=z+A+p+q-u-D-C-B>>4;break}if(!s){k=c[X>>2]|0;s=r;l=54}}while(0);if((l|0)==54)c[X>>2]=k>>s+2;if((t|0)==1)c[ra>>2]=c[ra>>2]>>3;else if((t|0)==2)c[ra>>2]=c[ra>>2]>>4;else if((t|0)==3)c[ra>>2]=(c[ra>>2]|0)*21>>9;else c[ra>>2]=c[ra>>2]>>5;Dc(ra);s=0;r=qa+((F<<6)+256)|0;k=ra;while(1){t=c[k+((s>>>1&3)<<2)>>2]|0;if((t|0)<0)t=0;else t=(t|0)>255?-1:t&255;a[r>>0]=t;t=s+1|0;if((t|0)==64)break;else{s=t;r=r+1|0;k=(t&15|0)==0?k+16|0:k}}F=F+1|0;if((F|0)==2)break;else{h=z;t=A;n=B;j=C;l=D;m=v;k=w;r=x;s=y;E=E+la|0}}sc(e,qa);i=sa;return}function Dc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;h=i;f=a+4|0;b=c[f>>2]|0;g=a+16|0;d=c[g>>2]|0;e=c[a>>2]|0;if(!(b|d)){c[a+60>>2]=e;c[a+56>>2]=e;c[a+52>>2]=e;c[a+48>>2]=e;c[a+44>>2]=e;c[a+40>>2]=e;c[a+36>>2]=e;c[a+32>>2]=e;c[a+28>>2]=e;c[a+24>>2]=e;c[a+20>>2]=e;c[g>>2]=e;c[a+12>>2]=e;c[a+8>>2]=e;c[f>>2]=e;i=h;return}else{k=b+e|0;g=b>>1;j=g+e|0;g=e-g|0;b=e-b|0;c[a>>2]=d+k;e=d>>1;c[a+16>>2]=e+k;c[a+32>>2]=k-e;c[a+48>>2]=k-d;c[f>>2]=d+j;c[a+20>>2]=e+j;c[a+36>>2]=j-e;c[a+52>>2]=j-d;c[a+8>>2]=d+g;c[a+24>>2]=e+g;c[a+40>>2]=g-e;c[a+56>>2]=g-d;c[a+12>>2]=d+b;c[a+28>>2]=e+b;c[a+44>>2]=b-e;c[a+60>>2]=b-d;i=h;return}}function Ec(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;id(b,0,952);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b>>2]=d&1;do if(d){d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+4>>2]=d;if((d|0)==255){d=jb(a,16)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+8>>2]=d;d=jb(a,16)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+12>>2]=d;break}}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+16>>2]=d&1;do if(d){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+20>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+24>>2]=d&1;do if(d){d=jb(a,3)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+28>>2]=d;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+32>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+36>>2]=d&1;if(!d){c[b+40>>2]=2;c[b+44>>2]=2;c[b+48>>2]=2;break}d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+40>>2]=d;d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+44>>2]=d;d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+48>>2]=d;break}}else{c[b+28>>2]=5;c[b+40>>2]=2;c[b+44>>2]=2;c[b+48>>2]=2}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+52>>2]=d&1;if(d){d=b+56|0;e=nb(a,d)|0;if(e){d=e;i=h;return d|0}if((c[d>>2]|0)>>>0>5){d=1;i=h;return d|0}d=b+60|0;e=nb(a,d)|0;if(e){d=e;i=h;return d|0}if((c[d>>2]|0)>>>0>5){d=1;i=h;return d|0}}d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+64>>2]=d&1;do if(d){d=kb(a)|0;if((lb(a,32)|0)==-1|(d|0)==0){d=1;i=h;return d|0}c[b+68>>2]=d;d=kb(a)|0;if((lb(a,32)|0)==-1|(d|0)==0){d=1;i=h;return d|0}c[b+72>>2]=d;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+76>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;f=b+80|0;c[f>>2]=d&1;if(d){e=Fc(a,b+84|0)|0;if(e){d=e;i=h;return d|0}}else{c[b+84>>2]=1;c[b+96>>2]=288000001;c[b+224>>2]=288000001;c[b+480>>2]=24;c[b+484>>2]=24;c[b+488>>2]=24;c[b+492>>2]=24}e=jb(a,1)|0;if((e|0)==-1){d=1;i=h;return d|0}e=(e|0)==1;d=b+496|0;c[d>>2]=e&1;if(e){e=Fc(a,b+500|0)|0;if(e){d=e;i=h;return d|0}}else{c[b+500>>2]=1;c[b+512>>2]=240000001;c[b+640>>2]=240000001;c[b+896>>2]=24;c[b+900>>2]=24;c[b+904>>2]=24;c[b+908>>2]=24}if(!((c[f>>2]|0)==0?(c[d>>2]|0)==0:0))g=46;do if((g|0)==46){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+912>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+916>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+920>>2]=d&1;do if(d){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+924>>2]=(d|0)==1&1;e=b+928|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+932|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+936|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+940|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}d=nb(a,b+944|0)|0;if(d){i=h;return d|0}d=nb(a,b+948|0)|0;if(!d)break;i=h;return d|0}else{c[b+924>>2]=1;c[b+928>>2]=2;c[b+932>>2]=1;c[b+936>>2]=16;c[b+940>>2]=16;c[b+944>>2]=16;c[b+948>>2]=16}while(0);d=0;i=h;return d|0}function Fc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;d=nb(a,b)|0;if(d){i=k;return d|0}d=(c[b>>2]|0)+1|0;c[b>>2]=d;if(d>>>0>32){d=1;i=k;return d|0}d=jb(a,4)|0;if((d|0)==-1){d=1;i=k;return d|0}j=b+4|0;c[j>>2]=d;e=jb(a,4)|0;if((e|0)==-1){d=1;i=k;return d|0}h=b+8|0;c[h>>2]=e;a:do if(c[b>>2]|0){g=0;while(1){f=b+(g<<2)+12|0;d=nb(a,f)|0;if(d){e=17;break}e=c[f>>2]|0;if((e|0)==-1){d=1;e=17;break}d=e+1|0;c[f>>2]=d;c[f>>2]=d<<(c[j>>2]|0)+6;f=b+(g<<2)+140|0;d=nb(a,f)|0;if(d){e=17;break}e=c[f>>2]|0;if((e|0)==-1){d=1;e=17;break}e=e+1|0;c[f>>2]=e;c[f>>2]=e<<(c[h>>2]|0)+4;e=jb(a,1)|0;if((e|0)==-1){d=1;e=17;break}c[b+(g<<2)+268>>2]=(e|0)==1&1;g=g+1|0;if(g>>>0>=(c[b>>2]|0)>>>0)break a}if((e|0)==17){i=k;return d|0}}while(0);d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+396>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+400>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+404>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+408>>2]=d;d=0;i=k;return d|0}function Gc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;a:do if(!(c[d+284>>2]|0))o=0;else{h=0;while(1){j=c[d+(h*20|0)+288>>2]|0;if((j|0)==5){o=1;break a}else if(!j)break;h=h+1|0}o=0}while(0);j=c[b+16>>2]|0;if((j|0)==1){if((c[e>>2]|0)!=5){f=c[a+12>>2]|0;if((c[a+8>>2]|0)>>>0>(c[d+12>>2]|0)>>>0)f=(c[b+12>>2]|0)+f|0}else f=0;m=c[b+36>>2]|0;h=(m|0)==0;if(h)j=0;else j=(c[d+12>>2]|0)+f|0;e=(c[e+4>>2]|0)==0;k=((e&(j|0)!=0)<<31>>31)+j|0;l=(k|0)!=0;if(l){g=k+-1|0;n=(g>>>0)%(m>>>0)|0;g=(g>>>0)/(m>>>0)|0}else{n=0;g=0}if(h)j=0;else{k=c[b+40>>2]|0;j=0;h=0;do{j=(c[k+(h<<2)>>2]|0)+j|0;h=h+1|0}while(h>>>0>>0)}if(l){g=Z(j,g)|0;k=c[b+40>>2]|0;j=0;do{g=(c[k+(j<<2)>>2]|0)+g|0;j=j+1|0}while(j>>>0<=n>>>0)}else g=0;if(e)j=(c[b+28>>2]|0)+g|0;else j=g;g=(c[d+32>>2]|0)+(c[b+32>>2]|0)|0;h=a+12|0;if(!o){b=((g|0)<0?g:0)+j+(c[d+28>>2]|0)|0;c[h>>2]=f;c[a+8>>2]=c[d+12>>2];i=p;return b|0}else{c[h>>2]=0;c[a+8>>2]=0;b=0;i=p;return b|0}}else if(!j){if((c[e>>2]|0)!=5){h=c[a>>2]|0;j=c[d+20>>2]|0;if(h>>>0>j>>>0?(k=c[b+20>>2]|0,(h-j|0)>>>0>=k>>>1>>>0):0){h=(c[a+4>>2]|0)+k|0;k=a}else{k=a;m=11}}else{c[a+4>>2]=0;c[a>>2]=0;j=c[d+20>>2]|0;h=0;k=a;m=11}do if((m|0)==11){if(j>>>0>h>>>0?(g=c[b+20>>2]|0,(j-h|0)>>>0>g>>>1>>>0):0){h=(c[a+4>>2]|0)-g|0;break}h=c[a+4>>2]|0}while(0);if(!(c[e+4>>2]|0)){b=c[d+24>>2]|0;b=j+h+((b|0)<0?b:0)|0;i=p;return b|0}c[a+4>>2]=h;f=c[d+24>>2]|0;g=(f|0)<0;if(!o){c[k>>2]=j;b=j+h+(g?f:0)|0;i=p;return b|0}else{c[a+4>>2]=0;c[k>>2]=g?0-f|0:0;b=0;i=p;return b|0}}else{if((c[e>>2]|0)==5){k=0;g=0;f=a+12|0}else{j=c[d+12>>2]|0;f=a+12|0;h=c[f>>2]|0;if((c[a+8>>2]|0)>>>0>j>>>0)h=(c[b+12>>2]|0)+h|0;k=h;g=(j+h<<1)+(((c[e+4>>2]|0)==0)<<31>>31)|0}if(!o){c[f>>2]=k;c[a+8>>2]=c[d+12>>2];b=g;i=p;return b|0}else{c[f>>2]=0;c[a+8>>2]=0;b=0;i=p;return b|0}}return 0}function Hc(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;Ab(a);e=fd(2112)|0;c[a+3376>>2]=e;if(e)if(!b)b=0;else{c[a+1216>>2]=1;b=0}else b=1;i=d;return b|0}function Ic(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,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;i=i+208|0;l=r+204|0;p=r;g=r+112|0;h=r+40|0;q=r+16|0;j=r+12|0;n=r+8|0;c[j>>2]=0;o=a+3344|0;if((c[o>>2]|0)!=0?(c[a+3348>>2]|0)==(b|0):0){b=a+3356|0;c[q+0>>2]=c[b+0>>2];c[q+4>>2]=c[b+4>>2];c[q+8>>2]=c[b+8>>2];c[q+12>>2]=c[b+12>>2];c[q+4>>2]=c[q>>2];c[q+8>>2]=0;c[q+16>>2]=0;c[f>>2]=c[a+3352>>2]}else k=4;do if((k|0)==4)if(!(Pa(b,d,q,f)|0)){d=a+3356|0;c[d+0>>2]=c[q+0>>2];c[d+4>>2]=c[q+4>>2];c[d+8>>2]=c[q+8>>2];c[d+12>>2]=c[q+12>>2];c[d+16>>2]=c[q+16>>2];c[a+3352>>2]=c[f>>2];c[a+3348>>2]=b;break}else{n=3;i=r;return n|0}while(0);c[o>>2]=0;if(sb(q,p)|0){n=3;i=r;return n|0}if(((c[p>>2]|0)+-1|0)>>>0>11){n=0;i=r;return n|0}b=Ib(q,p,a,j)|0;if(!b){do if(!(c[j>>2]|0))k=19;else{if((c[a+1184>>2]|0)!=0?(c[a+16>>2]|0)!=0:0){if(c[a+3380>>2]|0){n=3;i=r;return n|0}if(!(c[a+1188>>2]|0)){m=a+1220|0;n=a+1336|0;c[n>>2]=jc(m)|0;nc(m);Bc(a,n,0)|0}else Bc(a,a+1336|0,c[a+1372>>2]|0)|0;c[f>>2]=0;c[o>>2]=1;c[a+1180>>2]=0;g=a+1336|0;b=a+1360|0;break}c[a+1188>>2]=0;c[a+1180>>2]=0;k=19}while(0);do if((k|0)==19){b=c[p>>2]|0;if((b|0)==7)if(!(Qa(q,g)|0)){Bb(a,g)|0;n=0;i=r;return n|0}else{n=g+40|0;gd(c[n>>2]|0);c[n>>2]=0;n=g+84|0;gd(c[n>>2]|0);c[n>>2]=0;n=3;i=r;return n|0}else if((b|0)==1|(b|0)==5){k=a+1180|0;if(c[a+1180>>2]|0){n=0;i=r;return n|0}c[a+1184>>2]=1;if(Fb(a)|0){c[a+1204>>2]=0;c[a+1208>>2]=e;Ua(q,l)|0;j=a+8|0;d=c[j>>2]|0;b=Db(a,c[l>>2]|0,(c[p>>2]|0)==5&1)|0;if(b){c[a+4>>2]=256;c[a+12>>2]=0;c[j>>2]=32;c[a+16>>2]=0;c[a+3380>>2]=0;n=(b|0)==65535?5:4;i=r;return n|0}if((d|0)!=(c[j>>2]|0)){d=c[a+16>>2]|0;c[n>>2]=1;b=c[a>>2]|0;if(b>>>0<32)b=c[a+(b<<2)+20>>2]|0;else b=0;c[f>>2]=0;c[o>>2]=1;if((((((c[p>>2]|0)==5?(l=_a(n,q,d,c[a+12>>2]|0,5)|0,(c[n>>2]|l|0)==0):0)?(m=a+1220|0,!((c[a+1276>>2]|0)!=0|(b|0)==0)):0)?(c[b+52>>2]|0)==(c[d+52>>2]|0):0)?(c[b+56>>2]|0)==(c[d+56>>2]|0):0)?(c[b+88>>2]|0)==(c[d+88>>2]|0):0)qc(m);else c[a+1280>>2]=0;c[a>>2]=c[j>>2];n=2;i=r;return n|0}}if(c[a+3380>>2]|0){n=3;i=r;return n|0}h=a+1368|0;j=a+2356|0;b=a+16|0;if(Ta(q,j,c[b>>2]|0,c[a+12>>2]|0,p)|0){n=3;i=r;return n|0}if(!(Fb(a)|0))d=a+1220|0;else{d=a+1220|0;if((c[p>>2]|0)!=5?(oc(d,c[a+2368>>2]|0,(c[p+4>>2]|0)!=0&1,c[(c[b>>2]|0)+48>>2]|0)|0)!=0:0){n=3;i=r;return n|0}c[a+1336>>2]=jc(d)|0}od(h|0,j|0,988)|0;c[a+1188>>2]=1;b=a+1360|0;l=p;m=c[l+4>>2]|0;n=b;c[n>>2]=c[l>>2];c[n+4>>2]=m;Hb(a,c[a+1432>>2]|0);nc(d);if(gc(d,a+1436|0,c[a+1380>>2]|0,c[a+1412>>2]|0)|0){n=3;i=r;return n|0}g=a+1336|0;if($a(q,a,g,h)|0){ab(a,c[h>>2]|0);n=3;i=r;return n|0}if(!(Gb(a)|0)){n=0;i=r;return n|0}else{c[k>>2]=1;break}}else if((b|0)==8)if(!(Sa(q,h)|0)){Cb(a,h)|0;n=0;i=r;return n|0}else{n=h+20|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+24|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+28|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+44|0;gd(c[n>>2]|0);c[n>>2]=0;n=3;i=r;return n|0}else{n=0;i=r;return n|0}}while(0);uc(g,c[a+1212>>2]|0);Eb(a);j=Gc(a+1284|0,c[a+16>>2]|0,a+1368|0,b)|0;d=a+1188|0;do if(c[d>>2]|0){h=a+1220|0;if(!(c[a+1364>>2]|0)){hc(h,0,g,c[a+1380>>2]|0,j,(c[b>>2]|0)==5&1,c[a+1208>>2]|0,c[a+1204>>2]|0)|0;break}else{hc(h,a+1644|0,g,c[a+1380>>2]|0,j,(c[b>>2]|0)==5&1,c[a+1208>>2]|0,c[a+1204>>2]|0)|0;break}}while(0);c[a+1184>>2]=0;c[d>>2]=0;n=1;i=r;return n|0}else if((b|0)==65520){n=4;i=r;return n|0}else{n=3;i=r;return n|0}return 0}function Jc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;e=0;do{d=a+(e<<2)+20|0;b=c[d>>2]|0;if(b){gd(c[b+40>>2]|0);c[(c[d>>2]|0)+40>>2]=0;gd(c[(c[d>>2]|0)+84>>2]|0);c[(c[d>>2]|0)+84>>2]=0;gd(c[d>>2]|0);c[d>>2]=0}e=e+1|0}while((e|0)!=32);e=0;do{d=a+(e<<2)+148|0;b=c[d>>2]|0;if(b){gd(c[b+20>>2]|0);c[(c[d>>2]|0)+20>>2]=0;gd(c[(c[d>>2]|0)+24>>2]|0);c[(c[d>>2]|0)+24>>2]=0;gd(c[(c[d>>2]|0)+28>>2]|0);c[(c[d>>2]|0)+28>>2]=0;gd(c[(c[d>>2]|0)+44>>2]|0);c[(c[d>>2]|0)+44>>2]=0;gd(c[d>>2]|0);c[d>>2]=0}e=e+1|0}while((e|0)!=256);b=a+3376|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+1212|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+1172|0;gd(c[b>>2]|0);c[b>>2]=0;mc(a+1220|0);i=f;return}function Kc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=i;a=pc(a+1220|0)|0;if(!a){a=0;i=f;return a|0}c[b>>2]=c[a+4>>2];c[d>>2]=c[a+12>>2];c[e>>2]=c[a+8>>2];a=c[a>>2]|0;i=f;return a|0}function Lc(a){a=a|0;var b=0;b=i;a=c[a+16>>2]|0;if(!a){a=0;i=b;return a|0}a=c[a+52>>2]|0;i=b;return a|0}function Mc(a){a=a|0;var b=0;b=i;a=c[a+16>>2]|0;if(!a){a=0;i=b;return a|0}a=c[a+56>>2]|0;i=b;return a|0}function Nc(a){a=a|0;var b=0;b=i;qc(a+1220|0);i=b;return}function Oc(a){a=a|0;var b=0;b=i;a=(Jb(a)|0)==0&1;i=b;return a|0}function Pc(a){a=a|0;var b=0,d=0;d=i;a=c[a+16>>2]|0;if(((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(b=c[a+84>>2]|0,(b|0)!=0):0)?(c[b+24>>2]|0)!=0:0)?(c[b+32>>2]|0)!=0:0){a=1;i=d;return a|0}a=0;i=d;return a|0}function Qc(a){a=a|0;var b=0,d=0;d=i;a=c[a+16>>2]|0;if(((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(b=c[a+84>>2]|0,(b|0)!=0):0)?(c[b+24>>2]|0)!=0:0)?(c[b+36>>2]|0)!=0:0)a=c[b+48>>2]|0;else a=2;i=d;return a|0}function Rc(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;h=i;a=c[a+16>>2]|0;if((a|0)!=0?(c[a+60>>2]|0)!=0:0){c[b>>2]=1;b=a+64|0;c[d>>2]=c[b>>2]<<1;c[e>>2]=(c[a+52>>2]<<4)-((c[a+68>>2]|0)+(c[b>>2]|0)<<1);b=a+72|0;c[f>>2]=c[b>>2]<<1;a=(c[a+56>>2]<<4)-((c[a+76>>2]|0)+(c[b>>2]|0)<<1)|0;c[g>>2]=a;i=h;return}c[b>>2]=0;c[d>>2]=0;c[e>>2]=0;c[f>>2]=0;a=0;c[g>>2]=a;i=h;return}function Sc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;f=i;a=c[a+16>>2]|0;a:do if((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(e=c[a+84>>2]|0,(e|0)!=0):0)?(c[e>>2]|0)!=0:0){a=c[e+4>>2]|0;do switch(a|0){case 8:{e=11;a=32;break a}case 13:{e=99;a=160;break a}case 12:{e=33;a=64;break a}case 6:{e=11;a=24;break a}case 7:{e=11;a=20;break a}case 255:{a=c[e+8>>2]|0;e=c[e+12>>2]|0;g=(a|0)==0|(e|0)==0;e=g?0:e;a=g?0:a;break a}case 5:{e=33;a=40;break a}case 4:{e=11;a=16;break a}case 3:{e=11;a=10;break a}case 1:case 0:{e=a;break a}case 2:{e=11;a=12;break a}case 10:{e=11;a=18;break a}case 9:{e=33;a=80;break a}case 11:{e=11;a=15;break a}default:{e=0;a=0;break a}}while(0)}else{e=1;a=1}while(0);c[b>>2]=a;c[d>>2]=e;i=f;return}function Tc(a){a=a|0;a=c[a+16>>2]|0;if(!a)a=0;else a=c[a>>2]|0;return a|0}function Uc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;do if(a){d=fd(3396)|0;if(d){e=d+8|0;if(!(Hc(e,b)|0)){c[d>>2]=1;c[d+4>>2]=0;c[a>>2]=d;d=0;break}else{Jc(e);gd(d);d=-4;break}}else d=-4}else d=-1;while(0);i=f;return d|0}function Vc(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;if((a|0)==0|(b|0)==0){a=-1;i=e;return a|0}d=a+8|0;if(!(c[a+24>>2]|0)){a=-6;i=e;return a|0}if(!(c[a+20>>2]|0)){a=-6;i=e;return a|0}c[b+4>>2]=(Lc(d)|0)<<4;c[b+8>>2]=(Mc(d)|0)<<4;c[b+12>>2]=Pc(d)|0;c[b+16>>2]=Qc(d)|0;Rc(d,b+28|0,b+32|0,b+36|0,b+40|0,b+44|0);Sc(d,b+20|0,b+24|0);c[b>>2]=Tc(d)|0;a=0;i=e;return a|0}function Wc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;m=i;i=i+16|0;j=m;a:do if((!((b|0)==0|(d|0)==0)?(f=c[b>>2]|0,(f|0)!=0):0)?(g=c[b+4>>2]|0,(g|0)!=0):0)if((a|0)!=0?(e=c[a>>2]|0,(e|0)!=0):0){c[d>>2]=0;c[j>>2]=0;k=a+8|0;c[a+3392>>2]=c[b+12>>2];h=b+8|0;b=1;while(1){if((e|0)==2){l=8;break}e=Ic(k,f,g,c[h>>2]|0,j)|0;n=c[j>>2]|0;f=f+n|0;g=g-n|0;g=(g|0)<0?0:g;c[d>>2]=f;if((e|0)==5){b=-4;break a}else if((e|0)==4){e=(Oc(k)|0|g|0)==0;b=e?-2:b}else if((e|0)==2)break;else if((e|0)==1){l=13;break}if(!g)break a;e=c[a>>2]|0}if((l|0)==8){c[a>>2]=1;c[d>>2]=f+(c[j>>2]|0)}else if((l|0)==13){b=a+4|0;c[b>>2]=(c[b>>2]|0)+1;b=(g|0)==0?2:3;break}b=a+1288|0;if((c[b>>2]|0)!=0?(c[a+1244>>2]|0)!=(c[a+1248>>2]|0):0){c[b>>2]=0;c[a>>2]=2;b=3}else b=4}else b=-3;else b=-1;while(0);i=m;return b|0}function Xc(a){a=a|0;c[a>>2]=2;c[a+4>>2]=3;return}function Yc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;h=i;i=i+16|0;f=h+8|0;e=h+4|0;g=h;if((a|0)==0|(b|0)==0){a=-1;i=h;return a|0}a=a+8|0;if(d)Nc(a);a=Kc(a,g,e,f)|0;if(!a){a=0;i=h;return a|0}c[b>>2]=a;c[b+4>>2]=c[g>>2];c[b+8>>2]=c[e>>2];c[b+12>>2]=c[f>>2];a=2;i=h;return a|0}function Zc(a){a=a|0;var b=0,d=0;d=i;b=jd(a)|0;c[1792]=b;c[1791]=b;c[1790]=a;c[1793]=b+a;i=d;return b|0}function _c(a){a=a|0;c[1790]=a;return}function $c(){var a=0;a=i;c[1786]=c[1791];c[1787]=c[1790];do bd()|0;while((c[1787]|0)!=0);i=a;return}function ad(){var a=0,b=0;b=i;if(Uc(7176,0)|0){da(7280)|0;a=c[1784]|0;if(a)kd(a)}else{c[1796]=1;c[1798]=1}i=b;return -1}function bd(){var a=0,b=0,d=0;b=i;c[1788]=c[1798];a=Wc(c[1794]|0,7144,7200)|0;switch(a|0){case 1:case -2:{c[1787]=0;i=b;return a|0}case 4:{if(Vc(c[1794]|0,7208)|0){a=-1;i=b;return a|0}c[1814]=(Z((c[1803]|0)*3|0,c[1804]|0)|0)>>>1;ra();a=c[1800]|0;c[1787]=(c[1786]|0)-a+(c[1787]|0);c[1786]=a;a=0;i=b;return a|0}case 2:{c[1787]=0;break}case 3:{d=c[1800]|0;c[1787]=(c[1786]|0)-d+(c[1787]|0);c[1786]=d;break}default:{i=b;return a|0}}c[1798]=(c[1798]|0)+1;if((Yc(c[1794]|0,7264,0)|0)!=2){i=b;return a|0}do{c[1796]=(c[1796]|0)+1;ca(c[1816]|0,c[1803]|0,c[1804]|0)}while((Yc(c[1794]|0,7264,0)|0)==2);i=b;return a|0}function cd(){var a=0,b=0;b=i;a=c[1784]|0;if(a)kd(a);i=b;return}function dd(){var a=0,b=0;b=i;i=i+16|0;a=b;Xc(a);i=b;return c[a>>2]|0}function ed(){var a=0,b=0;b=i;i=i+16|0;a=b;Xc(a);i=b;return c[a+4>>2]|0}function fd(a){a=a|0;var b=0;b=i;a=jd(a)|0;i=b;return a|0}function gd(a){a=a|0;var b=0;b=i;kd(a);i=b;return}function hd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=i;od(a|0,b|0,c|0)|0;i=d;return}function id(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=i;nd(a|0,b&255|0,c|0)|0;i=d;return}function jd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=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,G=0,H=0,I=0,J=0,K=0,L=0;L=i;do if(a>>>0<245){if(a>>>0<11)p=16;else p=a+11&-8;a=p>>>3;l=c[1828]|0;k=l>>>a;if(k&3){g=(k&1^1)+a|0;b=g<<1;h=7352+(b<<2)|0;b=7352+(b+2<<2)|0;e=c[b>>2]|0;j=e+8|0;f=c[j>>2]|0;do if((h|0)!=(f|0)){if(f>>>0<(c[1832]|0)>>>0)ka();d=f+12|0;if((c[d>>2]|0)==(e|0)){c[d>>2]=h;c[b>>2]=f;break}else ka()}else c[1828]=l&~(1<>2]=x|3;x=e+(x|4)|0;c[x>>2]=c[x>>2]|1;x=j;i=L;return x|0}j=c[1830]|0;if(p>>>0>j>>>0){if(k){g=2<>>12&16;g=g>>>a;h=g>>>5&8;g=g>>>h;d=g>>>2&4;g=g>>>d;e=g>>>1&2;g=g>>>e;f=g>>>1&1;f=(h|a|d|e|f)+(g>>>f)|0;g=f<<1;e=7352+(g<<2)|0;g=7352+(g+2<<2)|0;d=c[g>>2]|0;a=d+8|0;h=c[a>>2]|0;do if((e|0)!=(h|0)){if(h>>>0<(c[1832]|0)>>>0)ka();j=h+12|0;if((c[j>>2]|0)==(d|0)){c[j>>2]=e;c[g>>2]=h;m=c[1830]|0;break}else ka()}else{c[1828]=l&~(1<>2]=p|3;b=d+p|0;c[d+(p|4)>>2]=k|1;c[d+x>>2]=k;if(m){e=c[1833]|0;g=m>>>3;h=g<<1;f=7352+(h<<2)|0;j=c[1828]|0;g=1<>2]|0;if(h>>>0<(c[1832]|0)>>>0)ka();else{n=j;o=h}}else{c[1828]=j|g;n=7352+(h+2<<2)|0;o=f}c[n>>2]=e;c[o+12>>2]=e;c[e+8>>2]=o;c[e+12>>2]=f}c[1830]=k;c[1833]=b;x=a;i=L;return x|0}k=c[1829]|0;if(k){l=(k&0-k)+-1|0;w=l>>>12&16;l=l>>>w;v=l>>>5&8;l=l>>>v;x=l>>>2&4;l=l>>>x;j=l>>>1&2;l=l>>>j;m=l>>>1&1;m=c[7616+((v|w|x|j|m)+(l>>>m)<<2)>>2]|0;l=(c[m+4>>2]&-8)-p|0;j=m;while(1){d=c[j+16>>2]|0;if(!d){d=c[j+20>>2]|0;if(!d)break}j=(c[d+4>>2]&-8)-p|0;x=j>>>0>>0;l=x?j:l;j=d;m=x?d:m}k=c[1832]|0;if(m>>>0>>0)ka();b=m+p|0;if(m>>>0>=b>>>0)ka();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){e=0;break}}while(1){f=j+20|0;g=c[f>>2]|0;if(g){j=g;h=f;continue}f=j+16|0;g=c[f>>2]|0;if(!g)break;else{j=g;h=f}}if(h>>>0>>0)ka();else{c[h>>2]=0;e=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ka();j=f+12|0;if((c[j>>2]|0)!=(m|0))ka();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;e=g;break}else ka()}while(0);do if(a){j=c[m+28>>2]|0;h=7616+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=e;if(!e){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=e;else c[a+20>>2]=e;if(!e)break}h=c[1832]|0;if(e>>>0>>0)ka();c[e+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ka();else{c[e+16>>2]=j;c[j+24>>2]=e;break}while(0);f=c[m+20>>2]|0;if(f)if(f>>>0<(c[1832]|0)>>>0)ka();else{c[e+20>>2]=f;c[f+24>>2]=e;break}}while(0);if(l>>>0<16){x=l+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}else{c[m+4>>2]=p|3;c[m+(p|4)>>2]=l|1;c[m+(l+p)>>2]=l;d=c[1830]|0;if(d){e=c[1833]|0;g=d>>>3;h=g<<1;f=7352+(h<<2)|0;j=c[1828]|0;g=1<>2]|0;if(h>>>0<(c[1832]|0)>>>0)ka();else{r=j;q=h}}else{c[1828]=j|g;r=7352+(h+2<<2)|0;q=f}c[r>>2]=e;c[q+12>>2]=e;c[e+8>>2]=q;c[e+12>>2]=f}c[1830]=l;c[1833]=b}x=m+8|0;i=L;return x|0}}}else if(a>>>0<=4294967231){a=a+11|0;p=a&-8;m=c[1829]|0;if(m){h=0-p|0;a=a>>>8;if(a)if(p>>>0>16777215)l=31;else{q=(a+1048320|0)>>>16&8;r=a<>>16&4;r=r<>>16&2;l=14-(o|q|l)+(r<>>15)|0;l=p>>>(l+7|0)&1|l<<1}else l=0;j=c[7616+(l<<2)>>2]|0;a:do if(!j){a=0;k=0}else{if((l|0)==31)k=0;else k=25-(l>>>1)|0;f=h;a=0;e=p<>2]&-8;h=g-p|0;if(h>>>0>>0)if((g|0)==(p|0)){a=j;k=j;break a}else k=j;else h=f;r=c[j+20>>2]|0;j=c[j+(e>>>31<<2)+16>>2]|0;a=(r|0)==0|(r|0)==(j|0)?a:r;if(!j)break;else{f=h;e=e<<1}}}while(0);if((a|0)==0&(k|0)==0){a=2<>>12&16;r=r>>>n;m=r>>>5&8;r=r>>>m;o=r>>>2&4;r=r>>>o;q=r>>>1&2;r=r>>>q;a=r>>>1&1;a=c[7616+((m|n|o|q|a)+(r>>>a)<<2)>>2]|0}if(!a){n=h;m=k}else while(1){r=(c[a+4>>2]&-8)-p|0;j=r>>>0>>0;h=j?r:h;k=j?a:k;j=c[a+16>>2]|0;if(j){a=j;continue}a=c[a+20>>2]|0;if(!a){n=h;m=k;break}}if((m|0)!=0?n>>>0<((c[1830]|0)-p|0)>>>0:0){k=c[1832]|0;if(m>>>0>>0)ka();o=m+p|0;if(m>>>0>=o>>>0)ka();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){b=0;break}}while(1){f=j+20|0;g=c[f>>2]|0;if(g){j=g;h=f;continue}f=j+16|0;g=c[f>>2]|0;if(!g)break;else{j=g;h=f}}if(h>>>0>>0)ka();else{c[h>>2]=0;b=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ka();j=f+12|0;if((c[j>>2]|0)!=(m|0))ka();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;b=g;break}else ka()}while(0);do if(a){j=c[m+28>>2]|0;h=7616+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=b;if(!b){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=b;else c[a+20>>2]=b;if(!b)break}h=c[1832]|0;if(b>>>0>>0)ka();c[b+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ka();else{c[b+16>>2]=j;c[j+24>>2]=b;break}while(0);j=c[m+20>>2]|0;if(j)if(j>>>0<(c[1832]|0)>>>0)ka();else{c[b+20>>2]=j;c[j+24>>2]=b;break}}while(0);b:do if(n>>>0>=16){c[m+4>>2]=p|3;c[m+(p|4)>>2]=n|1;c[m+(n+p)>>2]=n;j=n>>>3;if(n>>>0<256){g=j<<1;d=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(e>>>0>=(c[1832]|0)>>>0){t=f;u=e;break}ka()}while(0);c[t>>2]=o;c[u+12>>2]=o;c[m+(p+8)>>2]=u;c[m+(p+12)>>2]=d;break}d=n>>>8;if(d)if(n>>>0>16777215)f=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|w|f)+(x<>>15)|0;f=n>>>(f+7|0)&1|f<<1}else f=0;h=7616+(f<<2)|0;c[m+(p+28)>>2]=f;c[m+(p+20)>>2]=0;c[m+(p+16)>>2]=0;j=c[1829]|0;g=1<>2]=o;c[m+(p+24)>>2]=h;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break}j=c[h>>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;c:do if((c[j+4>>2]&-8|0)!=(n|0)){f=n<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(n|0)){v=h;break c}else{f=f<<1;j=h}}if(g>>>0<(c[1832]|0)>>>0)ka();else{c[g>>2]=o;c[m+(p+24)>>2]=j;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break b}}else v=j;while(0);b=v+8|0;d=c[b>>2]|0;x=c[1832]|0;if(v>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=o;c[b>>2]=o;c[m+(p+8)>>2]=d;c[m+(p+12)>>2]=v;c[m+(p+24)>>2]=0;break}else ka()}else{x=n+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}while(0);x=m+8|0;i=L;return x|0}}}else p=-1;while(0);k=c[1830]|0;if(k>>>0>=p>>>0){d=k-p|0;b=c[1833]|0;if(d>>>0>15){c[1833]=b+p;c[1830]=d;c[b+(p+4)>>2]=d|1;c[b+k>>2]=d;c[b+4>>2]=p|3}else{c[1830]=0;c[1833]=0;c[b+4>>2]=k|3;x=b+(k+4)|0;c[x>>2]=c[x>>2]|1}x=b+8|0;i=L;return x|0}k=c[1831]|0;if(k>>>0>p>>>0){w=k-p|0;c[1831]=w;x=c[1834]|0;c[1834]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}do if(!(c[1946]|0)){k=ua(30)|0;if(!(k+-1&k)){c[1948]=k;c[1947]=k;c[1949]=-1;c[1950]=-1;c[1951]=0;c[1939]=0;c[1946]=(ta(0)|0)&-16^1431655768;break}else ka()}while(0);l=p+48|0;g=c[1948]|0;f=p+47|0;h=g+f|0;g=0-g|0;m=h&g;if(m>>>0<=p>>>0){x=0;i=L;return x|0}a=c[1938]|0;if((a|0)!=0?(u=c[1936]|0,v=u+m|0,v>>>0<=u>>>0|v>>>0>a>>>0):0){x=0;i=L;return x|0}d:do if(!(c[1939]&4)){j=c[1834]|0;e:do if(j){a=7760|0;while(1){k=c[a>>2]|0;if(k>>>0<=j>>>0?(s=a+4|0,(k+(c[s>>2]|0)|0)>>>0>j>>>0):0)break;a=c[a+8>>2]|0;if(!a){A=181;break e}}if(a){k=h-(c[1831]|0)&g;if(k>>>0<2147483647){j=ma(k|0)|0;if((j|0)==((c[a>>2]|0)+(c[s>>2]|0)|0))A=190;else A=191}else k=0}else A=181}else A=181;while(0);do if((A|0)==181){j=ma(0)|0;if((j|0)!=(-1|0)){a=j;k=c[1947]|0;h=k+-1|0;if(!(h&a))k=m;else k=m-a+(h+a&0-k)|0;a=c[1936]|0;h=a+k|0;if(k>>>0>p>>>0&k>>>0<2147483647){v=c[1938]|0;if((v|0)!=0?h>>>0<=a>>>0|h>>>0>v>>>0:0){k=0;break}h=ma(k|0)|0;if((h|0)==(j|0))A=190;else{j=h;A=191}}else k=0}else k=0}while(0);f:do if((A|0)==190){if((j|0)!=(-1|0)){w=j;s=k;A=201;break d}}else if((A|0)==191){a=0-k|0;do if((j|0)!=(-1|0)&k>>>0<2147483647&l>>>0>k>>>0?(d=c[1948]|0,d=f-k+d&0-d,d>>>0<2147483647):0)if((ma(d|0)|0)==(-1|0)){ma(a|0)|0;k=0;break f}else{k=d+k|0;break}while(0);if((j|0)==(-1|0))k=0;else{w=j;s=k;A=201;break d}}while(0);c[1939]=c[1939]|4;A=198}else{k=0;A=198}while(0);if((((A|0)==198?m>>>0<2147483647:0)?(w=ma(m|0)|0,x=ma(0)|0,(w|0)!=(-1|0)&(x|0)!=(-1|0)&w>>>0>>0):0)?(z=x-w|0,y=z>>>0>(p+40|0)>>>0,y):0){s=y?z:k;A=201}if((A|0)==201){j=(c[1936]|0)+s|0;c[1936]=j;if(j>>>0>(c[1937]|0)>>>0)c[1937]=j;o=c[1834]|0;g:do if(o){f=7760|0;while(1){k=c[f>>2]|0;g=f+4|0;j=c[g>>2]|0;if((w|0)==(k+j|0)){A=213;break}h=c[f+8>>2]|0;if(!h)break;else f=h}if(((A|0)==213?(c[f+12>>2]&8|0)==0:0)?o>>>0>=k>>>0&o>>>0>>0:0){c[g>>2]=j+s;d=(c[1831]|0)+s|0;b=o+8|0;if(!(b&7))b=0;else b=0-b&7;x=d-b|0;c[1834]=o+b;c[1831]=x;c[o+(b+4)>>2]=x|1;c[o+(d+4)>>2]=40;c[1835]=c[1950];break}k=c[1832]|0;if(w>>>0>>0){c[1832]=w;k=w}h=w+s|0;g=7760|0;while(1){if((c[g>>2]|0)==(h|0)){A=223;break}j=c[g+8>>2]|0;if(!j)break;else g=j}if((A|0)==223?(c[g+12>>2]&8|0)==0:0){c[g>>2]=w;j=g+4|0;c[j>>2]=(c[j>>2]|0)+s;j=w+8|0;if(!(j&7))r=0;else r=0-j&7;j=w+(s+8)|0;if(!(j&7))b=0;else b=0-j&7;j=w+(b+s)|0;q=r+p|0;n=w+q|0;d=j-(w+r)-p|0;c[w+(r+4)>>2]=p|3;h:do if((j|0)!=(o|0)){if((j|0)==(c[1833]|0)){x=(c[1830]|0)+d|0;c[1830]=x;c[1833]=n;c[w+(q+4)>>2]=x|1;c[w+(x+q)>>2]=x;break}l=s+4|0;h=c[w+(l+b)>>2]|0;if((h&3|0)==1){m=h&-8;e=h>>>3;i:do if(h>>>0>=256){a=c[w+((b|24)+s)>>2]|0;g=c[w+(s+12+b)>>2]|0;do if((g|0)==(j|0)){g=b|16;f=w+(l+g)|0;h=c[f>>2]|0;if(!h){g=w+(g+s)|0;h=c[g>>2]|0;if(!h){H=0;break}}else g=f;while(1){e=h+20|0;f=c[e>>2]|0;if(f){h=f;g=e;continue}e=h+16|0;f=c[e>>2]|0;if(!f)break;else{h=f;g=e}}if(g>>>0>>0)ka();else{c[g>>2]=0;H=h;break}}else{f=c[w+((b|8)+s)>>2]|0;if(f>>>0>>0)ka();k=f+12|0;if((c[k>>2]|0)!=(j|0))ka();h=g+8|0;if((c[h>>2]|0)==(j|0)){c[k>>2]=g;c[h>>2]=f;H=g;break}else ka()}while(0);if(!a)break;k=c[w+(s+28+b)>>2]|0;h=7616+(k<<2)|0;do if((j|0)!=(c[h>>2]|0)){if(a>>>0<(c[1832]|0)>>>0)ka();k=a+16|0;if((c[k>>2]|0)==(j|0))c[k>>2]=H;else c[a+20>>2]=H;if(!H)break i}else{c[h>>2]=H;if(H)break;c[1829]=c[1829]&~(1<>>0>>0)ka();c[H+24>>2]=a;j=b|16;k=c[w+(j+s)>>2]|0;do if(k)if(k>>>0>>0)ka();else{c[H+16>>2]=k;c[k+24>>2]=H;break}while(0);j=c[w+(l+j)>>2]|0;if(!j)break;if(j>>>0<(c[1832]|0)>>>0)ka();else{c[H+20>>2]=j;c[j+24>>2]=H;break}}else{g=c[w+((b|8)+s)>>2]|0;f=c[w+(s+12+b)>>2]|0;h=7352+(e<<1<<2)|0;do if((g|0)!=(h|0)){if(g>>>0>>0)ka();if((c[g+12>>2]|0)==(j|0))break;ka()}while(0);if((f|0)==(g|0)){c[1828]=c[1828]&~(1<>>0>>0)ka();k=f+8|0;if((c[k>>2]|0)==(j|0)){D=k;break}ka()}while(0);c[g+12>>2]=f;c[D>>2]=g}while(0);j=w+((m|b)+s)|0;k=m+d|0}else k=d;j=j+4|0;c[j>>2]=c[j>>2]&-2;c[w+(q+4)>>2]=k|1;c[w+(k+q)>>2]=k;j=k>>>3;if(k>>>0<256){g=j<<1;f=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(h>>>0>=(c[1832]|0)>>>0){I=j;J=h;break}ka()}while(0);c[I>>2]=n;c[J+12>>2]=n;c[w+(q+8)>>2]=J;c[w+(q+12)>>2]=f;break}d=k>>>8;do if(!d)f=0;else{if(k>>>0>16777215){f=31;break}v=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|v|f)+(x<>>15)|0;f=k>>>(f+7|0)&1|f<<1}while(0);h=7616+(f<<2)|0;c[w+(q+28)>>2]=f;c[w+(q+20)>>2]=0;c[w+(q+16)>>2]=0;j=c[1829]|0;g=1<>2]=n;c[w+(q+24)>>2]=h;c[w+(q+12)>>2]=n;c[w+(q+8)>>2]=n;break}j=c[h>>2]|0;if((f|0)==31)h=0;else h=25-(f>>>1)|0;j:do if((c[j+4>>2]&-8|0)!=(k|0)){f=k<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(k|0)){K=h;break j}else{f=f<<1;j=h}}if(g>>>0<(c[1832]|0)>>>0)ka();else{c[g>>2]=n;c[w+(q+24)>>2]=j;c[w+(q+12)>>2]=n;c[w+(q+8)>>2]=n;break h}}else K=j;while(0);b=K+8|0;d=c[b>>2]|0;x=c[1832]|0;if(K>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=n;c[b>>2]=n;c[w+(q+8)>>2]=d;c[w+(q+12)>>2]=K;c[w+(q+24)>>2]=0;break}else ka()}else{x=(c[1831]|0)+d|0;c[1831]=x;c[1834]=n;c[w+(q+4)>>2]=x|1}while(0);x=w+(r|8)|0;i=L;return x|0}j=7760|0;while(1){h=c[j>>2]|0;if(h>>>0<=o>>>0?(B=c[j+4>>2]|0,C=h+B|0,C>>>0>o>>>0):0)break;j=c[j+8>>2]|0}j=h+(B+-39)|0;if(!(j&7))j=0;else j=0-j&7;g=h+(B+-47+j)|0;g=g>>>0<(o+16|0)>>>0?o:g;h=g+8|0;j=w+8|0;if(!(j&7))j=0;else j=0-j&7;f=s+-40-j|0;c[1834]=w+j;c[1831]=f;c[w+(j+4)>>2]=f|1;c[w+(s+-36)>>2]=40;c[1835]=c[1950];c[g+4>>2]=27;c[h+0>>2]=c[1940];c[h+4>>2]=c[1941];c[h+8>>2]=c[1942];c[h+12>>2]=c[1943];c[1940]=w;c[1941]=s;c[1943]=0;c[1942]=h;f=g+28|0;c[f>>2]=7;if((g+32|0)>>>0>>0)do{x=f;f=f+4|0;c[f>>2]=7}while((x+8|0)>>>0>>0);if((g|0)!=(o|0)){k=g-o|0;j=o+(k+4)|0;c[j>>2]=c[j>>2]&-2;c[o+4>>2]=k|1;c[o+k>>2]=k;j=k>>>3;if(k>>>0<256){g=j<<1;f=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(b>>>0>=(c[1832]|0)>>>0){E=d;F=b;break}ka()}while(0);c[E>>2]=o;c[F+12>>2]=o;c[o+8>>2]=F;c[o+12>>2]=f;break}d=k>>>8;if(d)if(k>>>0>16777215)g=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;g=14-(v|w|g)+(x<>>15)|0;g=k>>>(g+7|0)&1|g<<1}else g=0;h=7616+(g<<2)|0;c[o+28>>2]=g;c[o+20>>2]=0;c[o+16>>2]=0;e=c[1829]|0;j=1<>2]=o;c[o+24>>2]=h;c[o+12>>2]=o;c[o+8>>2]=o;break}e=c[h>>2]|0;if((g|0)==31)d=0;else d=25-(g>>>1)|0;k:do if((c[e+4>>2]&-8|0)!=(k|0)){j=k<>>31<<2)+16|0;d=c[h>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(k|0)){G=d;break k}else{j=j<<1;e=d}}if(h>>>0<(c[1832]|0)>>>0)ka();else{c[h>>2]=o;c[o+24>>2]=e;c[o+12>>2]=o;c[o+8>>2]=o;break g}}else G=e;while(0);b=G+8|0;d=c[b>>2]|0;x=c[1832]|0;if(G>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=o;c[b>>2]=o;c[o+8>>2]=d;c[o+12>>2]=G;c[o+24>>2]=0;break}else ka()}}else{x=c[1832]|0;if((x|0)==0|w>>>0>>0)c[1832]=w;c[1940]=w;c[1941]=s;c[1943]=0;c[1837]=c[1946];c[1836]=-1;b=0;do{x=b<<1;v=7352+(x<<2)|0;c[7352+(x+3<<2)>>2]=v;c[7352+(x+2<<2)>>2]=v;b=b+1|0}while((b|0)!=32);b=w+8|0;if(!(b&7))b=0;else b=0-b&7;x=s+-40-b|0;c[1834]=w+b;c[1831]=x;c[w+(b+4)>>2]=x|1;c[w+(s+-36)>>2]=40;c[1835]=c[1950]}while(0);b=c[1831]|0;if(b>>>0>p>>>0){w=b-p|0;c[1831]=w;x=c[1834]|0;c[1834]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}}c[(va()|0)>>2]=12;x=0;i=L;return x|0}function kd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=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;w=i;if(!a){i=w;return}f=a+-8|0;h=c[1832]|0;if(f>>>0>>0)ka();g=c[a+-4>>2]|0;e=g&3;if((e|0)==1)ka();q=g&-8;r=a+(q+-8)|0;do if(!(g&1)){g=c[f>>2]|0;if(!e){i=w;return}j=-8-g|0;m=a+j|0;n=g+q|0;if(m>>>0>>0)ka();if((m|0)==(c[1833]|0)){f=a+(q+-4)|0;g=c[f>>2]|0;if((g&3|0)!=3){v=m;l=n;break}c[1830]=n;c[f>>2]=g&-2;c[a+(j+4)>>2]=n|1;c[r>>2]=n;i=w;return}d=g>>>3;if(g>>>0<256){e=c[a+(j+8)>>2]|0;f=c[a+(j+12)>>2]|0;g=7352+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0>>0)ka();if((c[e+12>>2]|0)!=(m|0))ka()}if((f|0)==(e|0)){c[1828]=c[1828]&~(1<>>0>>0)ka();g=f+8|0;if((c[g>>2]|0)==(m|0))b=g;else ka()}else b=f+8|0;c[e+12>>2]=f;c[b>>2]=e;v=m;l=n;break}b=c[a+(j+24)>>2]|0;e=c[a+(j+12)>>2]|0;do if((e|0)==(m|0)){f=a+(j+20)|0;g=c[f>>2]|0;if(!g){f=a+(j+16)|0;g=c[f>>2]|0;if(!g){k=0;break}}while(1){d=g+20|0;e=c[d>>2]|0;if(e){g=e;f=d;continue}d=g+16|0;e=c[d>>2]|0;if(!e)break;else{g=e;f=d}}if(f>>>0>>0)ka();else{c[f>>2]=0;k=g;break}}else{d=c[a+(j+8)>>2]|0;if(d>>>0>>0)ka();g=d+12|0;if((c[g>>2]|0)!=(m|0))ka();f=e+8|0;if((c[f>>2]|0)==(m|0)){c[g>>2]=e;c[f>>2]=d;k=e;break}else ka()}while(0);if(b){g=c[a+(j+28)>>2]|0;f=7616+(g<<2)|0;if((m|0)==(c[f>>2]|0)){c[f>>2]=k;if(!k){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();g=b+16|0;if((c[g>>2]|0)==(m|0))c[g>>2]=k;else c[b+20>>2]=k;if(!k){v=m;l=n;break}}f=c[1832]|0;if(k>>>0>>0)ka();c[k+24>>2]=b;g=c[a+(j+16)>>2]|0;do if(g)if(g>>>0>>0)ka();else{c[k+16>>2]=g;c[g+24>>2]=k;break}while(0);g=c[a+(j+20)>>2]|0;if(g)if(g>>>0<(c[1832]|0)>>>0)ka();else{c[k+20>>2]=g;c[g+24>>2]=k;v=m;l=n;break}else{v=m;l=n}}else{v=m;l=n}}else{v=f;l=q}while(0);if(v>>>0>=r>>>0)ka();g=a+(q+-4)|0;f=c[g>>2]|0;if(!(f&1))ka();if(!(f&2)){if((r|0)==(c[1834]|0)){m=(c[1831]|0)+l|0;c[1831]=m;c[1834]=v;c[v+4>>2]=m|1;if((v|0)!=(c[1833]|0)){i=w;return}c[1833]=0;c[1830]=0;i=w;return}if((r|0)==(c[1833]|0)){m=(c[1830]|0)+l|0;c[1830]=m;c[1833]=v;c[v+4>>2]=m|1;c[v+m>>2]=m;i=w;return}h=(f&-8)+l|0;d=f>>>3;do if(f>>>0>=256){b=c[a+(q+16)>>2]|0;g=c[a+(q|4)>>2]|0;do if((g|0)==(r|0)){f=a+(q+12)|0;g=c[f>>2]|0;if(!g){f=a+(q+8)|0;g=c[f>>2]|0;if(!g){p=0;break}}while(1){d=g+20|0;e=c[d>>2]|0;if(e){g=e;f=d;continue}d=g+16|0;e=c[d>>2]|0;if(!e)break;else{g=e;f=d}}if(f>>>0<(c[1832]|0)>>>0)ka();else{c[f>>2]=0;p=g;break}}else{f=c[a+q>>2]|0;if(f>>>0<(c[1832]|0)>>>0)ka();e=f+12|0;if((c[e>>2]|0)!=(r|0))ka();d=g+8|0;if((c[d>>2]|0)==(r|0)){c[e>>2]=g;c[d>>2]=f;p=g;break}else ka()}while(0);if(b){g=c[a+(q+20)>>2]|0;f=7616+(g<<2)|0;if((r|0)==(c[f>>2]|0)){c[f>>2]=p;if(!p){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();g=b+16|0;if((c[g>>2]|0)==(r|0))c[g>>2]=p;else c[b+20>>2]=p;if(!p)break}g=c[1832]|0;if(p>>>0>>0)ka();c[p+24>>2]=b;f=c[a+(q+8)>>2]|0;do if(f)if(f>>>0>>0)ka();else{c[p+16>>2]=f;c[f+24>>2]=p;break}while(0);d=c[a+(q+12)>>2]|0;if(d)if(d>>>0<(c[1832]|0)>>>0)ka();else{c[p+20>>2]=d;c[d+24>>2]=p;break}}}else{e=c[a+q>>2]|0;f=c[a+(q|4)>>2]|0;g=7352+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0<(c[1832]|0)>>>0)ka();if((c[e+12>>2]|0)!=(r|0))ka()}if((f|0)==(e|0)){c[1828]=c[1828]&~(1<>>0<(c[1832]|0)>>>0)ka();g=f+8|0;if((c[g>>2]|0)==(r|0))o=g;else ka()}else o=f+8|0;c[e+12>>2]=f;c[o>>2]=e}while(0);c[v+4>>2]=h|1;c[v+h>>2]=h;if((v|0)==(c[1833]|0)){c[1830]=h;i=w;return}else g=h}else{c[g>>2]=f&-2;c[v+4>>2]=l|1;c[v+l>>2]=l;g=l}e=g>>>3;if(g>>>0<256){f=e<<1;g=7352+(f<<2)|0;d=c[1828]|0;e=1<>2]|0;if(b>>>0<(c[1832]|0)>>>0)ka();else{s=d;t=b}}else{c[1828]=d|e;s=7352+(f+2<<2)|0;t=g}c[s>>2]=v;c[t+12>>2]=v;c[v+8>>2]=t;c[v+12>>2]=g;i=w;return}d=g>>>8;if(d)if(g>>>0>16777215)f=31;else{l=(d+1048320|0)>>>16&8;m=d<>>16&4;m=m<>>16&2;f=14-(k|l|f)+(m<>>15)|0;f=g>>>(f+7|0)&1|f<<1}else f=0;b=7616+(f<<2)|0;c[v+28>>2]=f;c[v+20>>2]=0;c[v+16>>2]=0;d=c[1829]|0;e=1<>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;b:do if((c[b+4>>2]&-8|0)!=(g|0)){f=g<>>31<<2)+16|0;d=c[e>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(g|0)){u=d;break b}else{f=f<<1;b=d}}if(e>>>0<(c[1832]|0)>>>0)ka();else{c[e>>2]=v;c[v+24>>2]=b;c[v+12>>2]=v;c[v+8>>2]=v;break a}}else u=b;while(0);d=u+8|0;b=c[d>>2]|0;m=c[1832]|0;if(u>>>0>=m>>>0&b>>>0>=m>>>0){c[b+12>>2]=v;c[d>>2]=v;c[v+8>>2]=b;c[v+12>>2]=u;c[v+24>>2]=0;break}else ka()}else{c[1829]=d|e;c[b>>2]=v;c[v+24>>2]=b;c[v+12>>2]=v;c[v+8>>2]=v}while(0);m=(c[1836]|0)+-1|0;c[1836]=m;if(!m)b=7768|0;else{i=w;return}while(1){b=c[b>>2]|0;if(!b)break;else b=b+8|0}c[1836]=-1;i=w;return}function ld(){}function md(b){b=b|0;var c=0;c=b;while(a[c>>0]|0)c=c+1|0;return c-b|0}function nd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;h=b&3;i=d|d<<8|d<<16|d<<24;g=f&~3;if(h){h=b+4-h|0;while((b|0)<(h|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(g|0)){c[b>>2]=i;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function od(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return pa(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function pd(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;xa[a&3](b|0,c|0,d|0,e|0,f|0)}function qd(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;_(0)} + +// EMSCRIPTEN_END_FUNCS +var xa=[qd,fc,ec,qd];return{_strlen:md,_free:kd,_broadwayGetMajorVersion:dd,_get_h264bsdClip:Lb,_broadwayExit:cd,_memset:nd,_broadwayCreateStream:Zc,_malloc:jd,_memcpy:od,_broadwayGetMinorVersion:ed,_broadwayPlayStream:$c,_broadwaySetStreamLength:_c,_broadwayInit:ad,runPostSets:ld,stackAlloc:ya,stackSave:za,stackRestore:Aa,setThrew:Ba,setTempRet0:Ea,getTempRet0:Fa,dynCall_viiiii:pd}}) + + +// EMSCRIPTEN_END_ASM +(p.Xc,p.Yc,Q),Bb=p._strlen=$._strlen,Ea=p._free=$._free;p._broadwayGetMajorVersion=$._broadwayGetMajorVersion;p._get_h264bsdClip=$._get_h264bsdClip;p._broadwayExit=$._broadwayExit;var Gb=p._memset=$._memset;p._broadwayCreateStream=$._broadwayCreateStream;var Ca=p._malloc=$._malloc,gc=p._memcpy=$._memcpy; +p._broadwayGetMinorVersion=$._broadwayGetMinorVersion;p._broadwayPlayStream=$._broadwayPlayStream;p._broadwaySetStreamLength=$._broadwaySetStreamLength;p._broadwayInit=$._broadwayInit;p.runPostSets=$.runPostSets;p.dynCall_viiiii=$.dynCall_viiiii;z.pb=$.stackAlloc;z.Tb=$.stackSave;z.Sb=$.stackRestore;z.Yd=$.setTempRet0;z.xd=$.getTempRet0; +if(T)if("function"===typeof p.locateFile?T=p.locateFile(T):p.memoryInitializerPrefixURL&&(T=p.memoryInitializerPrefixURL+T),t||da){var hc=p.readBinary(T);N.set(hc,Ia)}else Ya(),yb(T,function(a){N.set(a,Ia);Za()},function(){d("could not load memory initializer "+T)});function ia(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}ia.prototype=Error();var ic,jc=k,Xa=function kc(){!p.calledRun&&lc&&mc();p.calledRun||(Xa=kc)}; +p.callMain=p.ag=function(a){function b(){for(var a=0;3>a;a++)e.push(0)}w(0==S,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");w(0==Oa.length,"cannot call main when preRun functions remain to be called");a=a||[];Sa||(Sa=i,Na(R));var c=a.length+1,e=[M(Va(p.thisProgram),"i8",0)];b();for(var f=0;f y ? y : z); + } + + function OptimizedGetBoundaryStrengthsA($mb, $bS) { + var $totalCoeff = $mb + 28; + + var tc0 = HEAP16[$totalCoeff + 0 >> 1]; + var tc1 = HEAP16[$totalCoeff + 2 >> 1]; + var tc2 = HEAP16[$totalCoeff + 4 >> 1]; + var tc3 = HEAP16[$totalCoeff + 6 >> 1]; + var tc4 = HEAP16[$totalCoeff + 8 >> 1]; + var tc5 = HEAP16[$totalCoeff + 10 >> 1]; + var tc6 = HEAP16[$totalCoeff + 12 >> 1]; + var tc7 = HEAP16[$totalCoeff + 14 >> 1]; + var tc8 = HEAP16[$totalCoeff + 16 >> 1]; + var tc9 = HEAP16[$totalCoeff + 18 >> 1]; + var tc10 = HEAP16[$totalCoeff + 20 >> 1]; + var tc11 = HEAP16[$totalCoeff + 22 >> 1]; + var tc12 = HEAP16[$totalCoeff + 24 >> 1]; + var tc13 = HEAP16[$totalCoeff + 26 >> 1]; + var tc14 = HEAP16[$totalCoeff + 28 >> 1]; + var tc15 = HEAP16[$totalCoeff + 30 >> 1]; + + HEAP32[$bS + 32 >> 2] = tc2 || tc0 ? 2 : 0; + HEAP32[$bS + 40 >> 2] = tc3 || tc1 ? 2 : 0; + HEAP32[$bS + 48 >> 2] = tc6 || tc4 ? 2 : 0; + HEAP32[$bS + 56 >> 2] = tc7 || tc5 ? 2 : 0; + HEAP32[$bS + 64 >> 2] = tc8 || tc2 ? 2 : 0; + HEAP32[$bS + 72 >> 2] = tc9 || tc3 ? 2 : 0; + HEAP32[$bS + 80 >> 2] = tc12 || tc6 ? 2 : 0; + HEAP32[$bS + 88 >> 2] = tc13 || tc7 ? 2 : 0; + HEAP32[$bS + 96 >> 2] = tc10 || tc8 ? 2 : 0; + HEAP32[$bS + 104 >> 2] = tc11 || tc9 ? 2 : 0; + HEAP32[$bS + 112 >> 2] = tc14 || tc12 ? 2 : 0; + HEAP32[$bS + 120 >> 2] = tc15 || tc13 ? 2 : 0; + + HEAP32[$bS + 12 >> 2] = tc1 || tc0 ? 2 : 0; + HEAP32[$bS + 20 >> 2] = tc4 || tc1 ? 2 : 0; + HEAP32[$bS + 28 >> 2] = tc5 || tc4 ? 2 : 0; + HEAP32[$bS + 44 >> 2] = tc3 || tc2 ? 2 : 0; + HEAP32[$bS + 52 >> 2] = tc6 || tc3 ? 2 : 0; + HEAP32[$bS + 60 >> 2] = tc7 || tc6 ? 2 : 0; + HEAP32[$bS + 76 >> 2] = tc9 || tc8 ? 2 : 0; + HEAP32[$bS + 84 >> 2] = tc12 || tc9 ? 2 : 0; + HEAP32[$bS + 92 >> 2] = tc13 || tc12 ? 2 : 0; + HEAP32[$bS + 108 >> 2] = tc11 || tc10 ? 2 : 0; + HEAP32[$bS + 116 >> 2] = tc14 || tc11 ? 2 : 0; + HEAP32[$bS + 124 >> 2] = tc15 || tc14 ? 2 : 0; + } + + function OptimizedFilterVerLumaEdge ($data, bS, $thresholds, imageWidth) { + var delta, tc, tmp; + var p0, q0, p1, q1, p2, q2; + var tmpFlag; + var $clp = _h264bsdClip + 512; + var alpha = HEAP32[$thresholds + 4 >> 2]; + var beta = HEAP32[$thresholds + 8 >> 2]; + var val; + + if (bS < 4) { + tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255; + for (var i = 4; i > 0; i--) { + p1 = HEAPU8[$data + -2] & 255; + p0 = HEAPU8[$data + -1] & 255; + q0 = HEAPU8[$data] & 255; + q1 = HEAPU8[$data + 1] & 255; + if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) { + p2 = HEAPU8[$data - 3] & 255; + if (Math.abs(p2 - p0) < beta) { + val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; + HEAP8[$data - 2] = p1 + clip(-tc, tc, val); + tmp++; + } + + q2 = HEAPU8[$data + 2] & 255; + if (Math.abs(q2 - q0) < beta) { + val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; + HEAP8[$data + 1] = (q1 + clip(-tc, tc, val)); + tmp++; + } + + val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); + delta = clip(-tmp, tmp, val); + + p0 = HEAPU8[$clp + (p0 + delta)] & 255; + q0 = HEAPU8[$clp + (q0 - delta)] & 255; + tmp = tc; + HEAP8[$data - 1] = p0; + HEAP8[$data] = q0; + + $data += imageWidth; + } + } + } else { + OriginalFilterVerLumaEdge($data, bS, $thresholds, imageWidth); + } + } + + /** + * Filter all four successive horizontal 4-pixel luma edges. This can be done when bS is equal to all four edges. + */ + function OptimizedFilterHorLuma ($data, bS, $thresholds, imageWidth) { + var delta, tc, tmp; + var p0, q0, p1, q1, p2, q2; + var tmpFlag; + var $clp = _h264bsdClip + 512; + var alpha = HEAP32[$thresholds + 4 >> 2]; + var beta = HEAP32[$thresholds + 8 >> 2]; + var val; + + if (bS < 4) { + tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255; + for (var i = 16; i > 0; i--) { + p1 = HEAPU8[$data + (-imageWidth << 1)] & 255; + p0 = HEAPU8[$data + -imageWidth] & 255; + q0 = HEAPU8[$data] & 255; + q1 = HEAPU8[$data + imageWidth] & 255; + + if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) { + p2 = HEAPU8[$data + (-imageWidth * 3)] & 255; + if (Math.abs(p2 - p0) < beta) { + val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; + HEAP8[$data + (-imageWidth << 1)] = p1 + clip(-tc, tc, val); + tmp++; + } + + q2 = HEAPU8[$data + (imageWidth << 2)] & 255; + if (Math.abs(q2 - q0) < beta) { + val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; + HEAP8[$data + imageWidth] = (q1 + clip(-tc, tc, val)); + tmp++; + } + + val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); + delta = clip(-tmp, tmp, val); + + p0 = HEAPU8[$clp + (p0 + delta)] & 255; + q0 = HEAPU8[$clp + (q0 - delta)] & 255; + tmp = tc; + HEAP8[$data - imageWidth] = p0; + HEAP8[$data] = q0; + + $data ++; + } + } + } else { + OriginalFilterHorLuma($data, bS, $thresholds, imageWidth); + } + } + }; + + + Broadway.prototype = { + configure: function (config) { + // patchOptimizations(config, patches); + console.info("Broadway Configured: " + JSON.stringify(config)); + } + + }; + + + + + /* + + asm.js implementation of a yuv to rgb convertor + provided by @soliton4 + + based on + http://www.wordsaretoys.com/2013/10/18/making-yuv-conversion-a-little-faster/ + + */ + + + // factory to create asm.js yuv -> rgb convertor for a given resolution + var asmInstances = {}; + var getAsm = function(parWidth, parHeight){ + var idStr = "" + parWidth + "x" + parHeight; + if (asmInstances[idStr]){ + return asmInstances[idStr]; + }; + + var lumaSize = parWidth * parHeight; + var chromaSize = (lumaSize|0) >> 2; + + var inpSize = lumaSize + chromaSize + chromaSize; + var outSize = parWidth * parHeight * 4; + var cacheSize = Math.pow(2, 24) * 4; + var size = inpSize + outSize + cacheSize; + + var chunkSize = Math.pow(2, 24); + var heapSize = chunkSize; + while (heapSize < size){ + heapSize += chunkSize; + }; + var heap = new ArrayBuffer(heapSize); + + var res = asmFactory(global, {}, heap); + res.init(parWidth, parHeight); + asmInstances[idStr] = res; + + res.heap = heap; + res.out = new Uint8Array(heap, 0, outSize); + res.inp = new Uint8Array(heap, outSize, inpSize); + res.outSize = outSize; + + return res; + }; + + + function asmFactory(stdlib, foreign, heap) { + "use asm"; + + var imul = stdlib.Math.imul; + var min = stdlib.Math.min; + var max = stdlib.Math.max; + var pow = stdlib.Math.pow; + var out = new stdlib.Uint8Array(heap); + var out32 = new stdlib.Uint32Array(heap); + var inp = new stdlib.Uint8Array(heap); + var mem = new stdlib.Uint8Array(heap); + var mem32 = new stdlib.Uint32Array(heap); + + // for double algo + /*var vt = 1.370705; + var gt = 0.698001; + var gt2 = 0.337633; + var bt = 1.732446;*/ + + var width = 0; + var height = 0; + var lumaSize = 0; + var chromaSize = 0; + var inpSize = 0; + var outSize = 0; + + var inpStart = 0; + var outStart = 0; + + var widthFour = 0; + + var cacheStart = 0; + + + function init(parWidth, parHeight){ + parWidth = parWidth|0; + parHeight = parHeight|0; + + var i = 0; + var s = 0; + + width = parWidth; + widthFour = imul(parWidth, 4)|0; + height = parHeight; + lumaSize = imul(width|0, height|0)|0; + chromaSize = (lumaSize|0) >> 2; + outSize = imul(imul(width, height)|0, 4)|0; + inpSize = ((lumaSize + chromaSize)|0 + chromaSize)|0; + + outStart = 0; + inpStart = (outStart + outSize)|0; + cacheStart = (inpStart + inpSize)|0; + + // initializing memory (to be on the safe side) + s = ~~(+pow(+2, +24)); + s = imul(s, 4)|0; + + for (i = 0|0; ((i|0) < (s|0))|0; i = (i + 4)|0){ + mem32[((cacheStart + i)|0) >> 2] = 0; + }; + }; + + function doit(){ + var ystart = 0; + var ustart = 0; + var vstart = 0; + + var y = 0; + var yn = 0; + var u = 0; + var v = 0; + + var o = 0; + + var line = 0; + var col = 0; + + var usave = 0; + var vsave = 0; + + var ostart = 0; + var cacheAdr = 0; + + ostart = outStart|0; + + ystart = inpStart|0; + ustart = (ystart + lumaSize|0)|0; + vstart = (ustart + chromaSize)|0; + + for (line = 0; (line|0) < (height|0); line = (line + 2)|0){ + usave = ustart; + vsave = vstart; + for (col = 0; (col|0) < (width|0); col = (col + 2)|0){ + y = inp[ystart >> 0]|0; + yn = inp[((ystart + width)|0) >> 0]|0; + + u = inp[ustart >> 0]|0; + v = inp[vstart >> 0]|0; + + cacheAdr = (((((y << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(y,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[ostart >> 2] = o; + + cacheAdr = (((((yn << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(yn,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[((ostart + widthFour)|0) >> 2] = o; + + //yuv2rgb5(y, u, v, ostart); + //yuv2rgb5(yn, u, v, (ostart + widthFour)|0); + ostart = (ostart + 4)|0; + + // next step only for y. u and v stay the same + ystart = (ystart + 1)|0; + y = inp[ystart >> 0]|0; + yn = inp[((ystart + width)|0) >> 0]|0; + + //yuv2rgb5(y, u, v, ostart); + cacheAdr = (((((y << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(y,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[ostart >> 2] = o; + + //yuv2rgb5(yn, u, v, (ostart + widthFour)|0); + cacheAdr = (((((yn << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(yn,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[((ostart + widthFour)|0) >> 2] = o; + ostart = (ostart + 4)|0; + + //all positions inc 1 + + ystart = (ystart + 1)|0; + ustart = (ustart + 1)|0; + vstart = (vstart + 1)|0; + }; + ostart = (ostart + widthFour)|0; + ystart = (ystart + width)|0; + + }; + + }; + + function yuv2rgbcalc(y, u, v){ + y = y|0; + u = u|0; + v = v|0; + + var r = 0; + var g = 0; + var b = 0; + + var o = 0; + + var a0 = 0; + var a1 = 0; + var a2 = 0; + var a3 = 0; + var a4 = 0; + + a0 = imul(1192, (y - 16)|0)|0; + a1 = imul(1634, (v - 128)|0)|0; + a2 = imul(832, (v - 128)|0)|0; + a3 = imul(400, (u - 128)|0)|0; + a4 = imul(2066, (u - 128)|0)|0; + + r = (((a0 + a1)|0) >> 10)|0; + g = (((((a0 - a2)|0) - a3)|0) >> 10)|0; + b = (((a0 + a4)|0) >> 10)|0; + + if ((((r & 255)|0) != (r|0))|0){ + r = min(255, max(0, r|0)|0)|0; + }; + if ((((g & 255)|0) != (g|0))|0){ + g = min(255, max(0, g|0)|0)|0; + }; + if ((((b & 255)|0) != (b|0))|0){ + b = min(255, max(0, b|0)|0)|0; + }; + + o = 255; + o = (o << 8)|0; + o = (o + b)|0; + o = (o << 8)|0; + o = (o + g)|0; + o = (o << 8)|0; + o = (o + r)|0; + + return o|0; + + }; + + + + return { + init: init, + doit: doit + }; + }; + + + /* + potential worker initialization + + */ + + + if (typeof self != "undefined"){ + var isWorker = false; + var decoder; + var reuseMemory = false; + + var memAr = []; + var getMem = function(length){ + if (memAr.length){ + var u = memAr.shift(); + while (u && u.byteLength !== length){ + u = memAr.shift(); + }; + if (u){ + return u; + }; + }; + return new ArrayBuffer(length); + }; + + self.addEventListener('message', function(e) { + + if (isWorker){ + if (reuseMemory){ + if (e.data.reuse){ + memAr.push(e.data.reuse); + }; + }; + if (e.data.buf){ + decoder.decode(new Uint8Array(e.data.buf, e.data.offset || 0, e.data.length), e.data.info); + }; + + }else{ + if (e.data && e.data.type === "Broadway.js - Worker init"){ + isWorker = true; + decoder = new Broadway(e.data.options); + + if (e.data.options.reuseMemory){ + reuseMemory = true; + decoder.onPictureDecoded = function (buffer, width, height, infos) { + + //var buf = getMem(); + + // buffer needs to be copied because we give up ownership + var copyU8 = new Uint8Array(getMem(buffer.length)); + copyU8.set( buffer, 0, buffer.length ); + + postMessage({ + buf: copyU8.buffer, + length: buffer.length, + width: width, + height: height, + infos: infos + }, [copyU8.buffer]); // 2nd parameter is used to indicate transfer of ownership + + }; + + }else{ + decoder.onPictureDecoded = function (buffer, width, height, infos) { + if (buffer) { + buffer = new Uint8Array(buffer); + }; + + // buffer needs to be copied because we give up ownership + var copyU8 = new Uint8Array(buffer.length); + copyU8.set( buffer, 0, buffer.length ); + + postMessage({ + buf: copyU8.buffer, + length: buffer.length, + width: width, + height: height, + infos: infos + }, [copyU8.buffer]); // 2nd parameter is used to indicate transfer of ownership + + }; + }; + postMessage({ consoleLog: "broadway worker initialized" }); + }; + }; + + + }, false); + }; + + Broadway.nowValue = nowValue; + + return Broadway; + + })(); + + +})); + diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/FilterWebGLCanvas.js b/tools/ffmpegToWeb/Player/broadway/canvas/FilterWebGLCanvas.js new file mode 100644 index 0000000..a8e380e --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/FilterWebGLCanvas.js @@ -0,0 +1,71 @@ +"use strict"; + +var Class = require('uclass'); + + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", [ + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D FTexture; + + void main(void) { + gl_FragColor = texture2D(FTexture, vTextureCoord); + } +`); + + +var FilterWebGLCanvas = new Class({ + Extends : WebGLCanvas, + + initialize : function(canvas, size, useFrameBuffer) { + FilterWebGLCanvas.parent.initialize.call(this, canvas, size, useFrameBuffer); + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord"); + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + console.log("creatingTextures: size: " + this.size); + this.FTexture = new Texture(this.gl, this.size, this.gl.RGBA); + }, + + onInitSceneTextures: function () { + this.FTexture.bind(0, this.program, "FTexture"); + }, + + process: function(buffer, output) { + this.FTexture.fill(buffer); + this.drawScene(); + this.readPixels(output); + }, + + toString: function() { + return "FilterWebGLCanvas Size: " + this.size; + } +}); + + + +module.exports = FilterWebGLCanvas; + diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/Program.js b/tools/ffmpegToWeb/Player/broadway/canvas/Program.js new file mode 100644 index 0000000..374d315 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/Program.js @@ -0,0 +1,32 @@ +"use strict"; +var assert = require('../utils/assert'); + + +function Program(gl) { + this.gl = gl; + this.program = this.gl.createProgram(); +} + +Program.prototype = { + attach: function (shader) { + this.gl.attachShader(this.program, shader.shader); + }, + link: function () { + this.gl.linkProgram(this.program); + // If creating the shader program failed, alert. + assert(this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS), + "Unable to initialize the shader program."); + }, + use: function () { + this.gl.useProgram(this.program); + }, + getAttributeLocation: function(name) { + return this.gl.getAttribLocation(this.program, name); + }, + setMatrixUniform: function(name, array) { + var uniform = this.gl.getUniformLocation(this.program, name); + this.gl.uniformMatrix4fv(uniform, false, array); + } +}; +module.exports = Program; + diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/README.md b/tools/ffmpegToWeb/Player/broadway/canvas/README.md new file mode 100644 index 0000000..dbb6e85 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/README.md @@ -0,0 +1,4 @@ +/* +* Those files wraps several WebGL constructs and provides a simple, single texture based WebGLCanvas as well as a +* specialized YUVWebGLCanvas that can handle YUV->RGB conversion. +*/ diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/Script.js b/tools/ffmpegToWeb/Player/broadway/canvas/Script.js new file mode 100644 index 0000000..d93416b --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/Script.js @@ -0,0 +1,41 @@ +"use strict"; + +var assert = require('../utils/assert'); + +/** + * Represents a WebGL shader script. + */ + +function Script() {} + +Script.createFromElementId = function(id) { + var script = document.getElementById(id); + + // Didn't find an element with the specified ID, abort. + assert(script , "Could not find shader with ID: " + id); + + // Walk through the source element's children, building the shader source string. + var source = ""; + var currentChild = script .firstChild; + while(currentChild) { + if (currentChild.nodeType == 3) { + source += currentChild.textContent; + } + currentChild = currentChild.nextSibling; + } + + var res = new Scriptor(); + res.type = script.type; + res.source = source; + return res; +}; + +Script.createFromSource = function(type, source) { + var res = new Script(); + res.type = type; + res.source = source; + return res; +} + + +module.exports = Script; \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/Shader.js b/tools/ffmpegToWeb/Player/broadway/canvas/Shader.js new file mode 100644 index 0000000..fecfdfe --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/Shader.js @@ -0,0 +1,38 @@ +"use strict"; + +var error = require('../utils/error'); + +/** + * Represents a WebGL shader object and provides a mechanism to load shaders from HTML + * script tags. + */ + + +function Shader(gl, script) { + + // Now figure out what type of shader script we have, based on its MIME type. + if (script.type == "x-shader/x-fragment") { + this.shader = gl.createShader(gl.FRAGMENT_SHADER); + } else if (script.type == "x-shader/x-vertex") { + this.shader = gl.createShader(gl.VERTEX_SHADER); + } else { + error("Unknown shader type: " + script.type); + return; + } + + // Send the source to the shader object. + gl.shaderSource(this.shader, script.source); + + // Compile the shader program. + gl.compileShader(this.shader); + + // See if it compiled successfully. + if (!gl.getShaderParameter(this.shader, gl.COMPILE_STATUS)) { + error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(this.shader)); + return; + } +} +module.exports = Shader; + + + diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/Texture.js b/tools/ffmpegToWeb/Player/broadway/canvas/Texture.js new file mode 100644 index 0000000..30becff --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/Texture.js @@ -0,0 +1,47 @@ +"use strict"; + +var assert = require('../utils/assert'); + +/** + * Represents a WebGL texture object. + */ + +function Texture(gl, size, format) { + this.gl = gl; + this.size = size; + this.texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + this.format = format ? format : gl.LUMINANCE; + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, size.w, size.h, 0, this.format, gl.UNSIGNED_BYTE, null); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); +} + +var textureIDs = null; +Texture.prototype = { + fill: function(textureData, useTexSubImage2D) { + var gl = this.gl; + assert(textureData.length >= this.size.w * this.size.h, + "Texture size mismatch, data:" + textureData.length + ", texture: " + this.size.w * this.size.h); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + if (useTexSubImage2D) { + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.size.w , this.size.h, this.format, gl.UNSIGNED_BYTE, textureData); + } else { + // texImage2D seems to be faster, thus keeping it as the default + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.size.w, this.size.h, 0, this.format, gl.UNSIGNED_BYTE, textureData); + } + }, + bind: function(n, program, name) { + var gl = this.gl; + if (!textureIDs) { + textureIDs = [gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2]; + } + gl.activeTexture(textureIDs[n]); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.uniform1i(gl.getUniformLocation(program.program, name), n); + } +}; +module.exports = Texture; + diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/WebGLCanvas.js b/tools/ffmpegToWeb/Player/broadway/canvas/WebGLCanvas.js new file mode 100644 index 0000000..65f7210 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/WebGLCanvas.js @@ -0,0 +1,261 @@ +"use strict"; + +/** + * Generic WebGL backed canvas that sets up: a quad to paint a texture on, appropriate vertex/fragment shaders, + * scene parameters and other things. Specialized versions of this class can be created by overriding several + * initialization methods. + + */ + +var Script = require('./Script'); +var error = require('../utils/error'); +var makePerspective = require('../utils/glUtils').makePerspective; +var Matrix = require('sylvester.js').Matrix; +var Class = require('uclass'); + + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", ` + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D texture; + void main(void) { + gl_FragColor = texture2D(texture, vTextureCoord); + } +`); + +var WebGLCanvas = new Class({ + + initialize : function(canvas, size, useFrameBuffer) { + + this.canvas = canvas; + this.size = size; + this.canvas.width = size.w; + this.canvas.height = size.h; + + this.onInitWebGL(); + this.onInitShaders(); + this.initBuffers(); + + if (useFrameBuffer) + this.initFramebuffer(); + + this.onInitTextures(); + this.initScene(); + }, + + +/** + * Initialize a frame buffer so that we can render off-screen. + */ + initFramebuffer : function() { + + var gl = this.gl; + + // Create framebuffer object and texture. + this.framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + this.framebufferTexture = new Texture(this.gl, this.size, gl.RGBA); + + // Create and allocate renderbuffer for depth data. + var renderbuffer = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.size.w, this.size.h); + + // Attach texture and renderbuffer to the framebuffer. + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.framebufferTexture.texture, 0); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer); + }, + + + +/** + * Initialize vertex and texture coordinate buffers for a plane. + */ + initBuffers : function () { + var tmp; + var gl = this.gl; + + // Create vertex position buffer. + this.quadVPBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer); + tmp = [ + 1.0, 1.0, 0.0, + -1.0, 1.0, 0.0, + 1.0, -1.0, 0.0, + -1.0, -1.0, 0.0]; + + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW); + this.quadVPBuffer.itemSize = 3; + this.quadVPBuffer.numItems = 4; + + /* + +--------------------+ + | -1,1 (1) | 1,1 (0) + | | + | | + | | + | | + | | + | -1,-1 (3) | 1,-1 (2) + +--------------------+ + */ + + var scaleX = 1.0; + var scaleY = 1.0; + + // Create vertex texture coordinate buffer. + this.quadVTCBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer); + tmp = [ + scaleX, 0.0, + 0.0, 0.0, + scaleX, scaleY, + 0.0, scaleY, + ]; + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW); + }, + + + mvIdentity : function () { + this.mvMatrix = Matrix.I(4); + }, + + mvMultiply : function(m) { + this.mvMatrix = this.mvMatrix.x(m); + }, + + mvTranslate : function (m) { + this.mvMultiply(Matrix.Translation($V([m[0], m[1], m[2]])).ensure4x4()); + }, + + setMatrixUniforms : function () { + this.program.setMatrixUniform("uPMatrix", new Float32Array(this.perspectiveMatrix.flatten())); + this.program.setMatrixUniform("uMVMatrix", new Float32Array(this.mvMatrix.flatten())); + }, + + initScene : function() { + var gl = this.gl; + + // Establish the perspective with which we want to view the + // scene. Our field of view is 45 degrees, with a width/height + // ratio of 640:480, and we only want to see objects between 0.1 units + // and 100 units away from the camera. + + this.perspectiveMatrix = makePerspective(45, 1, 0.1, 100.0); + + // Set the drawing position to the "identity" point, which is + // the center of the scene. + this.mvIdentity(); + + // Now move the drawing position a bit to where we want to start + // drawing the square. + this.mvTranslate([0.0, 0.0, -2.4]); + + // Draw the cube by binding the array buffer to the cube's vertices + // array, setting attributes, and pushing it to GL. + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer); + gl.vertexAttribPointer(this.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); + + // Set the texture coordinates attribute for the vertices. + + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer); + gl.vertexAttribPointer(this.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + + this.onInitSceneTextures(); + + this.setMatrixUniforms(); + + if (this.framebuffer) { + console.log("Bound Frame Buffer"); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + } + }, + + + + toString: function() { + return "WebGLCanvas Size: " + this.size; + }, + + checkLastError: function (operation) { + var err = this.gl.getError(); + if (err != this.gl.NO_ERROR) { + var name = this.glNames[err]; + name = (name !== undefined) ? name + "(" + err + ")": + ("Unknown WebGL ENUM (0x" + value.toString(16) + ")"); + if (operation) { + console.log("WebGL Error: %s, %s", operation, name); + } else { + console.log("WebGL Error: %s", name); + } + console.trace(); + } + }, + + onInitWebGL: function () { + try { + this.gl = this.canvas.getContext("experimental-webgl"); + } catch(e) {} + + if (!this.gl) { + error("Unable to initialize WebGL. Your browser may not support it."); + } + if (this.glNames) { + return; + } + this.glNames = {}; + for (var propertyName in this.gl) { + if (typeof this.gl[propertyName] == 'number') { + this.glNames[this.gl[propertyName]] = propertyName; + } + } + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");; + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + var gl = this.gl; + this.texture = new Texture(gl, this.size, gl.RGBA); + }, + + onInitSceneTextures: function () { + this.texture.bind(0, this.program, "texture"); + }, + + drawScene: function() { + this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); + }, + + readPixels: function(buffer) { + var gl = this.gl; + gl.readPixels(0, 0, this.size.w, this.size.h, gl.RGBA, gl.UNSIGNED_BYTE, buffer); + }, + + +}); + + + +module.exports = WebGLCanvas; diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/YUVCanvas.js b/tools/ffmpegToWeb/Player/broadway/canvas/YUVCanvas.js new file mode 100644 index 0000000..326135f --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/YUVCanvas.js @@ -0,0 +1,51 @@ +"use strict"; +var Class = require('uclass'); + +var YUVCanvas = new Class({ + + Binds : ['decode'], + + initialize : function(canvas, size) { + this.canvas = canvas; + this.canvasCtx = this.canvas.getContext("2d"); + this.canvasBuffer = this.canvasCtx.createImageData(size.w, size.h); + }, + + decode : function (buffer, width, height) { + if (!buffer) + return; + + var lumaSize = width * height; + var chromaSize = lumaSize >> 2; + + var ybuf = buffer.subarray(0, lumaSize); + var ubuf = buffer.subarray(lumaSize, lumaSize + chromaSize); + var vbuf = buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize); + + for (var y = 0; y < height; y++) { + for (var x = 0; x < width; x++) { + var yIndex = x + y * width; + var uIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2); + var vIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2); + var R = 1.164 * (ybuf[yIndex] - 16) + 1.596 * (vbuf[vIndex] - 128); + var G = 1.164 * (ybuf[yIndex] - 16) - 0.813 * (vbuf[vIndex] - 128) - 0.391 * (ubuf[uIndex] - 128); + var B = 1.164 * (ybuf[yIndex] - 16) + 2.018 * (ubuf[uIndex] - 128); + + var rgbIndex = yIndex * 4; + this.canvasBuffer.data[rgbIndex+0] = R; + this.canvasBuffer.data[rgbIndex+1] = G; + this.canvasBuffer.data[rgbIndex+2] = B; + this.canvasBuffer.data[rgbIndex+3] = 0xff; + } + } + + this.canvasCtx.putImageData(this.canvasBuffer, 0, 0); + + var date = new Date(); + //console.log("WSAvcPlayer: Decode time: " + (date.getTime() - this.rcvtime) + " ms"); + }, + +}); + + +module.exports = YUVCanvas; \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/YUVWebGLCanvas.js b/tools/ffmpegToWeb/Player/broadway/canvas/YUVWebGLCanvas.js new file mode 100644 index 0000000..0280670 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/YUVWebGLCanvas.js @@ -0,0 +1,108 @@ +"use strict"; + +var Program = require('./Program'); +var Shader = require('./Shader'); +var Texture = require('./Texture'); +var Script = require('./Script'); +var WebGLCanvas = require('./WebGLCanvas'); + +var Class = require('uclass'); + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", ` + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D YTexture; + uniform sampler2D UTexture; + uniform sampler2D VTexture; + const mat4 YUV2RGB = mat4 + ( + 1.1643828125, 0, 1.59602734375, -.87078515625, + 1.1643828125, -.39176171875, -.81296875, .52959375, + 1.1643828125, 2.017234375, 0, -1.081390625, + 0, 0, 0, 1 + ); + + void main(void) { + gl_FragColor = vec4( texture2D(YTexture, vTextureCoord).x, texture2D(UTexture, vTextureCoord).x, texture2D(VTexture, vTextureCoord).x, 1) * YUV2RGB; + } +`); + + + + +var YUVWebGLCanvas = new Class({ + Extends : WebGLCanvas, + Binds : ['decode'], + + initialize : function(canvas, size) { + YUVWebGLCanvas.parent.initialize.call(this, canvas, size); + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");; + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + console.log("creatingTextures: size: " + this.size); + this.YTexture = new Texture(this.gl, this.size); + this.UTexture = new Texture(this.gl, this.size.getHalfSize()); + this.VTexture = new Texture(this.gl, this.size.getHalfSize()); + }, + + onInitSceneTextures: function () { + this.YTexture.bind(0, this.program, "YTexture"); + this.UTexture.bind(1, this.program, "UTexture"); + this.VTexture.bind(2, this.program, "VTexture"); + }, + + fillYUVTextures: function(y, u, v) { + this.YTexture.fill(y); + this.UTexture.fill(u); + this.VTexture.fill(v); + }, + + decode: function(buffer, width, height) { + + if (!buffer) + return; + + var lumaSize = width * height; + var chromaSize = lumaSize >> 2; + + this.YTexture.fill(buffer.subarray(0, lumaSize)); + this.UTexture.fill(buffer.subarray(lumaSize, lumaSize + chromaSize)); + this.VTexture.fill(buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize)); + this.drawScene(); + }, + + toString: function() { + return "YUVCanvas Size: " + this.size; + } +}); + + + + + +module.exports = YUVWebGLCanvas; diff --git a/tools/ffmpegToWeb/Player/broadway/dist/http-live-player.js b/tools/ffmpegToWeb/Player/broadway/dist/http-live-player.js new file mode 100644 index 0000000..f8b3e31 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/dist/http-live-player.js @@ -0,0 +1,5214 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.WSAvcPlayer = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +function useColors() { + // is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + return (typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style) || + // is firebug? http://stackoverflow.com/a/398120/376773 + (window.console && (console.firebug || (console.exception && console.table))) || + // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); +} + +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +exports.formatters.j = function(v) { + return JSON.stringify(v); +}; + + +/** + * Colorize log arguments if enabled. + * + * @api public + */ + +function formatArgs() { + var args = arguments; + var useColors = this.useColors; + + args[0] = (useColors ? '%c' : '') + + this.namespace + + (useColors ? ' %c' : ' ') + + args[0] + + (useColors ? '%c ' : ' ') + + '+' + exports.humanize(this.diff); + + if (!useColors) return args; + + var c = 'color: ' + this.color; + args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); + + // the final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + var index = 0; + var lastC = 0; + args[0].replace(/%[a-z%]/g, function(match) { + if ('%%' === match) return; + index++; + if ('%c' === match) { + // we only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + + args.splice(lastC, 0, c); + return args; +} + +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". + * + * @api public + */ + +function log() { + // this hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return 'object' === typeof console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + +function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch(e) {} +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + var r; + try { + r = exports.storage.debug; + } catch(e) {} + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if ('env' in (typeof process === 'undefined' ? {} : process)) { + r = process.env.DEBUG; + } + + return r; +} + +/** + * Enable namespaces listed in `localStorage.debug` initially. + */ + +exports.enable(load()); + +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + +function localstorage(){ + try { + return window.localStorage; + } catch (e) {} +} + +},{"./debug":2}],2:[function(require,module,exports){ + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = debug.debug = debug; +exports.coerce = coerce; +exports.disable = disable; +exports.enable = enable; +exports.enabled = enabled; +exports.humanize = require('ms'); + +/** + * The currently active debug mode names, and names to skip. + */ + +exports.names = []; +exports.skips = []; + +/** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lowercased letter, i.e. "n". + */ + +exports.formatters = {}; + +/** + * Previously assigned color. + */ + +var prevColor = 0; + +/** + * Previous log timestamp. + */ + +var prevTime; + +/** + * Select a color. + * + * @return {Number} + * @api private + */ + +function selectColor() { + return exports.colors[prevColor++ % exports.colors.length]; +} + +/** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + +function debug(namespace) { + + // define the `disabled` version + function disabled() { + } + disabled.enabled = false; + + // define the `enabled` version + function enabled() { + + var self = enabled; + + // set `diff` timestamp + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + + // add the `color` if not set + if (null == self.useColors) self.useColors = exports.useColors(); + if (null == self.color && self.useColors) self.color = selectColor(); + + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + + args[0] = exports.coerce(args[0]); + + if ('string' !== typeof args[0]) { + // anything else let's inspect with %o + args = ['%o'].concat(args); + } + + // apply any `formatters` transformations + var index = 0; + args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { + // if we encounter an escaped % then don't increase the array index + if (match === '%%') return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); + + // now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + // apply env-specific formatting + args = exports.formatArgs.apply(self, args); + + var logFn = enabled.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } + enabled.enabled = true; + + var fn = exports.enabled(namespace) ? enabled : disabled; + + fn.namespace = namespace; + + return fn; +} + +/** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + +function enable(namespaces) { + exports.save(namespaces); + + var split = (namespaces || '').split(/[\s,]+/); + var len = split.length; + + for (var i = 0; i < len; i++) { + if (!split[i]) continue; // ignore empty strings + namespaces = split[i].replace(/[\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } + } +} + +/** + * Disable debug output. + * + * @api public + */ + +function disable() { + exports.enable(''); +} + +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + +function enabled(name) { + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; +} + +/** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} + +},{"ms":3}],3:[function(require,module,exports){ +/** + * Helpers. + */ + +var s = 1000 +var m = s * 60 +var h = m * 60 +var d = h * 24 +var y = d * 365.25 + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} options + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ + +module.exports = function (val, options) { + options = options || {} + var type = typeof val + if (type === 'string' && val.length > 0) { + return parse(val) + } else if (type === 'number' && isNaN(val) === false) { + return options.long ? + fmtLong(val) : + fmtShort(val) + } + throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val)) +} + +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function parse(str) { + str = String(str) + if (str.length > 10000) { + return + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str) + if (!match) { + return + } + var n = parseFloat(match[1]) + var type = (match[2] || 'ms').toLowerCase() + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y + case 'days': + case 'day': + case 'd': + return n * d + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n + default: + return undefined + } +} + +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd' + } + if (ms >= h) { + return Math.round(ms / h) + 'h' + } + if (ms >= m) { + return Math.round(ms / m) + 'm' + } + if (ms >= s) { + return Math.round(ms / s) + 's' + } + return ms + 'ms' +} + +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtLong(ms) { + return plural(ms, d, 'day') || + plural(ms, h, 'hour') || + plural(ms, m, 'minute') || + plural(ms, s, 'second') || + ms + ' ms' +} + +/** + * Pluralization helper. + */ + +function plural(ms, n, name) { + if (ms < n) { + return + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name + } + return Math.ceil(ms / n) + ' ' + name + 's' +} + +},{}],4:[function(require,module,exports){ +(function (__dirname){ +// universal module definition +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], factory); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.Decoder = factory(); + } +}(this, function () { + + var global; + + function initglobal(){ + global = this; + if (!global){ + if (typeof window != "undefined"){ + global = window; + }else if (typeof self != "undefined"){ + global = self; + }; + }; + }; + initglobal(); + + + function error(message) { + console.error(message); + console.trace(); + }; + + + function assert(condition, message) { + if (!condition) { + error(message); + }; + }; + + + return (function(){ + "use strict"; + + + + + var getModule = function(_broadwayOnHeadersDecoded, _broadwayOnPictureDecoded){ + + var window = this; + //console.log(typeof window); + + window._broadwayOnHeadersDecoded = _broadwayOnHeadersDecoded; + window._broadwayOnPictureDecoded = _broadwayOnPictureDecoded; + + var Module = { + 'print': function(text) { console.log('stdout: ' + text); }, + 'printErr': function(text) { console.log('stderr: ' + text); } + }; + + + /* + + The reason why this is all packed into one file is that this file can also function as worker. + you can integrate the file into your build system and provide the original file to be loaded into a worker. + + */ + +function d(a){throw a;}var g=void 0,i=!0,k=null,m=!1;function n(){return function(){}}var p;p||(p=eval("(function() { try { return Module || {} } catch(e) { return {} } })()"));var aa={},r;for(r in p)p.hasOwnProperty(r)&&(aa[r]=p[r]);var t="object"===typeof process&&"function"===typeof null,ba="object"===typeof window,ca="function"===typeof importScripts,da=!ba&&!t&&!ca; +if(t){p.print||(p.print=function(a){process.stdout.write(a+"\n")});p.printErr||(p.printErr=function(a){process.stderr.write(a+"\n")});var fa=(null)("fs"),ga=(null)("path");p.read=function(a,b){var a=ga.normalize(a),c=fa.readFileSync(a);!c&&a!=ga.resolve(a)&&(a=path.join(__dirname,"..","src",a),c=fa.readFileSync(a));c&&!b&&(c=c.toString());return c};p.readBinary=function(a){return p.read(a,i)};p.load=function(a){ha(read(a))};p.thisProgram=1 0) var gc = undefined")):ba||ca?(p.read=function(a){var b=new XMLHttpRequest;b.open("GET",a,m);b.send(k);return b.responseText},"undefined"!=typeof arguments&&(p.arguments=arguments),"undefined"!==typeof console?(p.print||(p.print=function(a){console.log(a)}),p.printErr||(p.printErr=function(a){console.log(a)})):p.print||(p.print= +n()),ba?window.Module=p:p.load=importScripts):d("Unknown runtime environment. Where are we?");function ha(a){eval.call(k,a)}!p.load&&p.read&&(p.load=function(a){ha(p.read(a))});p.print||(p.print=n());p.printErr||(p.printErr=p.print);p.arguments||(p.arguments=[]);p.thisProgram||(p.thisProgram="./this.program");p.print=p.print;p.fa=p.printErr;p.preRun=[];p.postRun=[];for(r in aa)aa.hasOwnProperty(r)&&(p[r]=aa[r]); +var z={Yd:function(a){ja=a},xd:function(){return ja},Tb:function(){return y},Sb:function(a){y=a},oc:function(a){switch(a){case "i1":case "i8":return 1;case "i16":return 2;case "i32":return 4;case "i64":return 8;case "float":return 4;case "double":return 8;default:return"*"===a[a.length-1]?z.ia:"i"===a[0]?(a=parseInt(a.substr(1)),w(0===a%8),a/8):0}},vd:function(a){return Math.max(z.oc(a),z.ia)},Qf:16,ng:function(a,b,c){return!c&&("i64"==a||"double"==a)?8:!a?Math.min(b,8):Math.min(b||(a?z.vd(a):0), +z.ia)},Fa:function(a,b,c){return c&&c.length?(c.splice||(c=Array.prototype.slice.call(c)),c.splice(0,0,b),p["dynCall_"+a].apply(k,c)):p["dynCall_"+a].call(k,b)},eb:[],Vc:function(a){for(var b=0;b=F&&A("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+F+", (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.");return b},ub:function(a,b){return Math.ceil(a/(b?b:16))*(b?b:16)},Fg:function(a,b,c){return c?+(a>>>0)+4294967296*+(b>>>0):+(a>>>0)+4294967296* ++(b|0)},Pc:8,ia:4,Rf:0};p.Runtime=z;z.addFunction=z.Vc;z.removeFunction=z.Sd;var H=m,la,ma,ja;function w(a,b){a||A("Assertion failed: "+b)}function na(a){var b=p["_"+a];if(!b)try{b=eval("_"+a)}catch(c){}w(b,"Cannot call unknown function "+a+" (perhaps LLVM optimizations or closure removed it?)");return b}var oa,pa; +(function(){function a(a){a=a.toString().match(e).slice(1);return{arguments:a[0],body:a[1],returnValue:a[2]}}var b={stackSave:function(){z.Tb()},stackRestore:function(){z.Sb()},arrayToC:function(a){var b=z.pb(a.length);qa(a,b);return b},stringToC:function(a){var b=0;a!==k&&(a!==g&&0!==a)&&(b=z.pb((a.length<<2)+1),ra(a,b));return b}},c={string:b.stringToC,array:b.arrayToC};pa=function(a,b,e,f){var h=na(a),s=[],a=0;if(f)for(var v=0;v>0]=b;break;case "i8":I[a>>0]=b;break;case "i16":J[a>>1]=b;break;case "i32":K[a>>2]=b;break;case "i64":ma=[b>>>0,(la=b,1<=+ta(la)?0>>0:~~+xa((la-+(~~la>>>0))/4294967296)>>>0:0)];K[a>>2]=ma[0];K[a+4>>2]=ma[1];break;case "float":ya[a>>2]=b;break;case "double":za[a>>3]=b;break;default:A("invalid type for setValue: "+c)}}p.setValue=sa; +function Aa(a,b){b=b||"i8";"*"===b.charAt(b.length-1)&&(b="i32");switch(b){case "i1":return I[a>>0];case "i8":return I[a>>0];case "i16":return J[a>>1];case "i32":return K[a>>2];case "i64":return K[a>>2];case "float":return ya[a>>2];case "double":return za[a>>3];default:A("invalid type for setValue: "+b)}return k}p.getValue=Aa;var L=2,Ba=4;p.ALLOC_NORMAL=0;p.ALLOC_STACK=1;p.ALLOC_STATIC=L;p.ALLOC_DYNAMIC=3;p.ALLOC_NONE=Ba; +function M(a,b,c,e){var f,h;"number"===typeof a?(f=i,h=a):(f=m,h=a.length);var j="string"===typeof b?b:k,c=c==Ba?e:[Ca,z.pb,z.Ec,z.bb][c===g?L:c](Math.max(h,j?1:b.length));if(f){e=c;w(0==(c&3));for(a=c+(h&-4);e>2]=0;for(a=c+h;e>0]=0;return c}if("i8"===j)return a.subarray||a.slice?N.set(a,c):N.set(new Uint8Array(a),c),c;for(var e=0,l,u;e>0];if(128<=e)c=i;else if(0==e&&!b)break;f++;if(b&&f==b)break}b||(b=f);var h="";if(!c){for(;0>0],h+=c.nb(e);return h}p.Pointer_stringify=ka;p.UTF16ToString=function(a){for(var b=0,c="";;){var e=J[a+2*b>>1];if(0==e)return c;++b;c+=String.fromCharCode(e)}}; +p.stringToUTF16=function(a,b){for(var c=0;c>1]=a.charCodeAt(c);J[b+2*a.length>>1]=0};p.UTF32ToString=function(a){for(var b=0,c="";;){var e=K[a+4*b>>2];if(0==e)return c;++b;65536<=e?(e-=65536,c+=String.fromCharCode(55296|e>>10,56320|e&1023)):c+=String.fromCharCode(e)}};p.stringToUTF32=function(a,b){for(var c=0,e=0;e=f)var h=a.charCodeAt(++e),f=65536+((f&1023)<<10)|h&1023;K[b+4*c>>2]=f;++c}K[b+4*c>>2]=0}; +function Da(a){function b(c,e,f){var e=e||Infinity,h="",j=[],s;if("N"===a[l]){l++;"K"===a[l]&&l++;for(s=[];"E"!==a[l];)if("S"===a[l]){l++;var C=a.indexOf("_",l);s.push(q[a.substring(l,C)||0]||"?");l=C+1}else if("C"===a[l])s.push(s[s.length-1]),l+=2;else{var C=parseInt(a.substr(l)),P=C.toString().length;if(!C||!P){l--;break}var sb=a.substr(l+P,C);s.push(sb);q.push(sb);l+=P+C}l++;s=s.join("::");e--;if(0===e)return c?[s]:s}else if(("K"===a[l]||x&&"L"===a[l])&&l++,C=parseInt(a.substr(l)))P=C.toString().length, +s=a.substr(l+P,C),l+=P+C;x=m;"I"===a[l]?(l++,C=b(i),P=b(i,1,i),h+=P[0]+" "+s+"<"+C.join(", ")+">"):h=s;a:for(;lO?2*O:O+16777216; +O!==F&&(p.fa("increasing TOTAL_MEMORY to "+O+" to be compliant with the asm.js spec"),F=O);w("undefined"!==typeof Int32Array&&"undefined"!==typeof Float64Array&&!!(new Int32Array(1)).subarray&&!!(new Int32Array(1)).set,"JS engine does not provide full typed array support");var Q=new ArrayBuffer(F);I=new Int8Array(Q);J=new Int16Array(Q);K=new Int32Array(Q);N=new Uint8Array(Q);Ga=new Uint16Array(Q);Ha=new Uint32Array(Q);ya=new Float32Array(Q);za=new Float64Array(Q);K[0]=255;w(255===N[0]&&0===N[3],"Typed arrays 2 must be run on a little-endian system"); +p.HEAP=g;p.buffer=Q;p.HEAP8=I;p.HEAP16=J;p.HEAP32=K;p.HEAPU8=N;p.HEAPU16=Ga;p.HEAPU32=Ha;p.HEAPF32=ya;p.HEAPF64=za;function Na(a){for(;0>0]=a[c],c+=1}p.writeStringToMemory=ra;function qa(a,b){for(var c=0;c>0]=a[c]}p.writeArrayToMemory=qa; +p.writeAsciiToMemory=function(a,b,c){for(var e=0;e>0]=a.charCodeAt(e);c||(I[b+a.length>>0]=0)};if(!Math.imul||-5!==Math.imul(4294967295,5))Math.imul=function(a,b){var c=a&65535,e=b&65535;return c*e+((a>>>16)*e+c*(b>>>16)<<16)|0};Math.vg=Math.imul;var ta=Math.abs,xa=Math.ceil,wa=Math.floor,va=Math.min,S=0,Wa=k,Xa=k;function Ya(){S++;p.monitorRunDependencies&&p.monitorRunDependencies(S)}p.addRunDependency=Ya; +function Za(){S--;p.monitorRunDependencies&&p.monitorRunDependencies(S);if(0==S&&(Wa!==k&&(clearInterval(Wa),Wa=k),Xa)){var a=Xa;Xa=k;a()}}p.removeRunDependency=Za;p.preloadedImages={};p.preloadedAudios={};var T=k,Ia=8,D=Ia+7808;R.push(); +M([0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,0,0,0,0,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,0,0,0,0,10,0,0,0,13,0,0,0,16,0,0,0,11,0,0,0,14,0,0,0,18,0,0,0,13,0,0,0,16,0,0,0,20,0,0,0,14,0,0,0,18,0,0,0,23,0,0,0,16,0,0,0,20,0,0,0,25,0,0,0,18,0,0,0,23,0,0,0,29,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0, +0,0,14,0,0,0,15,0,0,0,16,0,0,0,17,0,0,0,18,0,0,0,19,0,0,0,20,0,0,0,21,0,0,0,22,0,0,0,23,0,0,0,24,0,0,0,25,0,0,0,26,0,0,0,27,0,0,0,28,0,0,0,29,0,0,0,29,0,0,0,30,0,0,0,31,0,0,0,32,0,0,0,32,0,0,0,33,0,0,0,34,0,0,0,34,0,0,0,35,0,0,0,35,0,0,0,36,0,0,0,36,0,0,0,37,0,0,0,37,0,0,0,37,0,0,0,38,0,0,0,38,0,0,0,38,0,0,0,39,0,0,0,39,0,0,0,39,0,0,0,39,0,0,0,1,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,16,0,0,0,32,0,0,0,64,0,0,0,128,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,1,0,0,0,4,0,0, +0,5,0,0,0,2,0,0,0,3,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,12,0,0,0,13,0,0,0,10,0,0,0,11,0,0,0,14,0,0,0,15,0,0,0,47,31,15,0,23,27,29,30,7,11,13,14,39,43,45,46,16,3,5,10,12,19,21,26,28,35,37,42,44,1,2,4,8,17,18,20,24,6,9,22,25,32,33,34,36,40,38,41,0,16,1,2,4,8,32,3,5,10,12,15,47,7,11,13,14,6,9,31,35,37,42,44,33,34,36,40,39,43,45,46,17,18,20,24,19,21,26,28,23,27,29,30,22,25,38,41,17,1,0,0,0,0,0,0,34,18,1,1,0,0,0,0,50,34,18,2,0,0,0,0,67,51,34,34,18,18,2,2,83,67,51,35,18,18,2,2,19,35,67,51,99,83,2,2,0, +0,101,85,68,68,52,52,35,35,35,35,19,19,19,19,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,249,233,217,200,200,184,184,167,167,167,167,151,151,151,151,134,134,134,134,134,134,134,134,118,118,118,118,118,118,118,118,230,214,198,182,165,165,149,149,132,132,132,132,116,116,116,116,100,100,100,100,84,84,84,84,67,67,67,67,67,67,67,67,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,19,19,19,19,19,19,19,19,3,3,3,3,3,3,3,3,214,182,197,197,165,165,149,149,132,132,132,132,84,84,84,84,68,68,68,68,4,4,4,4,115,115,115,115, +115,115,115,115,99,99,99,99,99,99,99,99,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,19,19,19,19,19,19,19,19,197,181,165,5,148,148,116,116,52,52,36,36,131,131,131,131,99,99,99,99,83,83,83,83,67,67,67,67,19,19,19,19,181,149,164,164,132,132,36,36,20,20,4,4,115,115,115,115,99,99,99,99,83,83,83,83,67,67,67,67,51,51,51,51,166,6,21,21,132,132,132,132,147,147,147,147,147,147,147,147,115,115,115,115,115,115,115,115,99,99,99,99,99,99,99,99,83,83,83,83,83,83,83,83,67,67,67,67,67,67,67,67,51,51,51,51,51, +51,51,51,35,35,35,35,35,35,35,35,150,6,21,21,116,116,116,116,131,131,131,131,131,131,131,131,99,99,99,99,99,99,99,99,67,67,67,67,67,67,67,67,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,134,6,37,37,20,20,20,20,115,115,115,115,115,115,115,115,99,99,99,99,99,99,99,99,51,51,51,51,51,51,51,51,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,22,6,117,117,36,36,36,36,83,83,83,83,83,83,83,83,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,21,5,100,100,35,35,35,35,82,82,82,82,82,82,82,82,66,66,66,66,66,66,66,66,50,50,50,50,50,50,50,50,4,20,35,35,51,51,83,83,65,65,65,65,65,65,65,65,4,20,67,67,34,34,34,34,49,49,49,49,49,49,49,49,3,19,50,50,33,33,33,33,2,18,33,33,0,0,0,0,0,0,0,0,0,0,102,32,38,16,6,8,101,24,101,24,67,16,67,16,67,16,67,16,67,16,67,16,67,16,67,16,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34, +8,34,8,34,8,34,8,34,8,34,8,34,8,0,0,0,0,0,0,0,0,106,64,74,48,42,40,10,32,105,56,105,56,73,40,73,40,41,32,41,32,9,24,9,24,104,48,104,48,104,48,104,48,72,32,72,32,72,32,72,32,40,24,40,24,40,24,40,24,8,16,8,16,8,16,8,16,103,40,103,40,103,40,103,40,103,40,103,40,103,40,103,40,71,24,71,24,71,24,71,24,71,24,71,24,71,24,71,24,110,96,78,88,46,80,14,80,110,88,78,80,46,72,14,72,13,64,13,64,77,72,77,72,45,64,45,64,13,56,13,56,109,80,109,80,77,64,77,64,45,56,45,56,13,48,13,48,107,72,107,72,107,72,107,72,107, +72,107,72,107,72,107,72,75,56,75,56,75,56,75,56,75,56,75,56,75,56,75,56,43,48,43,48,43,48,43,48,43,48,43,48,43,48,43,48,11,40,11,40,11,40,11,40,11,40,11,40,11,40,11,40,0,0,0,0,47,104,47,104,16,128,80,128,48,128,16,120,112,128,80,120,48,120,16,112,112,120,80,112,48,112,16,104,111,112,111,112,79,104,79,104,47,96,47,96,15,96,15,96,111,104,111,104,79,96,79,96,47,88,47,88,15,88,15,88,0,0,0,0,0,0,0,0,102,56,70,32,38,32,6,16,102,48,70,24,38,24,6,8,101,40,101,40,37,16,37,16,100,32,100,32,100,32,100,32,100, +24,100,24,100,24,100,24,67,16,67,16,67,16,67,16,67,16,67,16,67,16,67,16,0,0,0,0,0,0,0,0,105,72,73,56,41,56,9,48,8,40,8,40,72,48,72,48,40,48,40,48,8,32,8,32,103,64,103,64,103,64,103,64,71,40,71,40,71,40,71,40,39,40,39,40,39,40,39,40,7,24,7,24,7,24,7,24,0,0,0,0,109,120,109,120,110,128,78,128,46,128,14,128,46,120,14,120,78,120,46,112,77,112,77,112,13,112,13,112,109,112,109,112,77,104,77,104,45,104,45,104,13,104,13,104,109,104,109,104,77,96,77,96,45,96,45,96,13,96,13,96,12,88,12,88,12,88,12,88,76,88, +76,88,76,88,76,88,44,88,44,88,44,88,44,88,12,80,12,80,12,80,12,80,108,96,108,96,108,96,108,96,76,80,76,80,76,80,76,80,44,80,44,80,44,80,44,80,12,72,12,72,12,72,12,72,107,88,107,88,107,88,107,88,107,88,107,88,107,88,107,88,75,72,75,72,75,72,75,72,75,72,75,72,75,72,75,72,43,72,43,72,43,72,43,72,43,72,43,72,43,72,43,72,11,64,11,64,11,64,11,64,11,64,11,64,11,64,11,64,107,80,107,80,107,80,107,80,107,80,107,80,107,80,107,80,75,64,75,64,75,64,75,64,75,64,75,64,75,64,75,64,43,64,43,64,43,64,43,64,43,64,43, +64,43,64,43,64,11,56,11,56,11,56,11,56,11,56,11,56,11,56,11,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,24,70,56,38,56,6,16,102,72,70,48,38,48,6,8,37,40,37,40,69,40,69,40,37,32,37,32,69,32,69,32,37,24,37,24,101,64,101,64,69,24,69,24,37,16,37,16,100,56,100,56,100,56,100,56,100,48,100,48,100,48,100,48,100,40,100,40,100,40,100,40,100,32,100,32,100,32,100,32,100,24,100,24,100,24,100,24,68,16,68,16,68,16,68,16,36,8,36,8,36,8,36,8,4,0,4,0,4,0,4,0,0,0,10,128,106,128,74,128,42,128,10,120,106,120,74,120,42,120,10, +112,106,112,74,112,42,112,10,104,41,104,41,104,9,96,9,96,73,104,73,104,41,96,41,96,9,88,9,88,105,104,105,104,73,96,73,96,41,88,41,88,9,80,9,80,104,96,104,96,104,96,104,96,72,88,72,88,72,88,72,88,40,80,40,80,40,80,40,80,8,72,8,72,8,72,8,72,104,88,104,88,104,88,104,88,72,80,72,80,72,80,72,80,40,72,40,72,40,72,40,72,8,64,8,64,8,64,8,64,7,56,7,56,7,56,7,56,7,56,7,56,7,56,7,56,7,48,7,48,7,48,7,48,7,48,7,48,7,48,7,48,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,7,40,7,40,7,40,7,40,7,40,7,40,7,40,7,40, +103,80,103,80,103,80,103,80,103,80,103,80,103,80,103,80,71,64,71,64,71,64,71,64,71,64,71,64,71,64,71,64,39,64,39,64,39,64,39,64,39,64,39,64,39,64,39,64,7,32,7,32,7,32,7,32,7,32,7,32,7,32,7,32,6,8,38,8,0,0,6,0,6,16,38,16,70,16,0,0,6,24,38,24,70,24,102,24,6,32,38,32,70,32,102,32,6,40,38,40,70,40,102,40,6,48,38,48,70,48,102,48,6,56,38,56,70,56,102,56,6,64,38,64,70,64,102,64,6,72,38,72,70,72,102,72,6,80,38,80,70,80,102,80,6,88,38,88,70,88,102,88,6,96,38,96,70,96,102,96,6,104,38,104,70,104,102,104,6,112, +38,112,70,112,102,112,6,120,38,120,70,120,102,120,6,128,38,128,70,128,102,128,0,0,67,16,2,0,2,0,33,8,33,8,33,8,33,8,103,32,103,32,72,32,40,32,71,24,71,24,39,24,39,24,6,32,6,32,6,32,6,32,6,24,6,24,6,24,6,24,6,16,6,16,6,16,6,16,102,24,102,24,102,24,102,24,38,16,38,16,38,16,38,16,6,8,6,8,6,8,6,8,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,3, +0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,3,0,0,0,19,0,0,0,1,0,0,0,18,0,0,0,0,0,0,0,17,0,0,0,4,0,0,0,16,0,0,0,3,0,0,0,23,0,0,0,1,0,0,0,22,0,0,0,0,0,0,0,21,0,0,0,4,0,0,0,20,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,4,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,12,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,4,0,0,0,13,0,0,0,255,0,0,0,8,0,0,0,1,0,0,0,19,0,0,0,2,0,0,0,18,0,0,0,4,0, +0,0,17,0,0,0,255,0,0,0,16,0,0,0,1,0,0,0,23,0,0,0,2,0,0,0,22,0,0,0,4,0,0,0,21,0,0,0,255,0,0,0,20,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,13,0,0,0,1,0,0,0,18,0,0,0,1,0,0,0,19,0,0,0,4,0,0,0,16,0,0,0,4,0,0,0,17,0,0,0,1,0,0,0,22,0,0,0,1,0,0,0,23,0,0,0,4,0,0,0,20,0,0,0,4,0,0,0,21,0,0,0,0, +0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,15,0,0,0,4,0,0,0,10,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,11,0,0,0,4,0,0,0,14,0,0,0,0,0,0,0,17,0,0,0,4,0,0,0,16,0,0,0,0,0,0,0,19,0,0,0,4,0,0,0,18,0,0,0,0,0,0,0,21,0,0,0,4,0,0,0,20,0,0,0,0,0,0,0,23,0,0,0,4,0,0,0,22,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,12,0,0,0,8,0,0,0,12,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0, +12,0,0,0,8,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,8,0,0,0,8,0,0,0,12,0,0,0,12,0,0,0,8,0,0,0,8,0,0,0,12,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108, +109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234, +235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,0,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,1,0,0,0,255,0, +0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,13,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0, +0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,4,0,0,0,2,0,0,0,10,0,0, +0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,2,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0, +0,0,4,0,0,0,9,0,0,0,255,0,0,0,12,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,4,0,0,0,13,0,0,0,255,0,0,0,8,0,0,0,1,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,4,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,255,0, +0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0, +0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,13,0,0,0,0,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0, +0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,13,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0, +0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,15,0,0,0,4,0,0,0,10,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,11,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,11,0,0,0,4,0,0,0,14,0,0, +0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0,0,0,14,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,5,6,7,8,9,10,12,13,15,17,20,22,25,28,32,36,40,45,50,56,63,71,80,90,101,113,127,144,162,182,203,226,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,3,4,4,4,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,1,0,0,1,0,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,1,1,2,1,1,2,1,2,3,1,2,3,2,2,3,2,2,4,2,3,4,2,3,4,3,3,5,3,4,6,3,4,6,4,5,7,4,5,8,4,6,9,5,7,10,6,8,11,6,8,13,7,10,14,8,11,16,9,12,18,10,13,20,11,15,23,13,17,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,69,67,79,68,69,82,32,73,78,73,84,73,65,76,73,90,65,84,73,79,78,32,70,65,73,76,69,68,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"i8",Ba,z.Pc);var $a=z.ub(M(12,"i8",L),8);w(0==$a%8); +var U={O:1,Q:2,Ef:3,De:4,ha:5,Zb:6,be:7,$e:8,V:9,oe:10,Ca:11,Of:11,Mc:12,qb:13,ye:14,mf:15,ga:16,Xb:17,Oc:18,Qa:19,Sa:20,pa:21,B:22,Ve:23,Lc:24,Nc:25,Lf:26,ze:27,hf:28,Ua:29,Bf:30,Oe:31,uf:32,ve:33,yf:34,df:42,Be:43,pe:44,Fe:45,Ge:46,He:47,Ne:48,Mf:49,Ye:50,Ee:51,te:35,af:37,ge:52,je:53,Pf:54,We:55,ke:56,le:57,ue:35,me:59,kf:60,Ze:61,If:62,jf:63,ef:64,ff:65,Af:66,bf:67,ee:68,Ff:69,qe:70,vf:71,Qe:72,we:73,ie:74,qf:76,he:77,zf:78,Ie:79,Je:80,Me:81,Le:82,Ke:83,lf:38,sb:39,Re:36,rb:40,Ta:95,tf:96,se:104, +Xe:105,fe:97,xf:91,of:88,gf:92,Cf:108,Wb:111,ce:98,re:103,Ue:101,Se:100,Jf:110,Ae:112,Yb:113,Jc:115,Hc:114,Ic:89,Pe:90,wf:93,Df:94,de:99,Te:102,Kc:106,Ra:107,Kf:109,Nf:87,xe:122,Gf:116,pf:95,cf:123,Ce:84,rf:75,ne:125,nf:131,sf:130,Hf:86},ab={"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"},bb=0;function V(a){return K[bb>>2]=a} +function cb(a,b){for(var c=0,e=a.length-1;0<=e;e--){var f=a[e];"."===f?a.splice(e,1):".."===f?(a.splice(e,1),c++):c&&(a.splice(e,1),c--)}if(b)for(;c--;c)a.unshift("..");return a}function db(a){var b="/"===a.charAt(0),c="/"===a.substr(-1),a=cb(a.split("/").filter(function(a){return!!a}),!b).join("/");!a&&!b&&(a=".");a&&c&&(a+="/");return(b?"/":"")+a} +function eb(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 W(a){if("/"===a)return"/";var b=a.lastIndexOf("/");return-1===b?a:a.substr(b+1)}function fb(){var a=Array.prototype.slice.call(arguments,0);return db(a.join("/"))}function X(a,b){return db(a+"/"+b)} +function gb(){for(var a="",b=m,c=arguments.length-1;-1<=c&&!b;c--){b=0<=c?arguments[c]:B.yb();"string"!==typeof b&&d(new TypeError("Arguments to path.resolve must be strings"));if(!b)return"";a=b+"/"+a;b="/"===b.charAt(0)}a=cb(a.split("/").filter(function(a){return!!a}),!b).join("/");return(b?"/":"")+a||"."} +function hb(a,b){function c(a){for(var b=0;bc?[]:a.slice(b,c-b+1)}for(var a=gb(a).substr(1),b=gb(b).substr(1),e=c(a.split("/")),f=c(b.split("/")),h=Math.min(e.length,f.length),j=h,l=0;la.k.length)&&(a.k=Y.ud(a),a.q=a.k.length);if(!a.k||a.k.subarray){var c=a.k?a.k.buffer.byteLength:0;c>=b||(b=Math.max(b,c*(1048576>c?2:1.125)|0),0!=c&&(b=Math.max(b,256)),c=a.k,a.k=new Uint8Array(b),0b)a.k.length=b;else for(;a.k.length=a.g.q)return 0;a=Math.min(a.g.q-f,e);w(0<=a);if(8b&&d(new B.e(U.B));return b},Ea:function(a,b,c){Y.lc(a.g,b+c);a.g.q=Math.max(a.g.q,b+c)},Ja:function(a,b,c,e,f,h,j){B.isFile(a.g.mode)||d(new B.e(U.Qa));c=a.g.k;if(!(j&2)&&(c.buffer===b||c.buffer=== +b.buffer))a=m,e=c.byteOffset;else{if(0>>0)%B.T.length},tc:function(a){var b=B.Fb(a.parent.id,a.name);a.ma=B.T[b];B.T[b]=a},uc:function(a){var b=B.Fb(a.parent.id,a.name);if(B.T[b]===a)B.T[b]=a.ma;else for(b=B.T[b];b;){if(b.ma===a){b.ma=a.ma;break}b=b.ma}},aa:function(a,b){var c=B.Gd(a);c&&d(new B.e(c,a));for(c=B.T[B.Fb(a.id,b)];c;c=c.ma){var e=c.name;if(c.parent.id===a.id&&e===b)return c}return B.ra(a,b)},createNode:function(a,b,c,e){B.Va||(B.Va=function(a,b,c,e){a|| +(a=this);this.parent=a;this.F=a.F;this.Ka=k;this.id=B.Jd++;this.name=b;this.mode=c;this.n={};this.p={};this.ob=e},B.Va.prototype={},Object.defineProperties(B.Va.prototype,{M:{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}},Dd:{get:function(){return B.J(this.mode)}},Gb:{get:function(){return B.ib(this.mode)}}}));a=new B.Va(a,b,c,e);B.tc(a);return a}, +zb:function(a){B.uc(a)},jb:function(a){return a===a.parent},ka:function(a){return!!a.Ka},isFile:function(a){return 32768===(a&61440)},J:function(a){return 16384===(a&61440)},Ia:function(a){return 40960===(a&61440)},ib:function(a){return 8192===(a&61440)},Bd:function(a){return 24576===(a&61440)},Cd:function(a){return 4096===(a&61440)},Ed:function(a){return 49152===(a&49152)},rd:{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}, +wc:function(a){var b=B.rd[a];"undefined"===typeof b&&d(Error("Unknown file open mode: "+a));return b},sd:function(a){var b=["r","w","rw"][a&2097155];a&512&&(b+="w");return b},na:function(a,b){return B.vc?0:-1!==b.indexOf("r")&&!(a.mode&292)||-1!==b.indexOf("w")&&!(a.mode&146)||-1!==b.indexOf("x")&&!(a.mode&73)?U.qb:0},Gd:function(a){var b=B.na(a,"x");return b?b:!a.n.ra?U.qb:0},Jb:function(a,b){try{return B.aa(a,b),U.Xb}catch(c){}return B.na(a,"wx")},kb:function(a,b,c){var e;try{e=B.aa(a,b)}catch(f){return f.cb}if(a= +B.na(a,"wx"))return a;if(c){if(!B.J(e.mode))return U.Sa;if(B.jb(e)||B.da(e)===B.yb())return U.ga}else if(B.J(e.mode))return U.pa;return 0},Hd:function(a,b){return!a?U.Q:B.Ia(a.mode)?U.rb:B.J(a.mode)&&(0!==(b&2097155)||b&512)?U.pa:B.na(a,B.sd(b))},Qc:4096,Kd:function(a,b){for(var b=b||B.Qc,c=a||0;c<=b;c++)if(!B.oa[c])return c;d(new B.e(U.Lc))},qa:function(a){return B.oa[a]},fc:function(a,b,c){B.Wa||(B.Wa=n(),B.Wa.prototype={},Object.defineProperties(B.Wa.prototype,{object:{get:function(){return this.g}, +set:function(a){this.g=a}},yg:{get:function(){return 1!==(this.D&2097155)}},zg:{get:function(){return 0!==(this.D&2097155)}},xg:{get:function(){return this.D&1024}}}));var e=new B.Wa,f;for(f in a)e[f]=a[f];a=e;b=B.Kd(b,c);a.C=b;return B.oa[b]=a},dd:function(a){B.oa[a]=k},pc:function(a){return B.oa[a-1]},Eb:function(a){return a?a.C+1:0},bd:{open:function(a){a.p=B.td(a.g.ob).p;a.p.open&&a.p.open(a)},$:function(){d(new B.e(U.Ua))}},Ib:function(a){return a>>8},Gg:function(a){return a&255},la:function(a, +b){return a<<8|b},Ob:function(a,b){B.ic[a]={p:b}},td:function(a){return B.ic[a]},nc:function(a){for(var b=[],a=[a];a.length;){var c=a.pop();b.push(c);a.push.apply(a,c.La)}return b},Fc:function(a,b){function c(a){if(a){if(!c.pd)return c.pd=i,b(a)}else++f>=e.length&&b(k)}"function"===typeof a&&(b=a,a=m);var e=B.nc(B.root.F),f=0;e.forEach(function(b){if(!b.type.Fc)return c(k);b.type.Fc(b,a,c)})},F:function(a,b,c){var e="/"===c,f=!c,h;e&&B.root&&d(new B.e(U.ga));!e&&!f&&(h=B.u(c,{Bb:m}),c=h.path,h=h.g, +B.ka(h)&&d(new B.e(U.ga)),B.J(h.mode)||d(new B.e(U.Sa)));b={type:a,Kg:b,Id:c,La:[]};a=a.F(b);a.F=b;b.root=a;e?B.root=a:h&&(h.Ka=b,h.F&&h.F.La.push(b));return a},Qg:function(a){a=B.u(a,{Bb:m});B.ka(a.g)||d(new B.e(U.B));var a=a.g,b=a.Ka,c=B.nc(b);Object.keys(B.T).forEach(function(a){for(a=B.T[a];a;){var b=a.ma;-1!==c.indexOf(a.F)&&B.zb(a);a=b}});a.Ka=k;b=a.F.La.indexOf(b);w(-1!==b);a.F.La.splice(b,1)},ra:function(a,b){return a.n.ra(a,b)},ba:function(a,b,c){var e=B.u(a,{parent:i}).g,a=W(a);(!a||"."=== +a||".."===a)&&d(new B.e(U.B));var f=B.Jb(e,a);f&&d(new B.e(f));e.n.ba||d(new B.e(U.O));return e.n.ba(e,a,b,c)},create:function(a,b){b=(b!==g?b:438)&4095;b|=32768;return B.ba(a,b,0)},ea:function(a,b){b=(b!==g?b:511)&1023;b|=16384;return B.ba(a,b,0)},lb:function(a,b,c){"undefined"===typeof c&&(c=b,b=438);return B.ba(a,b|8192,c)},ca:function(a,b){gb(a)||d(new B.e(U.Q));var c=B.u(b,{parent:i}).g;c||d(new B.e(U.Q));var e=W(b),f=B.Jb(c,e);f&&d(new B.e(f));c.n.ca||d(new B.e(U.O));return c.n.ca(c,e,a)},rename:function(a, +b){var c=eb(a),e=eb(b),f=W(a),h=W(b),j,l,u;try{j=B.u(a,{parent:i}),l=j.g,j=B.u(b,{parent:i}),u=j.g}catch(q){d(new B.e(U.ga))}(!l||!u)&&d(new B.e(U.Q));l.F!==u.F&&d(new B.e(U.Oc));j=B.aa(l,f);e=hb(a,e);"."!==e.charAt(0)&&d(new B.e(U.B));e=hb(b,c);"."!==e.charAt(0)&&d(new B.e(U.sb));var x;try{x=B.aa(u,h)}catch(s){}if(j!==x){c=B.J(j.mode);(f=B.kb(l,f,c))&&d(new B.e(f));(f=x?B.kb(u,h,c):B.Jb(u,h))&&d(new B.e(f));l.n.rename||d(new B.e(U.O));(B.ka(j)||x&&B.ka(x))&&d(new B.e(U.ga));u!==l&&(f=B.na(l,"w"))&& +d(new B.e(f));try{B.H.willMovePath&&B.H.willMovePath(a,b)}catch(v){console.log("FS.trackingDelegate['willMovePath']('"+a+"', '"+b+"') threw an exception: "+v.message)}B.uc(j);try{l.n.rename(j,u,h)}catch(G){d(G)}finally{B.tc(j)}try{if(B.H.onMovePath)B.H.onMovePath(a,b)}catch(ua){console.log("FS.trackingDelegate['onMovePath']('"+a+"', '"+b+"') threw an exception: "+ua.message)}}},Oa:function(a){var b=B.u(a,{parent:i}).g,c=W(a),e=B.aa(b,c),f=B.kb(b,c,i);f&&d(new B.e(f));b.n.Oa||d(new B.e(U.O));B.ka(e)&& +d(new B.e(U.ga));try{B.H.willDeletePath&&B.H.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.n.Oa(b,c);B.zb(e);try{if(B.H.onDeletePath)B.H.onDeletePath(a)}catch(j){console.log("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+j.message)}},Na:function(a){a=B.u(a,{R:i}).g;a.n.Na||d(new B.e(U.Sa));return a.n.Na(a)},za:function(a){var b=B.u(a,{parent:i}).g,c=W(a),e=B.aa(b,c),f=B.kb(b,c,m);f&&(f===U.pa&&(f=U.O), +d(new B.e(f)));b.n.za||d(new B.e(U.O));B.ka(e)&&d(new B.e(U.ga));try{B.H.willDeletePath&&B.H.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.n.za(b,c);B.zb(e);try{if(B.H.onDeletePath)B.H.onDeletePath(a)}catch(j){console.log("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+j.message)}},ta:function(a){(a=B.u(a).g)||d(new B.e(U.Q));a.n.ta||d(new B.e(U.B));return a.n.ta(a)},Dc:function(a,b){var c=B.u(a,{R:!b}).g; +c||d(new B.e(U.Q));c.n.S||d(new B.e(U.O));return c.n.S(c)},Eg:function(a){return B.Dc(a,i)},Ya:function(a,b,c){a="string"===typeof a?B.u(a,{R:!c}).g:a;a.n.I||d(new B.e(U.O));a.n.I(a,{mode:b&4095|a.mode&-4096,timestamp:Date.now()})},Bg:function(a,b){B.Ya(a,b,i)},jg:function(a,b){var c=B.qa(a);c||d(new B.e(U.V));B.Ya(c.g,b)},dc:function(a,b,c,e){a="string"===typeof a?B.u(a,{R:!e}).g:a;a.n.I||d(new B.e(U.O));a.n.I(a,{timestamp:Date.now()})},Cg:function(a,b,c){B.dc(a,b,c,i)},kg:function(a,b,c){(a=B.qa(a))|| +d(new B.e(U.V));B.dc(a.g,b,c)},truncate:function(a,b){0>b&&d(new B.e(U.B));var c;c="string"===typeof a?B.u(a,{R:i}).g:a;c.n.I||d(new B.e(U.O));B.J(c.mode)&&d(new B.e(U.pa));B.isFile(c.mode)||d(new B.e(U.B));var e=B.na(c,"w");e&&d(new B.e(e));c.n.I(c,{size:b,timestamp:Date.now()})},mg:function(a,b){var c=B.qa(a);c||d(new B.e(U.V));0===(c.D&2097155)&&d(new B.e(U.B));B.truncate(c.g,b)},Rg:function(a,b,c){a=B.u(a,{R:i}).g;a.n.I(a,{timestamp:Math.max(b,c)})},open:function(a,b,c,e,f){""===a&&d(new B.e(U.Q)); +var b="string"===typeof b?B.wc(b):b,c=b&64?("undefined"===typeof c?438:c)&4095|32768:0,h;if("object"===typeof a)h=a;else{a=db(a);try{h=B.u(a,{R:!(b&131072)}).g}catch(j){}}var l=m;b&64&&(h?b&128&&d(new B.e(U.Xb)):(h=B.ba(a,c,0),l=i));h||d(new B.e(U.Q));B.ib(h.mode)&&(b&=-513);l||(c=B.Hd(h,b))&&d(new B.e(c));b&512&&B.truncate(h,0);b&=-641;e=B.fc({g:h,path:B.da(h),D:b,seekable:i,position:0,p:h.p,$d:[],error:m},e,f);e.p.open&&e.p.open(e);p.logReadFiles&&!(b&1)&&(B.Mb||(B.Mb={}),a in B.Mb||(B.Mb[a]=1, +p.printErr("read file: "+a)));try{B.H.onOpenFile&&(f=0,1!==(b&2097155)&&(f|=B.Gc.yc.Rc),0!==(b&2097155)&&(f|=B.Gc.yc.Sc),B.H.onOpenFile(a,f))}catch(u){console.log("FS.trackingDelegate['onOpenFile']('"+a+"', flags) threw an exception: "+u.message)}return e},close:function(a){try{a.p.close&&a.p.close(a)}catch(b){d(b)}finally{B.dd(a.C)}},$:function(a,b,c){(!a.seekable||!a.p.$)&&d(new B.e(U.Ua));a.position=a.p.$(a,b,c);a.$d=[];return a.position},M:function(a,b,c,e,f){(0>e||0>f)&&d(new B.e(U.B));1===(a.D& +2097155)&&d(new B.e(U.V));B.J(a.g.mode)&&d(new B.e(U.pa));a.p.M||d(new B.e(U.B));var h=i;"undefined"===typeof f?(f=a.position,h=m):a.seekable||d(new B.e(U.Ua));b=a.p.M(a,b,c,e,f);h||(a.position+=b);return b},write:function(a,b,c,e,f,h){(0>e||0>f)&&d(new B.e(U.B));0===(a.D&2097155)&&d(new B.e(U.V));B.J(a.g.mode)&&d(new B.e(U.pa));a.p.write||d(new B.e(U.B));a.D&1024&&B.$(a,0,2);var j=i;"undefined"===typeof f?(f=a.position,j=m):a.seekable||d(new B.e(U.Ua));b=a.p.write(a,b,c,e,f,h);j||(a.position+=b); +try{if(a.path&&B.H.onWriteToFile)B.H.onWriteToFile(a.path)}catch(l){console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: "+l.message)}return b},Ea:function(a,b,c){(0>b||0>=c)&&d(new B.e(U.B));0===(a.D&2097155)&&d(new B.e(U.V));!B.isFile(a.g.mode)&&!B.J(node.mode)&&d(new B.e(U.Qa));a.p.Ea||d(new B.e(U.Ta));a.p.Ea(a,b,c)},Ja:function(a,b,c,e,f,h,j){1===(a.D&2097155)&&d(new B.e(U.qb));a.p.Ja||d(new B.e(U.Qa));return a.p.Ja(a,b,c,e,f,h,j)},Ha:function(a,b,c){a.p.Ha||d(new B.e(U.Nc)); +return a.p.Ha(a,b,c)},Mg:function(a,b){b=b||{};b.D=b.D||"r";b.encoding=b.encoding||"binary";"utf8"!==b.encoding&&"binary"!==b.encoding&&d(Error('Invalid encoding type "'+b.encoding+'"'));var c,e=B.open(a,b.D),f=B.Dc(a).size,h=new Uint8Array(f);B.M(e,h,0,f,0);if("utf8"===b.encoding){c="";for(var j=new z.Da,l=0;l>2]=B.Eb(a);w(0===a.C,"invalid handle for stdin ("+a.C+")");a=B.open("/dev/stdout","w");K[pb>>2]=B.Eb(a);w(1===a.C,"invalid handle for stdout ("+a.C+")");a=B.open("/dev/stderr","w");K[qb>>2]=B.Eb(a);w(2===a.C,"invalid handle for stderr ("+a.C+")")},jc:function(){B.e||(B.e=function(a,b){this.g=b;this.Xd=function(a){this.cb=a;for(var b in U)if(U[b]=== +a){this.code=b;break}};this.Xd(a);this.message=ab[a]},B.e.prototype=Error(),[U.Q].forEach(function(a){B.Db[a]=new B.e(a);B.Db[a].stack=""}))},Zd:function(){B.jc();B.T=Array(4096);B.F(Y,{},"/");B.fd();B.ed()},Ga:function(a,b,c){w(!B.Ga.hb,"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)");B.Ga.hb=i;B.jc();p.stdin=a||p.stdin;p.stdout=b||p.stdout;p.stderr= +c||p.stderr;B.od()},Qd:function(){B.Ga.hb=m;for(var a=0;athis.length-1||0>a)){var b=a%this.cd;return this.yd(a/ +this.cd|0)[b]}};h.prototype.Wd=function(a){this.yd=a};h.prototype.bc=function(){var a=new XMLHttpRequest;a.open("HEAD",c,m);a.send(k);200<=a.status&&300>a.status||304===a.status||d(Error("Couldn't load "+c+". Status: "+a.status));var b=Number(a.getResponseHeader("Content-length")),e,f=1048576;if(!((e=a.getResponseHeader("Accept-Ranges"))&&"bytes"===e))f=b;var h=this;h.Wd(function(a){var e=a*f,j=(a+1)*f-1,j=Math.min(j,b-1);if("undefined"===typeof h.Za[a]){var l=h.Za;e>j&&d(Error("invalid range ("+ +e+", "+j+") or no bytes requested!"));j>b-1&&d(Error("only "+b+" bytes available! programmer error!"));var q=new XMLHttpRequest;q.open("GET",c,m);b!==f&&q.setRequestHeader("Range","bytes="+e+"-"+j);"undefined"!=typeof Uint8Array&&(q.responseType="arraybuffer");q.overrideMimeType&&q.overrideMimeType("text/plain; charset=x-user-defined");q.send(k);200<=q.status&&300>q.status||304===q.status||d(Error("Couldn't load "+c+". Status: "+q.status));e=q.response!==g?new Uint8Array(q.response||[]):Va(q.responseText|| +"",i);l[a]=e}"undefined"===typeof h.Za[a]&&d(Error("doXHR failed!"));return h.Za[a]});this.Uc=b;this.Tc=f;this.Hb=i};if("undefined"!==typeof XMLHttpRequest){ca||d("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc");var j=new h;Object.defineProperty(j,"length",{get:function(){this.Hb||this.bc();return this.Uc}});Object.defineProperty(j,"chunkSize",{get:function(){this.Hb||this.bc();return this.Tc}});j={Gb:m,k:j}}else j={Gb:m,url:c}; +var l=B.gd(a,b,j,e,f);j.k?l.k=j.k:j.url&&(l.k=k,l.url=j.url);Object.defineProperty(l,"usedBytes",{get:function(){return this.k.length}});var u={};Object.keys(l.p).forEach(function(a){var b=l.p[a];u[a]=function(){B.mc(l)||d(new B.e(U.ha));return b.apply(k,arguments)}});u.M=function(a,b,c,e,f){B.mc(l)||d(new B.e(U.ha));a=a.g.k;if(f>=a.length)return 0;e=Math.min(a.length-f,e);w(0<=e);if(a.slice)for(var h=0;h>h-6&63,h=h-6,c=c+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[q]}2==h?(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&3)<<4],c+="=="):4==h&&(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&15)<<2],c+="="); +s.src="data:audio/x-"+b.substr(-3)+";base64,"+c;f(s)}};s.src=l;p.noExitRuntime=i;setTimeout(function(){H||f(s)},1E4)}else return h()}});var v=p.canvas;v&&(v.Pb=v.requestPointerLock||v.mozRequestPointerLock||v.webkitRequestPointerLock||v.msRequestPointerLock||n(),v.kc=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock||document.msExitPointerLock||n(),v.kc=v.kc.bind(document),document.addEventListener("pointerlockchange",q,m),document.addEventListener("mozpointerlockchange", +q,m),document.addEventListener("webkitpointerlockchange",q,m),document.addEventListener("mspointerlockchange",q,m),p.elementPointerLock&&v.addEventListener("click",function(a){!rb&&v.Pb&&(v.Pb(),a.preventDefault())},m))}var G=b?gb(X(a,b)):a;Ya();"string"==typeof c?yb(c,function(a){x(a)},j):x(c)},indexedDB:function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},Ub:function(){return"EM_FS_"+window.location.pathname},Vb:20,Ba:"FILE_DATA",Og:function(a,b,c){var b= +b||n(),c=c||n(),e=B.indexedDB();try{var f=e.open(B.Ub(),B.Vb)}catch(h){return c(h)}f.Ld=function(){console.log("creating db");f.result.createObjectStore(B.Ba)};f.onsuccess=function(){var e=f.result.transaction([B.Ba],"readwrite"),h=e.objectStore(B.Ba),u=0,q=0,x=a.length;a.forEach(function(a){a=h.put(B.vb(a).object.k,a);a.onsuccess=function(){u++;u+q==x&&(0==q?b():c())};a.onerror=function(){q++;u+q==x&&(0==q?b():c())}});e.onerror=c};f.onerror=c},Dg:function(a,b,c){var b=b||n(),c=c||n(),e=B.indexedDB(); +try{var f=e.open(B.Ub(),B.Vb)}catch(h){return c(h)}f.Ld=c;f.onsuccess=function(){var e=f.result;try{var h=e.transaction([B.Ba],"readonly")}catch(u){c(u);return}var q=h.objectStore(B.Ba),x=0,s=0,v=a.length;a.forEach(function(a){var e=q.get(a);e.onsuccess=function(){B.vb(a).Ab&&B.za(a);B.xb(eb(a),W(a),e.result,i,i,i);x++;x+s==v&&(0==s?b():c())};e.onerror=function(){s++;x+s==v&&(0==s?b():c())}});h.onerror=c};f.onerror=c}};function zb(){d("TODO")} +var Z={F:function(){p.websocket=p.websocket&&"object"===typeof p.websocket?p.websocket:{};p.websocket.tb={};p.websocket.on=function(a,b){"function"===typeof b&&(this.tb[a]=b);return this};p.websocket.P=function(a,b){"function"===typeof this.tb[a]&&this.tb[a].call(this,b)};return B.createNode(k,"/",16895,0)},nd:function(a,b,c){c&&w(1==b==(6==c));a={qd:a,type:b,protocol:c,G:k,error:k,Ma:{},Kb:[],ua:[],wa:Z.L};b=Z.mb();c=B.createNode(Z.root,b,49152,0);c.va=a;b=B.fc({path:b,g:c,D:B.wc("r+"),seekable:m, +p:Z.p});a.A=b;return a},wd:function(a){a=B.qa(a);return!a||!B.Ed(a.g.mode)?k:a.g.va},p:{zc:function(a){a=a.g.va;return a.wa.zc(a)},Ha:function(a,b,c){a=a.g.va;return a.wa.Ha(a,b,c)},M:function(a,b,c,e){a=a.g.va;e=a.wa.Rd(a,e);if(!e)return 0;b.set(e.buffer,c);return e.buffer.length},write:function(a,b,c,e){a=a.g.va;return a.wa.Vd(a,b,c,e)},close:function(a){a=a.g.va;a.wa.close(a)}},mb:function(){Z.mb.gc||(Z.mb.gc=0);return"socket["+Z.mb.gc++ +"]"},L:{$a:function(a,b,c){var e;"object"===typeof b&&(e= +b,c=b=k);if(e)e._socket?(b=e._socket.remoteAddress,c=e._socket.remotePort):((c=/ws[s]?:\/\/([^:]+):(\d+)/.exec(e.url))||d(Error("WebSocket URL must be in the format ws(s)://address:port")),b=c[1],c=parseInt(c[2],10));else try{var f=p.websocket&&"object"===typeof p.websocket,h="ws:#".replace("#","//");f&&"string"===typeof p.websocket.url&&(h=p.websocket.url);if("ws://"===h||"wss://"===h)var j=b.split("/"),h=h+j[0]+":"+c+"/"+j.slice(1).join("/");j="binary";f&&"string"===typeof p.websocket.subprotocol&& +(j=p.websocket.subprotocol);var j=j.replace(/^ +| +$/g,"").split(/ *, */),l=t?{protocol:j.toString()}:j;e=new (t?(null)("ws"):window.WebSocket)(h,l);e.binaryType="arraybuffer"}catch(u){d(new B.e(U.Yb))}b={W:b,port:c,o:e,ab:[]};Z.L.$b(a,b);Z.L.zd(a,b);2===a.type&&"undefined"!==typeof a.ya&&b.ab.push(new Uint8Array([255,255,255,255,112,111,114,116,(a.ya&65280)>>8,a.ya&255]));return b},gb:function(a,b,c){return a.Ma[b+":"+c]},$b:function(a,b){a.Ma[b.W+":"+b.port]=b},Bc:function(a,b){delete a.Ma[b.W+ +":"+b.port]},zd:function(a,b){function c(){p.websocket.P("open",a.A.C);try{for(var c=b.ab.shift();c;)b.o.send(c),c=b.ab.shift()}catch(e){b.o.close()}}function e(c){w("string"!==typeof c&&c.byteLength!==g);var c=new Uint8Array(c),e=f;f=m;e&&10===c.length&&255===c[0]&&255===c[1]&&255===c[2]&&255===c[3]&&112===c[4]&&111===c[5]&&114===c[6]&&116===c[7]?(c=c[8]<<8|c[9],Z.L.Bc(a,b),b.port=c,Z.L.$b(a,b)):(a.ua.push({W:b.W,port:b.port,data:c}),p.websocket.P("message",a.A.C))}var f=i;t?(b.o.on("open",c),b.o.on("message", +function(a,b){b.binary&&e((new Uint8Array(a)).buffer)}),b.o.on("close",function(){p.websocket.P("close",a.A.C)}),b.o.on("error",function(){a.error=U.Wb;p.websocket.P("error",[a.A.C,a.error,"ECONNREFUSED: Connection refused"])})):(b.o.onopen=c,b.o.onclose=function(){p.websocket.P("close",a.A.C)},b.o.onmessage=function(a){e(a.data)},b.o.onerror=function(){a.error=U.Wb;p.websocket.P("error",[a.A.C,a.error,"ECONNREFUSED: Connection refused"])})},zc:function(a){if(1===a.type&&a.G)return a.Kb.length?65: +0;var b=0,c=1===a.type?Z.L.gb(a,a.Y,a.Z):k;if(a.ua.length||!c||c&&c.o.readyState===c.o.Pa||c&&c.o.readyState===c.o.CLOSED)b|=65;if(!c||c&&c.o.readyState===c.o.OPEN)b|=4;if(c&&c.o.readyState===c.o.Pa||c&&c.o.readyState===c.o.CLOSED)b|=16;return b},Ha:function(a,b,c){switch(b){case 21531:return b=0,a.ua.length&&(b=a.ua[0].data.length),K[c>>2]=b,0;default:return U.B}},close:function(a){if(a.G){try{a.G.close()}catch(b){}a.G=k}for(var c=Object.keys(a.Ma),e=0;e>0]=c;if(-1==Ab(Cb(b),Eb.Cc,1)){if(c=B.pc(b))c.error=i;return-1}return c}function Fb(a){Fb.$c||(E=E+4095&-4096,Fb.$c=i,w(z.bb),Fb.Wc=z.bb,z.bb=function(){A("cannot dynamically allocate, sbrk now has control")});var b=E;0!=a&&Fb.Wc(a);return b}p._memset=Gb;function Hb(a,b,c){window._broadwayOnPictureDecoded(a,b,c)}p._broadwayOnPictureDecoded=Hb;function Ib(){window._broadwayOnHeadersDecoded()}p._broadwayOnHeadersDecoded=Ib; +function Jb(a,b){Kb=a;Lb=b;if(!Mb)return 1;0==a?(Nb=function(){setTimeout(Ob,b)},Pb="timeout"):1==a&&(Nb=function(){Qb(Ob)},Pb="rAF");return 0} +function Rb(a,b,c,e){p.noExitRuntime=i;w(!Mb,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");Mb=a;Sb=e;var f=Tb;Ob=function(){if(!H)if(0=bc;)bc+=1E3/60;b=Math.max(bc-b,0);setTimeout(a,b)}function Qb(a){"undefined"===typeof window?cc(a):(window.requestAnimationFrame||(window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||cc),window.requestAnimationFrame(a))} +function xb(a){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",bmp:"image/bmp",ogg:"audio/ogg",wav:"audio/wav",mp3:"audio/mpeg"}[a.substr(a.lastIndexOf(".")+1)]} +function yb(a,b,c){function e(){c?c():d('Loading data file "'+a+'" failed.')}var f=new XMLHttpRequest;f.open("GET",a,i);f.responseType="arraybuffer";f.onload=function(){if(200==f.status||0==f.status&&f.response){var c=f.response;w(c,'Loading data file "'+a+'" failed (no arrayBuffer).');b(new Uint8Array(c));Za()}else e()};f.onerror=e;f.send(k);Ya()}var dc=[];function ec(){var a=p.canvas;dc.forEach(function(b){b(a.width,a.height)})} +function fc(a,b,c){b&&c?(a.ae=b,a.Ad=c):(b=a.ae,c=a.Ad);var e=b,f=c;p.forcedAspectRatio&&0>2]=0;R.unshift({ja:n()});Qa.push({ja:n()});var lb=new z.Da;t&&((null)("fs"),process.platform.match(/^win/));R.push({ja:function(){Z.root=B.F(Z,{},k)}}); +Eb.Cc=M([0],"i8",L); +p.requestFullScreen=function(a,b){function c(){Yb=m;var a=e.parentNode;(document.webkitFullScreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.mozFullscreenElement||document.fullScreenElement||document.fullscreenElement||document.msFullScreenElement||document.msFullscreenElement||document.webkitCurrentFullScreenElement)===a?(e.cc=document.cancelFullScreen||document.mozCancelFullScreen||document.webkitCancelFullScreen||document.msExitFullscreen||document.exitFullscreen|| +n(),e.cc=e.cc.bind(document),$b&&e.Pb(),Yb=i,ac&&("undefined"!=typeof SDL&&(a=Ha[SDL.screen+0*z.ia>>2],K[SDL.screen+0*z.ia>>2]=a|8388608),ec())):(a.parentNode.insertBefore(e,a),a.parentNode.removeChild(a),ac&&("undefined"!=typeof SDL&&(a=Ha[SDL.screen+0*z.ia>>2],K[SDL.screen+0*z.ia>>2]=a&-8388609),ec()));if(p.onFullScreen)p.onFullScreen(Yb);fc(e)}$b=a;ac=b;"undefined"===typeof $b&&($b=i);"undefined"===typeof ac&&(ac=m);var e=p.canvas;Zb||(Zb=i,document.addEventListener("fullscreenchange",c,m),document.addEventListener("mozfullscreenchange", +c,m),document.addEventListener("webkitfullscreenchange",c,m),document.addEventListener("MSFullscreenChange",c,m));var f=document.createElement("div");e.parentNode.insertBefore(f,e);f.appendChild(e);f.Td=f.requestFullScreen||f.mozRequestFullScreen||f.msRequestFullscreen||(f.webkitRequestFullScreen?function(){f.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}:k);f.Td()};p.requestAnimationFrame=function(a){Qb(a)};p.setCanvasSize=function(a,b,c){fc(p.canvas,a,b);c||ec()}; +p.pauseMainLoop=function(){Nb=k;Tb++};p.resumeMainLoop=function(){Tb++;var a=Kb,b=Lb,c=Mb;Mb=k;Rb(c,0,m,Sb);Jb(a,b)};p.getUserMedia=function(){window.qc||(window.qc=navigator.getUserMedia||navigator.mozGetUserMedia);window.qc(g)};Ja=y=z.ub(D);Ka=Ja+Ma;La=E=z.ub(Ka);w(La>2],a=Db(a,b);return 0>a?a:0>Eb(10,b)?-1:a+1},_fflush:n(),_fputc:Eb,_send:function(a,b,c){return!Z.wd(a)?(V(U.V),-1):Ab(a,b,c)},_pwrite:function(a,b,c,e){a=B.qa(a);if(!a)return V(U.V),-1;try{return B.write(a,I,b,c,e)}catch(f){return B.sc(f),-1}},_fputs:Db,_emscripten_set_main_loop:Rb, +_abort:function(){p.abort()},___setErrNo:V,_sbrk:Fb,_mkport:zb,_emscripten_set_main_loop_timing:Jb,_emscripten_memcpy_big:function(a,b,c){N.set(N.subarray(b,b+c),a);return a},_fileno:Cb,_broadwayOnHeadersDecoded:Ib,_write:Ab,_time:function(a){var b=Date.now()/1E3|0;a&&(K[a>>2]=b);return b},_sysconf:function(a){switch(a){case 30:return 4096;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 79:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809; +case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32; +case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1E3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:return"object"===typeof navigator?navigator.hardwareConcurrency||1:1}V(U.B);return-1}, +___errno_location:function(){return bb},STACKTOP:y,STACK_MAX:Ka,tempDoublePtr:$a,ABORT:H,NaN:NaN,Infinity:Infinity};// EMSCRIPTEN_START_ASM +var $=(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.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=0;var n=0;var o=0;var p=0;var q=+env.NaN,r=+env.Infinity;var s=0,t=0,u=0,v=0,w=0.0,x=0,y=0,z=0,A=0.0;var B=0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=global.Math.floor;var M=global.Math.abs;var N=global.Math.sqrt;var O=global.Math.pow;var P=global.Math.cos;var Q=global.Math.sin;var R=global.Math.tan;var S=global.Math.acos;var T=global.Math.asin;var U=global.Math.atan;var V=global.Math.atan2;var W=global.Math.exp;var X=global.Math.log;var Y=global.Math.ceil;var Z=global.Math.imul;var _=env.abort;var $=env.assert;var aa=env.min;var ba=env.invoke_viiiii;var ca=env._broadwayOnPictureDecoded;var da=env._puts;var ea=env._fflush;var fa=env._fputc;var ga=env._send;var ha=env._pwrite;var ia=env._fputs;var ja=env._emscripten_set_main_loop;var ka=env._abort;var la=env.___setErrNo;var ma=env._sbrk;var na=env._mkport;var oa=env._emscripten_set_main_loop_timing;var pa=env._emscripten_memcpy_big;var qa=env._fileno;var ra=env._broadwayOnHeadersDecoded;var sa=env._write;var ta=env._time;var ua=env._sysconf;var va=env.___errno_location;var wa=0.0; +// EMSCRIPTEN_START_FUNCS +function Sb(a,f,g,h,j,k){a=a|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var 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,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;X=i;i=i+32|0;W=X;p=c[j+4>>2]|0;V=(h>>>0)/(p>>>0)|0;U=V<<4;V=h-(Z(V,p)|0)<<4;c[W+4>>2]=p;c[W+8>>2]=c[j+8>>2];p=c[a>>2]|0;do if((p|0)==1|(p|0)==0){A=c[f+144>>2]|0;l=a+4|0;n=c[a+200>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){o=n+152|0;o=e[o>>1]|e[o+2>>1]<<16;m=1;v=o&65535;o=o>>>16&65535;s=c[n+104>>2]|0}else{m=1;v=0;o=0;s=-1}else{m=0;v=0;o=0;s=-1}n=c[a+204>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){w=n+172|0;w=e[w>>1]|e[w+2>>1]<<16;u=w&65535;q=1;r=c[n+108>>2]|0;w=w>>>16&65535}else{u=0;q=1;r=-1;w=0}else{u=0;q=0;r=-1;w=0}do if(!p)if(!((m|0)==0|(q|0)==0)){if((s|0)==0?((o&65535)<<16|v&65535|0)==0:0){n=0;o=0;break}if((r|0)==0?((w&65535)<<16|u&65535|0)==0:0){n=0;o=0}else T=16}else{n=0;o=0}else T=16;while(0);if((T|0)==16){y=b[f+160>>1]|0;z=b[f+162>>1]|0;n=c[a+208>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){t=n+172|0;p=c[n+108>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;T=25}else{p=-1;t=0;T=25}else T=20;do if((T|0)==20){p=c[a+212>>2]|0;if((p|0)!=0?(c[p+4>>2]|0)==(c[l>>2]|0):0){if((c[p>>2]|0)>>>0>=6){p=-1;t=0;T=25;break}t=p+192|0;p=c[p+112>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;T=25;break}if((m|0)==0|(q|0)!=0){p=-1;t=0;T=25}else n=v}while(0);do if((T|0)==25){m=(s|0)==(A|0);n=(r|0)==(A|0);if(((n&1)+(m&1)+((p|0)==(A|0)&1)|0)==1){if(m|n){n=m?v:u;o=m?o:w;break}n=t&65535;o=t>>>16&65535;break}n=v<<16>>16;l=u<<16>>16;p=t<<16>>16;if(u<<16>>16>v<<16>>16)m=l;else{m=n;n=(l|0)<(n|0)?l:n}if((m|0)<(p|0))p=m;else p=(n|0)>(p|0)?n:p;n=o<<16>>16;m=w<<16>>16;l=t>>16;if(w<<16>>16>o<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=p&65535;o=o&65535}while(0);n=(n&65535)+(y&65535)|0;o=(o&65535)+(z&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}else{n=n&65535;o=o&65535}}l=ic(g,A)|0;if(!l){G=1;i=X;return G|0}else{G=a+132|0;E=a+136|0;D=a+140|0;C=a+144|0;B=a+148|0;z=a+152|0;y=a+156|0;x=a+160|0;w=a+164|0;v=a+168|0;m=a+172|0;p=a+176|0;q=a+180|0;r=a+184|0;s=a+188|0;F=a+192|0;b[a+192>>1]=n;b[a+194>>1]=o;F=e[F>>1]|e[F+2>>1]<<16;b[s>>1]=F;b[s+2>>1]=F>>>16;b[r>>1]=F;b[r+2>>1]=F>>>16;b[q>>1]=F;b[q+2>>1]=F>>>16;b[p>>1]=F;b[p+2>>1]=F>>>16;b[m>>1]=F;b[m+2>>1]=F>>>16;b[v>>1]=F;b[v+2>>1]=F>>>16;b[w>>1]=F;b[w+2>>1]=F>>>16;b[x>>1]=F;b[x+2>>1]=F>>>16;b[y>>1]=F;b[y+2>>1]=F>>>16;b[z>>1]=F;b[z+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+100>>2]=A;c[a+104>>2]=A;c[a+108>>2]=A;c[a+112>>2]=A;c[a+116>>2]=l;c[a+120>>2]=l;c[a+124>>2]=l;c[a+128>>2]=l;c[W>>2]=l;dc(k,a+132|0,W,V,U,0,0,16,16);break}}else if((p|0)==3){x=b[f+160>>1]|0;y=b[f+162>>1]|0;C=c[f+144>>2]|0;u=a+4|0;o=c[a+200>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){w=o+152|0;w=e[w>>1]|e[w+2>>1]<<16;n=1;s=w&65535;w=w>>>16&65535;o=c[o+104>>2]|0}else{n=1;s=0;w=0;o=-1}else{n=0;s=0;w=0;o=-1}a:do if((o|0)==(C|0)){n=s;o=w}else{o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){G=o+172|0;G=e[G>>1]|e[G+2>>1]<<16;t=o+188|0;p=c[o+108>>2]|0;l=c[o+112>>2]|0;n=G&65535;o=G>>>16&65535;t=e[t>>1]|e[t+2>>1]<<16}else{p=-1;l=-1;n=0;o=0;t=0}else T=107;do if((T|0)==107){o=c[a+212>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0){if((c[o>>2]|0)>>>0>=6){p=-1;l=-1;n=0;o=0;t=0;break}t=o+192|0;p=-1;l=c[o+112>>2]|0;n=0;o=0;t=e[t>>1]|e[t+2>>1]<<16;break}if(!n){p=-1;l=-1;n=0;o=0;t=0}else{n=s;o=w;break a}}while(0);m=(p|0)==(C|0);if(((m&1)+((l|0)==(C|0)&1)|0)==1){if(m)break;n=t&65535;o=t>>>16&65535;break}l=s<<16>>16;p=n<<16>>16;q=t<<16>>16;if(n<<16>>16>s<<16>>16){m=p;n=l}else{m=l;n=(p|0)<(l|0)?p:l}if((m|0)<(q|0))q=m;else q=(n|0)>(q|0)?n:q;n=w<<16>>16;m=o<<16>>16;l=t>>16;if(o<<16>>16>w<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=q&65535;o=o&65535}while(0);n=(n&65535)+(x&65535)|0;o=(o&65535)+(y&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}m=ic(g,C)|0;if(!m){G=1;i=X;return G|0}x=a+132|0;z=a+136|0;A=a+140|0;y=a+144|0;G=a+164|0;F=a+168|0;E=a+172|0;w=a+176|0;b[a+176>>1]=n;b[a+178>>1]=o;w=e[w>>1]|e[w+2>>1]<<16;b[E>>1]=w;b[E+2>>1]=w>>>16;b[F>>1]=w;b[F+2>>1]=w>>>16;b[G>>1]=w;b[G+2>>1]=w>>>16;b[y>>1]=w;b[y+2>>1]=w>>>16;b[A>>1]=w;b[A+2>>1]=w>>>16;b[z>>1]=w;b[z+2>>1]=w>>>16;b[x>>1]=w;b[x+2>>1]=w>>>16;c[a+100>>2]=C;c[a+108>>2]=C;x=a+116|0;c[x>>2]=m;c[a+124>>2]=m;z=b[f+164>>1]|0;A=b[f+166>>1]|0;y=c[f+148>>2]|0;o=c[a+208>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){r=o+172|0;o=c[o+108>>2]|0;p=1;r=e[r>>1]|e[r+2>>1]<<16}else{o=-1;p=1;r=0}else{o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){r=o+176|0;o=c[o+108>>2]|0;p=1;r=e[r>>1]|e[r+2>>1]<<16}else{o=-1;p=1;r=0}else{o=-1;p=0;r=0}}do if((o|0)!=(y|0)){s=w&65535;o=w>>>16;v=o&65535;n=c[a+204>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[u>>2]|0):0)if((c[n>>2]|0)>>>0<6){u=n+188|0;u=e[u>>1]|e[u+2>>1]<<16;p=c[n+112>>2]|0;l=u&65535;u=u>>>16&65535}else{p=-1;l=0;u=0}else if(!p){m=w;break}else{p=-1;l=0;u=0}m=(C|0)==(y|0);n=(p|0)==(y|0);if(((n&1)+(m&1)|0)==1){if(m){m=w;break}if(n){o=u&65535;m=o<<16|l&65535;break}else{m=r;o=r>>>16;break}}o=w<<16>>16;p=l<<16>>16;q=r<<16>>16;if(l<<16>>16>s<<16>>16)m=p;else{m=o;o=(p|0)<(o|0)?p:o}if((m|0)>=(q|0))m=(o|0)>(q|0)?o:q;n=w>>16;l=u<<16>>16;p=r>>16;if(u<<16>>16>v<<16>>16)o=l;else{o=n;n=(l|0)<(n|0)?l:n}if((o|0)>=(p|0))o=(n|0)>(p|0)?n:p}else{m=r;o=r>>>16}while(0);m=(m&65535)+(z&65535)|0;n=(o&65535)+(A&65535)|0;if(((m<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((n<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}o=ic(g,y)|0;if(!o){G=1;i=X;return G|0}else{G=a+148|0;E=a+152|0;D=a+156|0;C=a+160|0;B=a+180|0;A=a+184|0;z=a+188|0;F=a+192|0;b[a+192>>1]=m;b[a+194>>1]=n;F=e[F>>1]|e[F+2>>1]<<16;b[z>>1]=F;b[z+2>>1]=F>>>16;b[A>>1]=F;b[A+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+104>>2]=y;c[a+112>>2]=y;F=a+120|0;c[F>>2]=o;c[a+128>>2]=o;c[W>>2]=c[x>>2];dc(k,a+132|0,W,V,U,0,0,8,16);c[W>>2]=c[F>>2];dc(k,G,W,V,U,8,0,8,16);break}}else if((p|0)==2){z=b[f+160>>1]|0;A=b[f+162>>1]|0;C=c[f+144>>2]|0;B=a+4|0;o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[B>>2]|0):0)if((c[o>>2]|0)>>>0<6){w=o+172|0;w=e[w>>1]|e[w+2>>1]<<16;m=1;o=c[o+108>>2]|0;r=w&65535;w=w>>>16&65535}else{m=1;o=-1;r=0;w=0}else{m=0;o=-1;r=0;w=0}b:do if((o|0)==(C|0)){n=r;o=w}else{n=c[a+200>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0)if((c[n>>2]|0)>>>0<6){o=n+152|0;o=e[o>>1]|e[o+2>>1]<<16;q=1;s=o&65535;o=o>>>16&65535;p=c[n+104>>2]|0}else{q=1;s=0;o=0;p=-1}else{q=0;s=0;o=0;p=-1}n=c[a+208>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0)if((c[n>>2]|0)>>>0<6){t=n+172|0;n=c[n+108>>2]|0;t=e[t>>1]|e[t+2>>1]<<16}else{n=-1;t=0}else T=54;do if((T|0)==54){n=c[a+212>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0){if((c[n>>2]|0)>>>0>=6){n=-1;t=0;break}t=n+192|0;n=c[n+112>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;break}if((q|0)==0|(m|0)!=0){n=-1;t=0}else{n=s;break b}}while(0);m=(p|0)==(C|0);if((((n|0)==(C|0)&1)+(m&1)|0)==1){if(m){n=m?s:r;o=m?o:w;break}n=t&65535;o=t>>>16&65535;break}n=s<<16>>16;l=r<<16>>16;p=t<<16>>16;if(r<<16>>16>s<<16>>16)m=l;else{m=n;n=(l|0)<(n|0)?l:n}if((m|0)<(p|0))q=m;else q=(n|0)>(p|0)?n:p;n=o<<16>>16;m=w<<16>>16;l=t>>16;if(w<<16>>16>o<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=q&65535;o=o&65535}while(0);n=(n&65535)+(z&65535)|0;o=(o&65535)+(A&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}m=ic(g,C)|0;if(!m){G=1;i=X;return G|0}A=a+132|0;x=a+136|0;y=a+140|0;z=a+144|0;q=a+148|0;p=a+152|0;G=a+156|0;v=a+160|0;b[a+160>>1]=n;b[a+162>>1]=o;v=e[v>>1]|e[v+2>>1]<<16;b[G>>1]=v;b[G+2>>1]=v>>>16;b[p>>1]=v;b[p+2>>1]=v>>>16;b[q>>1]=v;b[q+2>>1]=v>>>16;b[z>>1]=v;b[z+2>>1]=v>>>16;b[y>>1]=v;b[y+2>>1]=v>>>16;b[x>>1]=v;b[x+2>>1]=v>>>16;b[A>>1]=v;b[A+2>>1]=v>>>16;c[a+100>>2]=C;c[a+104>>2]=C;A=a+116|0;c[A>>2]=m;c[a+120>>2]=m;x=b[f+164>>1]|0;y=b[f+166>>1]|0;z=c[f+148>>2]|0;q=c[a+200>>2]|0;p=(q|0)==0;if((!p?(c[q+4>>2]|0)==(c[B>>2]|0):0)?(c[q>>2]|0)>>>0<6:0){w=q+184|0;w=e[w>>1]|e[w+2>>1]<<16;r=w&65535;w=w>>>16&65535;o=c[q+112>>2]|0}else{r=0;w=0;o=-1}do if((o|0)!=(z|0)){s=v&65535;n=v>>>16;u=n&65535;if((!p?(c[q+4>>2]|0)==(c[B>>2]|0):0)?(c[q>>2]|0)>>>0<6:0){t=q+160|0;p=c[q+104>>2]|0;t=e[t>>1]|e[t+2>>1]<<16}else{p=-1;t=0}o=(C|0)==(z|0);if((((p|0)==(z|0)&1)+(o&1)|0)==1){m=o?v:t;o=o?n:t>>>16;break}o=r<<16>>16;p=v<<16>>16;q=t<<16>>16;if(s<<16>>16>r<<16>>16)m=p;else{m=o;o=(p|0)<(o|0)?p:o}if((m|0)>=(q|0))m=(o|0)>(q|0)?o:q;n=w<<16>>16;l=v>>16;p=t>>16;if(u<<16>>16>w<<16>>16)o=l;else{o=n;n=(l|0)<(n|0)?l:n}if((o|0)>=(p|0))o=(n|0)>(p|0)?n:p}else{o=w&65535;m=o<<16|r&65535}while(0);m=(m&65535)+(x&65535)|0;n=(o&65535)+(y&65535)|0;if(((m<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((n<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}o=ic(g,z)|0;if(!o){G=1;i=X;return G|0}else{G=a+164|0;E=a+168|0;D=a+172|0;C=a+176|0;B=a+180|0;y=a+184|0;x=a+188|0;F=a+192|0;b[a+192>>1]=m;b[a+194>>1]=n;F=e[F>>1]|e[F+2>>1]<<16;b[x>>1]=F;b[x+2>>1]=F>>>16;b[y>>1]=F;b[y+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+108>>2]=z;c[a+112>>2]=z;F=a+124|0;c[F>>2]=o;c[a+128>>2]=o;c[W>>2]=c[A>>2];dc(k,a+132|0,W,V,U,0,0,16,8);c[W>>2]=c[F>>2];dc(k,G,W,V,U,0,8,16,8);break}}else{S=a+4|0;H=0;c:while(1){D=f+(H<<2)+176|0;G=eb(c[D>>2]|0)|0;E=f+(H<<2)+192|0;c[a+(H<<2)+100>>2]=c[E>>2];F=ic(g,c[E>>2]|0)|0;c[a+(H<<2)+116>>2]=F;if(!F){l=1;T=212;break}if(G){J=H<<2;K=a+(J<<2)+132|0;O=a+(J<<2)+134|0;P=J|1;L=a+(P<<2)+132|0;P=a+(P<<2)+134|0;Q=J|2;M=a+(Q<<2)+132|0;Q=a+(Q<<2)+134|0;R=J|3;N=a+(R<<2)+132|0;R=a+(R<<2)+134|0;I=0;do{C=b[f+(H<<4)+(I<<2)+208>>1]|0;B=b[f+(H<<4)+(I<<2)+210>>1]|0;F=hb(c[D>>2]|0)|0;n=c[E>>2]|0;s=ub(a,c[6288+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;r=d[6288+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((s|0)!=0?(c[s+4>>2]|0)==(c[S>>2]|0):0)if((c[s>>2]|0)>>>0<6){q=s+(r<<2)+132|0;q=e[q>>1]|e[q+2>>1]<<16;A=c[s+(r>>>2<<2)+100>>2]|0;o=q&65535;z=1;q=q>>>16&65535}else{A=-1;o=0;z=1;q=0}else{A=-1;o=0;z=0;q=0}v=ub(a,c[5776+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;l=d[5776+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((v|0)!=0?(c[v+4>>2]|0)==(c[S>>2]|0):0)if((c[v>>2]|0)>>>0<6){p=v+(l<<2)+132|0;p=e[p>>1]|e[p+2>>1]<<16;y=1;x=c[v+(l>>>2<<2)+100>>2]|0;m=p&65535;p=p>>>16&65535}else{y=1;x=-1;m=0;p=0}else{y=0;x=-1;m=0;p=0}w=ub(a,c[5264+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;v=d[5264+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((w|0)!=0?(c[w+4>>2]|0)==(c[S>>2]|0):0)if((c[w>>2]|0)>>>0<6){z=w+(v<<2)+132|0;z=e[z>>1]|e[z+2>>1]<<16;v=c[w+(v>>>2<<2)+100>>2]|0;T=180}else{z=0;v=-1;T=180}else T=175;do if((T|0)==175){T=0;w=ub(a,c[4752+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;v=d[4752+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((w|0)!=0?(c[w+4>>2]|0)==(c[S>>2]|0):0){if((c[w>>2]|0)>>>0>=6){z=0;v=-1;T=180;break}z=w+(v<<2)+132|0;z=e[z>>1]|e[z+2>>1]<<16;v=c[w+(v>>>2<<2)+100>>2]|0;T=180;break}if((z|0)==0|(y|0)!=0){z=0;v=-1;T=180}else{v=o;t=q}}while(0);do if((T|0)==180){l=(A|0)==(n|0);w=(x|0)==(n|0);if(((w&1)+(l&1)+((v|0)==(n|0)&1)|0)==1){if(l|w){v=l?o:m;t=l?q:p;break}v=z&65535;t=z>>>16&65535;break}u=o<<16>>16;w=m<<16>>16;l=z<<16>>16;if(m<<16>>16>o<<16>>16)v=w;else{v=u;u=(w|0)<(u|0)?w:u}if((v|0)<(l|0))w=v;else w=(u|0)>(l|0)?u:l;t=q<<16>>16;v=p<<16>>16;l=z>>16;if(p<<16>>16>q<<16>>16)s=v;else{s=t;t=(v|0)<(t|0)?v:t}if((s|0)>=(l|0))s=(t|0)>(l|0)?t:l;v=w&65535;t=s&65535}while(0);C=(v&65535)+(C&65535)|0;q=C&65535;s=(t&65535)+(B&65535)|0;r=s&65535;if(((C<<16>>16)+8192|0)>>>0>16383){l=1;T=212;break c}if(((s<<16>>16)+2048|0)>>>0>4095){l=1;T=212;break c}if(!F){b[K>>1]=q;b[O>>1]=r;b[L>>1]=q;b[P>>1]=r;b[M>>1]=q;b[Q>>1]=r;b[N>>1]=q;b[R>>1]=r}else if((F|0)==1){F=(I<<1)+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r;F=F|1;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}else if((F|0)==2){F=I+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r;F=F+2|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}else if((F|0)==3){F=I+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}I=I+1|0}while(I>>>0>>0)}H=H+1|0;if(H>>>0>=4){T=201;break}}if((T|0)==201){o=0;do{c[W>>2]=c[a+(o<<2)+116>>2];m=hb(c[f+(o<<2)+176>>2]|0)|0;l=o<<3&8;n=o>>>0<2?0:8;if(!m)dc(k,a+(o<<2<<2)+132|0,W,V,U,l,n,8,8);else if((m|0)==1){G=o<<2;dc(k,a+(G<<2)+132|0,W,V,U,l,n,8,4);dc(k,a+((G|2)<<2)+132|0,W,V,U,l,n|4,8,4)}else if((m|0)==2){G=o<<2;dc(k,a+(G<<2)+132|0,W,V,U,l,n,4,8);dc(k,a+((G|1)<<2)+132|0,W,V,U,l|4,n,4,8)}else{E=o<<2;dc(k,a+(E<<2)+132|0,W,V,U,l,n,4,4);F=l|4;dc(k,a+((E|1)<<2)+132|0,W,V,U,F,n,4,4);G=n|4;dc(k,a+((E|2)<<2)+132|0,W,V,U,l,G,4,4);dc(k,a+((E|3)<<2)+132|0,W,V,U,F,G,4,4)}o=o+1|0}while((o|0)!=4)}else if((T|0)==212){i=X;return l|0}}while(0);if((c[a+196>>2]|0)>>>0>1){G=0;i=X;return G|0}if(!(c[a>>2]|0)){sc(j,k);G=0;i=X;return G|0}else{tc(j,h,k,f+328|0);G=0;i=X;return G|0}return 0}function Tb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0,D=0,E=0,F=0;B=i;i=i+144|0;m=B;if((e|0)>=0?!((e+1+k|0)>>>0>g>>>0|(f|0)<0|(l+f|0)>>>0>h>>>0):0)m=b;else{A=k+1|0;Ub(b,m,e,f,g,h,A,l,A);Ub(b+(Z(h,g)|0)|0,m+(Z(A,l)|0)|0,e,f,g,h,A,l,A);h=l;g=A;e=0;f=0}A=8-j|0;v=l>>>1;z=(v|0)==0;w=k>>>1;y=(w|0)==0;x=16-k|0;u=(g<<1)-k|0;s=g+1|0;t=g+2|0;p=w<<1;r=0;do{l=m+((Z((Z(r,h)|0)+f|0,g)|0)+e)|0;if(!(z|y)){q=c+(r<<6)|0;o=v;while(1){k=q;b=l;n=w;while(1){D=d[b>>0]|0;E=d[b+s>>0]|0;F=b;b=b+2|0;C=d[F+1>>0]|0;a[k+8>>0]=(((Z(E,j)|0)+(Z(d[F+g>>0]|0,A)|0)<<3)+32|0)>>>6;a[k>>0]=(((Z(C,j)|0)+(Z(D,A)|0)<<3)+32|0)>>>6;D=d[b>>0]|0;a[k+9>>0]=(((Z(d[F+t>>0]|0,j)|0)+(Z(E,A)|0)<<3)+32|0)>>>6;a[k+1>>0]=(((Z(D,j)|0)+(Z(C,A)|0)<<3)+32|0)>>>6;n=n+-1|0;if(!n)break;else k=k+2|0}o=o+-1|0;if(!o)break;else{q=q+(p+x)|0;l=l+(p+u)|0}}}r=r+1|0}while((r|0)!=2);i=B;return}function Ub(a,b,c,d,e,f,g,h,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;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;k=g+c|0;o=h+d|0;s=(c|0)<0|(k|0)>(e|0)?2:1;m=(o|0)<0?0-h|0:d;d=(k|0)<0?0-g|0:c;m=(m|0)>(f|0)?f:m;d=(d|0)>(e|0)?e:d;k=d+g|0;l=m+h|0;if((d|0)>0)a=a+d|0;if((m|0)>0)a=a+(Z(m,e)|0)|0;r=(d|0)<0?0-d|0:0;q=(k|0)>(e|0)?k-e|0:0;p=g-r-q|0;g=0-m|0;m=(m|0)<0?g:0;c=l-f|0;n=(l|0)>(f|0)?c:0;k=h-m|0;d=k-n|0;if(m){m=h+-1-((o|0)>0?o:0)|0;l=~f;l=(m|0)>(l|0)?m:l;m=~l;m=Z(l+((m|0)>0?m:0)+1|0,j)|0;l=b;while(1){xa[s&3](a,l,r,p,q);g=g+-1|0;if(!g)break;else l=l+j|0}b=b+m|0}if((k|0)!=(n|0)){l=h+-1|0;g=l-((o|0)>0?o:0)|0;k=~f;k=(g|0)>(k|0)?g:k;l=l-k|0;g=~k;g=h+f+-1-((l|0)<(f|0)?f:l)-k-((g|0)>0?g:0)|0;k=Z(g,j)|0;g=Z(g,e)|0;l=b;m=a;while(1){xa[s&3](m,l,r,p,q);d=d+-1|0;if(!d)break;else{l=l+j|0;m=m+e|0}}b=b+k|0;a=a+g|0}a=a+(0-e)|0;if(!n){i=t;return}while(1){xa[s&3](a,b,r,p,q);c=c+-1|0;if(!c)break;else b=b+j|0}i=t;return}function Vb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0,D=0,E=0;C=i;i=i+144|0;m=C;if(((e|0)>=0?!((k+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+1+l|0)>>>0<=h>>>0:0)m=b;else{A=l+1|0;Ub(b,m,e,f,g,h,k,A,k);Ub(b+(Z(h,g)|0)|0,m+(Z(A,k)|0)|0,e,f,g,h,k,A,k);h=A;g=k;e=0;f=0}B=8-j|0;w=l>>>1;A=(w|0)==0;x=k>>>1;z=(x|0)==0;y=16-k|0;v=g<<1;u=v-k|0;t=v|1;s=g+1|0;p=x<<1;r=0;do{l=m+((Z((Z(r,h)|0)+f|0,g)|0)+e)|0;if(!(A|z)){q=c+(r<<6)|0;o=w;while(1){k=q;b=l;n=x;while(1){D=d[b+g>>0]|0;E=d[b>>0]|0;a[k+8>>0]=(((Z(D,B)|0)+(Z(d[b+v>>0]|0,j)|0)<<3)+32|0)>>>6;a[k>>0]=(((Z(E,B)|0)+(Z(D,j)|0)<<3)+32|0)>>>6;D=d[b+s>>0]|0;E=d[b+1>>0]|0;a[k+9>>0]=(((Z(D,B)|0)+(Z(d[b+t>>0]|0,j)|0)<<3)+32|0)>>>6;a[k+1>>0]=(((Z(E,B)|0)+(Z(D,j)|0)<<3)+32|0)>>>6;n=n+-1|0;if(!n)break;else{k=k+2|0;b=b+2|0}}o=o+-1|0;if(!o)break;else{q=q+(p+y)|0;l=l+(p+u)|0}}}r=r+1|0}while((r|0)!=2);i=C;return}function Wb(b,c,e,f,g,h,j,k,l,m){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,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;I=i;i=i+176|0;n=I;if(((e|0)>=0?!((e+1+l|0)>>>0>g>>>0|(f|0)<0):0)?(f+1+m|0)>>>0<=h>>>0:0)n=b;else{B=l+1|0;A=m+1|0;Ub(b,n,e,f,g,h,B,A,B);Ub(b+(Z(h,g)|0)|0,n+(Z(A,B)|0)|0,e,f,g,h,B,A,B);h=A;g=B;e=0;f=0}G=8-j|0;H=8-k|0;B=m>>>1;E=(B|0)==0;A=g<<1;C=l>>>1;F=(C|0)==0;D=16-l|0;z=A-l|0;v=g+1|0;w=A|1;x=g+2|0;y=A+2|0;s=C<<1;u=0;do{l=n+((Z((Z(u,h)|0)+f|0,g)|0)+e)|0;if(!(E|F)){t=c+(u<<6)|0;r=B;while(1){p=d[l+g>>0]|0;m=t;b=l;o=(Z(p,k)|0)+(Z(d[l>>0]|0,H)|0)|0;p=(Z(d[l+A>>0]|0,k)|0)+(Z(p,H)|0)|0;q=C;while(1){K=d[b+v>>0]|0;J=(Z(K,k)|0)+(Z(d[b+1>>0]|0,H)|0)|0;K=(Z(d[b+w>>0]|0,k)|0)+(Z(K,H)|0)|0;M=((Z(o,G)|0)+32+(Z(J,j)|0)|0)>>>6;a[m+8>>0]=((Z(p,G)|0)+32+(Z(K,j)|0)|0)>>>6;a[m>>0]=M;M=b;b=b+2|0;L=d[M+x>>0]|0;o=(Z(L,k)|0)+(Z(d[b>>0]|0,H)|0)|0;p=(Z(d[M+y>>0]|0,k)|0)+(Z(L,H)|0)|0;J=((Z(J,G)|0)+32+(Z(o,j)|0)|0)>>>6;a[m+9>>0]=((Z(K,G)|0)+32+(Z(p,j)|0)|0)>>>6;a[m+1>>0]=J;q=q+-1|0;if(!q)break;else m=m+2|0}r=r+-1|0;if(!r)break;else{t=t+(s+D)|0;l=l+(s+z)|0}}}u=u+1|0}while((u|0)!=2);i=I;return}function Xb(b,c,e,f,g,h,j,k){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var 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;r=i;i=i+448|0;l=r;if(((e|0)>=0?!((j+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)l=b;else{Ub(b,l,e,f,g,h,j,k+5|0,j);g=j;e=0;f=0}h=e+g+(Z(f,g)|0)|0;b=k>>>2;if(!b){i=r;return}n=g<<2;q=0-g|0;o=q<<1;p=g<<1;if(!j){i=r;return}else{m=l+h|0;e=l+(h+(g*5|0))|0}while(1){l=j;h=c;k=m;f=e;while(1){u=d[f+o>>0]|0;v=d[f+q>>0]|0;w=d[f+g>>0]|0;y=d[f>>0]|0;x=w+u|0;s=d[k+p>>0]|0;a[h+48>>0]=a[((d[f+p>>0]|0)+16-x-(x<<2)+s+((y+v|0)*20|0)>>5)+3984>>0]|0;x=s+y|0;t=d[k+g>>0]|0;a[h+32>>0]=a[(w+16-x-(x<<2)+t+((v+u|0)*20|0)>>5)+3984>>0]|0;x=t+v|0;w=d[k>>0]|0;a[h+16>>0]=a[(y+16-x-(x<<2)+w+((s+u|0)*20|0)>>5)+3984>>0]|0;u=w+u|0;a[h>>0]=a[(v+16-u-(u<<2)+(d[k+q>>0]|0)+((t+s|0)*20|0)>>5)+3984>>0]|0;l=l+-1|0;if(!l)break;else{h=h+1|0;k=k+1|0;f=f+1|0}}b=b+-1|0;if(!b)break;else{c=c+64|0;m=m+n|0;e=e+n|0}}i=r;return}function Yb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0;v=i;i=i+448|0;m=v;if(((e|0)>=0?!((j+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)m=b;else{Ub(b,m,e,f,g,h,j,k+5|0,j);g=j;e=0;f=0}h=e+g+(Z(f,g)|0)|0;b=k>>>2;if(!b){i=v;return}u=(j|0)==0;s=(g<<2)-j|0;t=64-j|0;r=0-g|0;p=r<<1;q=g<<1;e=m+h|0;f=m+(h+(Z(g,l+2|0)|0))|0;m=m+(h+(g*5|0))|0;while(1){if(u){h=c;k=f}else{k=f+j|0;h=c+j|0;l=j;o=e;n=m;while(1){y=d[n+p>>0]|0;z=d[n+r>>0]|0;A=d[n+g>>0]|0;C=d[n>>0]|0;B=A+y|0;w=d[o+q>>0]|0;a[c+48>>0]=((d[((d[n+q>>0]|0)+16-B-(B<<2)+w+((C+z|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+q>>0]|0)|0)>>>1;B=w+C|0;x=d[o+g>>0]|0;a[c+32>>0]=((d[(A+16-B-(B<<2)+x+((z+y|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+g>>0]|0)|0)>>>1;B=x+z|0;A=d[o>>0]|0;a[c+16>>0]=((d[(C+16-B-(B<<2)+A+((w+y|0)*20|0)>>5)+3984>>0]|0)+1+(d[f>>0]|0)|0)>>>1;y=A+y|0;a[c>>0]=((d[(z+16-y-(y<<2)+(d[o+r>>0]|0)+((x+w|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+r>>0]|0)|0)>>>1;l=l+-1|0;if(!l)break;else{c=c+1|0;o=o+1|0;f=f+1|0;n=n+1|0}}e=e+j|0;m=m+j|0}b=b+-1|0;if(!b)break;else{c=h+t|0;e=e+s|0;f=k+s|0;m=m+s|0}}i=v;return}function Zb(b,c,e,f,g,h,j,k){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;u=i;i=i+448|0;l=u;if((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0|(k+f|0)>>>0>h>>>0):0)l=b;else{n=j+5|0;Ub(b,l,e,f,g,h,n,k,n);g=n;e=0;f=0}if(!k){i=u;return}r=j>>>2;t=(r|0)==0;s=g-j|0;q=16-j|0;p=r<<2;b=c;l=l+(e+5+(Z(f,g)|0))|0;o=k;while(1){if(t)h=b;else{h=b+p|0;e=l;g=d[l+-1>>0]|0;k=d[l+-2>>0]|0;m=d[l+-3>>0]|0;n=d[l+-4>>0]|0;j=d[l+-5>>0]|0;c=r;while(1){f=n+g|0;v=n;n=d[e>>0]|0;a[b>>0]=a[(j+16-f-(f<<2)+n+((m+k|0)*20|0)>>5)+3984>>0]|0;j=n+m|0;f=m;m=d[e+1>>0]|0;a[b+1>>0]=a[(v+16-j-(j<<2)+m+((k+g|0)*20|0)>>5)+3984>>0]|0;j=m+k|0;v=k;k=d[e+2>>0]|0;a[b+2>>0]=a[(f+16-j-(j<<2)+k+((n+g|0)*20|0)>>5)+3984>>0]|0;j=k+g|0;f=d[e+3>>0]|0;a[b+3>>0]=a[(v+16-j-(j<<2)+f+((m+n|0)*20|0)>>5)+3984>>0]|0;c=c+-1|0;if(!c)break;else{j=g;b=b+4|0;e=e+4|0;g=f}}l=l+p|0}o=o+-1|0;if(!o)break;else{b=h+q|0;l=l+s|0}}i=u;return}function _b(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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;v=i;i=i+448|0;m=v;if((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0|(k+f|0)>>>0>h>>>0):0)m=b;else{o=j+5|0;Ub(b,m,e,f,g,h,o,k,o);g=o;e=0;f=0}if(!k){i=v;return}s=j>>>2;u=(s|0)==0;t=g-j|0;r=16-j|0;q=(l|0)!=0;p=s<<2;b=c;m=m+(e+5+(Z(f,g)|0))|0;while(1){if(u)h=b;else{h=b+p|0;l=m;e=d[m+-1>>0]|0;g=d[m+-2>>0]|0;n=d[m+-3>>0]|0;o=d[m+-4>>0]|0;j=d[m+-5>>0]|0;c=s;while(1){f=o+e|0;w=o;o=d[l>>0]|0;a[b>>0]=((q?g:n)+1+(d[(j+16-f-(f<<2)+o+((n+g|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=o+n|0;f=n;n=d[l+1>>0]|0;a[b+1>>0]=((q?e:g)+1+(d[(w+16-j-(j<<2)+n+((g+e|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=n+g|0;w=g;g=d[l+2>>0]|0;a[b+2>>0]=((q?o:e)+1+(d[(f+16-j-(j<<2)+g+((o+e|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=g+e|0;f=d[l+3>>0]|0;a[b+3>>0]=((q?n:o)+1+(d[(w+16-j-(j<<2)+f+((n+o|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;c=c+-1|0;if(!c)break;else{j=e;b=b+4|0;l=l+4|0;e=f}}m=m+p|0}k=k+-1|0;if(!k)break;else{b=h+r|0;m=m+t|0}}i=v;return}function $b(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0;z=i;i=i+448|0;m=z;if(((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)m=b;else{y=j+5|0;Ub(b,m,e,f,g,h,y,k+5|0,y);g=y;e=0;f=0}b=(Z(f,g)|0)+e|0;y=(l&1|2)+g+b|0;n=m+y|0;if(!k){i=z;return}u=j>>>2;w=(u|0)==0;v=g-j|0;x=16-j|0;t=u<<2;b=m+((Z(g,l>>>1&1|2)|0)+5+b)|0;s=k;while(1){if(!w){r=c+t|0;h=b;e=d[b+-1>>0]|0;f=d[b+-2>>0]|0;o=d[b+-3>>0]|0;p=d[b+-4>>0]|0;l=d[b+-5>>0]|0;q=u;while(1){A=p+e|0;B=p;p=d[h>>0]|0;a[c>>0]=a[(l+16-A-(A<<2)+p+((o+f|0)*20|0)>>5)+3984>>0]|0;A=p+o|0;l=o;o=d[h+1>>0]|0;a[c+1>>0]=a[(B+16-A-(A<<2)+o+((f+e|0)*20|0)>>5)+3984>>0]|0;A=o+f|0;B=f;f=d[h+2>>0]|0;a[c+2>>0]=a[(l+16-A-(A<<2)+f+((p+e|0)*20|0)>>5)+3984>>0]|0;A=f+e|0;l=d[h+3>>0]|0;a[c+3>>0]=a[(B+16-A-(A<<2)+l+((o+p|0)*20|0)>>5)+3984>>0]|0;q=q+-1|0;if(!q)break;else{A=e;c=c+4|0;h=h+4|0;e=l;l=A}}c=r;b=b+t|0}s=s+-1|0;if(!s)break;else{c=c+x|0;b=b+v|0}}b=k>>>2;if(!b){i=z;return}t=(j|0)==0;p=(g<<2)-j|0;o=64-j|0;q=0-g|0;s=q<<1;r=g<<1;c=c+(x-(k<<4))|0;h=m+(y+(g*5|0))|0;l=b;while(1){if(t){b=c;m=n}else{b=c+j|0;m=c;e=n;f=h;c=j;while(1){x=d[f+s>>0]|0;w=d[f+q>>0]|0;u=d[f+g>>0]|0;B=d[f>>0]|0;y=u+x|0;k=d[e+r>>0]|0;A=m+48|0;a[A>>0]=((d[((d[f+r>>0]|0)+16-y-(y<<2)+k+((B+w|0)*20|0)>>5)+3984>>0]|0)+1+(d[A>>0]|0)|0)>>>1;A=k+B|0;y=d[e+g>>0]|0;v=m+32|0;a[v>>0]=((d[(u+16-A-(A<<2)+y+((w+x|0)*20|0)>>5)+3984>>0]|0)+1+(d[v>>0]|0)|0)>>>1;v=d[e>>0]|0;A=y+w|0;u=m+16|0;a[u>>0]=((d[(B+16-A-(A<<2)+v+((k+x|0)*20|0)>>5)+3984>>0]|0)+1+(d[u>>0]|0)|0)>>>1;x=v+x|0;a[m>>0]=((d[(w+16-x-(x<<2)+(d[e+q>>0]|0)+((y+k|0)*20|0)>>5)+3984>>0]|0)+1+(d[m>>0]|0)|0)>>>1;c=c+-1|0;if(!c)break;else{m=m+1|0;e=e+1|0;f=f+1|0}}m=n+j|0;h=h+j|0}l=l+-1|0;if(!l)break;else{c=b+o|0;n=m+p|0;h=h+p|0}}i=z;return}function ac(b,e,f,g,h,j,k,l){b=b|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0;x=i;i=i+1792|0;m=x+1344|0;w=x;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0){o=l+5|0;m=b;n=f+5|0}else{n=k+5|0;o=l+5|0;Ub(b,m,f,g,h,j,n,o,n);h=n;n=5;g=0}if(o){t=k>>>2;v=(t|0)==0;s=h-k|0;u=t<<2;f=w;m=m+(n+(Z(g,h)|0))|0;while(1){if(v)b=f;else{b=f+(u<<2)|0;g=m;h=d[m+-1>>0]|0;j=d[m+-2>>0]|0;p=d[m+-3>>0]|0;q=d[m+-4>>0]|0;n=d[m+-5>>0]|0;r=t;while(1){y=q+h|0;z=q;q=d[g>>0]|0;c[f>>2]=n-y-(y<<2)+q+((p+j|0)*20|0);y=q+p|0;n=p;p=d[g+1>>0]|0;c[f+4>>2]=z-y+p-(y<<2)+((j+h|0)*20|0);y=p+j|0;z=j;j=d[g+2>>0]|0;c[f+8>>2]=n-y+j-(y<<2)+((q+h|0)*20|0);y=j+h|0;n=d[g+3>>0]|0;c[f+12>>2]=z-y+n-(y<<2)+((p+q|0)*20|0);r=r+-1|0;if(!r)break;else{y=h;f=f+16|0;g=g+4|0;h=n;n=y}}m=m+u|0}o=o+-1|0;if(!o)break;else{f=b;m=m+s|0}}}h=l>>>2;if(!h){i=x;return}u=(k|0)==0;s=64-k|0;p=k*3|0;t=0-k|0;q=t<<1;r=k<<1;g=e;b=w+(k<<2)|0;m=w+(k*6<<2)|0;o=h;while(1){if(u)h=g;else{h=g+k|0;f=b;j=m;n=k;while(1){e=c[j+(q<<2)>>2]|0;w=c[j+(t<<2)>>2]|0;z=c[j+(k<<2)>>2]|0;A=c[j>>2]|0;y=z+e|0;v=c[f+(r<<2)>>2]|0;a[g+48>>0]=a[((c[j+(r<<2)>>2]|0)+512-y-(y<<2)+v+((A+w|0)*20|0)>>10)+3984>>0]|0;y=v+A|0;l=c[f+(k<<2)>>2]|0;a[g+32>>0]=a[(z+512-y-(y<<2)+l+((w+e|0)*20|0)>>10)+3984>>0]|0;y=c[f>>2]|0;z=l+w|0;a[g+16>>0]=a[(A+512-z-(z<<2)+y+((v+e|0)*20|0)>>10)+3984>>0]|0;e=y+e|0;a[g>>0]=a[(w+512-e-(e<<2)+(c[f+(t<<2)>>2]|0)+((l+v|0)*20|0)>>10)+3984>>0]|0;n=n+-1|0;if(!n)break;else{g=g+1|0;f=f+4|0;j=j+4|0}}b=b+(k<<2)|0;m=m+(k<<2)|0}o=o+-1|0;if(!o)break;else{g=h+s|0;b=b+(p<<2)|0;m=m+(p<<2)|0}}i=x;return}function bc(b,e,f,g,h,j,k,l,m){b=b|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0;y=i;i=i+1792|0;n=y+1344|0;x=y;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0){o=l+5|0;n=b;f=f+5|0}else{q=k+5|0;o=l+5|0;Ub(b,n,f,g,h,j,q,o,q);h=q;f=5;g=0}if(o){v=k>>>2;t=(v|0)==0;u=h-k|0;w=v<<2;p=x;n=n+(f+(Z(g,h)|0))|0;s=o;while(1){if(t)b=p;else{b=p+(w<<2)|0;g=n;f=d[n+-1>>0]|0;h=d[n+-2>>0]|0;j=d[n+-3>>0]|0;q=d[n+-4>>0]|0;o=d[n+-5>>0]|0;r=v;while(1){z=q+f|0;A=q;q=d[g>>0]|0;c[p>>2]=o-z-(z<<2)+q+((j+h|0)*20|0);z=q+j|0;o=j;j=d[g+1>>0]|0;c[p+4>>2]=A-z+j-(z<<2)+((h+f|0)*20|0);z=j+h|0;A=h;h=d[g+2>>0]|0;c[p+8>>2]=o-z+h-(z<<2)+((q+f|0)*20|0);z=h+f|0;o=d[g+3>>0]|0;c[p+12>>2]=A-z+o-(z<<2)+((j+q|0)*20|0);r=r+-1|0;if(!r)break;else{z=f;p=p+16|0;g=g+4|0;f=o;o=z}}n=n+w|0}s=s+-1|0;if(!s)break;else{p=b;n=n+u|0}}}f=l>>>2;if(!f){i=y;return}w=(k|0)==0;u=64-k|0;q=k*3|0;v=0-k|0;t=v<<1;s=k<<1;b=x+(k<<2)|0;n=x+((Z(m+2|0,k)|0)+k<<2)|0;h=x+(k*6<<2)|0;r=f;while(1){if(w){g=e;f=n}else{f=n+(k<<2)|0;g=e+k|0;p=b;j=h;o=k;while(1){m=c[j+(t<<2)>>2]|0;l=c[j+(v<<2)>>2]|0;B=c[j+(k<<2)>>2]|0;C=c[j>>2]|0;A=B+m|0;z=c[p+(s<<2)>>2]|0;a[e+48>>0]=((d[((c[j+(s<<2)>>2]|0)+512-A-(A<<2)+z+((C+l|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(s<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;A=z+C|0;x=c[p+(k<<2)>>2]|0;a[e+32>>0]=((d[(B+512-A-(A<<2)+x+((l+m|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(k<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;A=c[p>>2]|0;B=x+l|0;a[e+16>>0]=((d[(C+512-B-(B<<2)+A+((z+m|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=A+m|0;a[e>>0]=((d[(l+512-m-(m<<2)+(c[p+(v<<2)>>2]|0)+((x+z|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(v<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;o=o+-1|0;if(!o)break;else{e=e+1|0;p=p+4|0;n=n+4|0;j=j+4|0}}b=b+(k<<2)|0;h=h+(k<<2)|0}r=r+-1|0;if(!r)break;else{e=g+u|0;b=b+(q<<2)|0;n=f+(q<<2)|0;h=h+(q<<2)|0}}i=y;return}function cc(b,e,f,g,h,j,k,l,m){b=b|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;B=i;i=i+1792|0;n=B+1344|0;A=B;z=k+5|0;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0)n=b;else{Ub(b,n,f,g,h,j,z,l+5|0,z);h=z;f=0;g=0}s=f+h+(Z(g,h)|0)|0;g=l>>>2;if(g){y=(z|0)==0;x=(h<<2)-k+-5|0;t=z*3|0;p=0-h|0;w=p<<1;v=h<<1;u=z<<1;q=-5-k|0;j=A+(z<<2)|0;r=n+s|0;f=n+(s+(h*5|0))|0;while(1){if(y)s=j;else{s=j+(z<<2)|0;n=r;b=f;o=z;while(1){E=d[b+w>>0]|0;F=d[b+p>>0]|0;H=d[b+h>>0]|0;I=d[b>>0]|0;G=H+E|0;C=d[n+v>>0]|0;c[j+(u<<2)>>2]=(d[b+v>>0]|0)-G-(G<<2)+C+((I+F|0)*20|0);G=C+I|0;D=d[n+h>>0]|0;c[j+(z<<2)>>2]=H-G+D-(G<<2)+((F+E|0)*20|0);G=d[n>>0]|0;H=D+F|0;c[j>>2]=I-H+G-(H<<2)+((C+E|0)*20|0);E=G+E|0;c[j+(q<<2)>>2]=F-E+(d[n+p>>0]|0)-(E<<2)+((D+C|0)*20|0);o=o+-1|0;if(!o)break;else{j=j+4|0;n=n+1|0;b=b+1|0}}r=r+z|0;f=f+z|0}g=g+-1|0;if(!g)break;else{j=s+(t<<2)|0;r=r+x|0;f=f+x|0}}}if(!l){i=B;return}v=k>>>2;w=(v|0)==0;u=16-k|0;t=v<<2;h=A+(m+2<<2)|0;g=A+20|0;while(1){if(w)f=h;else{f=h+(t<<2)|0;s=e;n=g;j=c[g+-4>>2]|0;o=c[g+-8>>2]|0;p=c[g+-12>>2]|0;q=c[g+-16>>2]|0;b=c[g+-20>>2]|0;r=v;while(1){m=q+j|0;k=q;q=c[n>>2]|0;a[s>>0]=((d[(b+512-m-(m<<2)+q+((p+o|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=q+p|0;b=p;p=c[n+4>>2]|0;a[s+1>>0]=((d[(k+512-m-(m<<2)+p+((o+j|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+4>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=p+o|0;k=o;o=c[n+8>>2]|0;a[s+2>>0]=((d[(b+512-m-(m<<2)+o+((q+j|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+8>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=o+j|0;b=c[n+12>>2]|0;a[s+3>>0]=((d[(k+512-m-(m<<2)+b+((p+q|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+12>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;r=r+-1|0;if(!r)break;else{m=j;s=s+4|0;h=h+16|0;n=n+16|0;j=b;b=m}}e=e+t|0;g=g+(t<<2)|0}l=l+-1|0;if(!l)break;else{e=e+u|0;h=f+20|0;g=g+20|0}}i=B;return}function dc(a,d,e,f,g,h,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|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;x=i;q=a+((j<<4)+h)|0;u=b[d>>1]|0;w=d+2|0;t=b[w>>1]|0;s=e+4|0;p=c[s>>2]<<4;r=e+8|0;o=c[r>>2]<<4;f=h+f|0;m=f+(u>>2)|0;g=j+g|0;n=g+(t>>2)|0;do switch(c[6800+((u&3)<<4)+((t&3)<<2)>>2]|0){case 10:{ac(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l);break}case 6:{cc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 4:{_b(c[e>>2]|0,q,m+-2|0,n,p,o,k,l,0);break}case 1:{Yb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l,0);break}case 2:{Xb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l);break}case 12:{_b(c[e>>2]|0,q,m+-2|0,n,p,o,k,l,1);break}case 14:{cc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}case 7:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,2);break}case 13:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}case 5:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 0:{Ub(c[e>>2]|0,q,m,n,p,o,k,l,16);break}case 9:{bc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 8:{Zb(c[e>>2]|0,q,m+-2|0,n,p,o,k,l);break}case 3:{Yb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l,1);break}case 11:{bc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}default:$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,3)}while(0);u=(h>>>1)+256+(j>>>1<<3)|0;v=a+u|0;t=c[e>>2]|0;m=c[s>>2]|0;j=c[r>>2]|0;r=m<<3;s=j<<3;p=b[d>>1]|0;e=(p>>3)+(f>>>1)|0;q=b[w>>1]|0;o=(q>>3)+(g>>>1)|0;p=p&7;q=q&7;g=k>>>1;h=l>>>1;j=Z(m<<8,j)|0;f=t+j|0;m=(p|0)!=0;n=(q|0)!=0;if(m&n){Wb(f,v,e,o,r,s,p,q,g,h);i=x;return}if(m){Tb(f,v,e,o,r,s,p,g,h);i=x;return}if(n){Vb(f,v,e,o,r,s,q,g,h);i=x;return}else{Ub(f,v,e,o,r,s,g,h,8);Ub(t+((Z(s,r)|0)+j)|0,a+(u+64)|0,e,o,r,s,g,h,8);i=x;return}}function ec(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,j=0;j=i;if(d){nd(c|0,a[b>>0]|0,d|0)|0;c=c+d|0}if(e){h=c+e|0;g=e;d=b;while(1){a[c>>0]=a[d>>0]|0;g=g+-1|0;if(!g)break;else{c=c+1|0;d=d+1|0}}c=h;b=b+e|0}if(!f){i=j;return}nd(c|0,a[b+-1>>0]|0,f|0)|0;i=j;return}function fc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;c=i;hd(b,a,d);i=c;return}function gc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;f=c[a+40>>2]|0;if(f){h=c[a>>2]|0;k=a+32|0;j=0;do{if(((c[h+(j*40|0)+20>>2]|0)+-1|0)>>>0<2){g=c[h+(j*40|0)+12>>2]|0;if(g>>>0>d>>>0)g=g-(c[k>>2]|0)|0;c[h+(j*40|0)+8>>2]=g}j=j+1|0}while((j|0)!=(f|0))}if(!(c[b>>2]|0)){p=0;i=q;return p|0}g=c[b+4>>2]|0;if(g>>>0>=3){p=0;i=q;return p|0}o=a+32|0;p=a+24|0;n=a+4|0;f=d;m=0;a:while(1){b:do if(g>>>0<2){k=c[b+(m*12|0)+8>>2]|0;if(!g){g=f-k|0;if((g|0)<0)g=(c[o>>2]|0)+g|0}else{l=k+f|0;g=c[o>>2]|0;g=l-((l|0)<(g|0)?0:g)|0}if(g>>>0>d>>>0)f=g-(c[o>>2]|0)|0;else f=g;j=c[p>>2]|0;if(!j){f=1;g=37;break a}k=c[a>>2]|0;l=0;while(1){h=c[k+(l*40|0)+20>>2]|0;if((h+-1|0)>>>0<2?(c[k+(l*40|0)+8>>2]|0)==(f|0):0){f=g;break b}l=l+1|0;if(l>>>0>=j>>>0){f=1;g=37;break a}}}else{j=c[b+(m*12|0)+12>>2]|0;h=c[p>>2]|0;if(!h){f=1;g=37;break a}k=c[a>>2]|0;g=0;while(1){if((c[k+(g*40|0)+20>>2]|0)==3?(c[k+(g*40|0)+8>>2]|0)==(j|0):0){h=3;l=g;break b}g=g+1|0;if(g>>>0>=h>>>0){f=1;g=37;break a}}}while(0);if(!((l|0)>-1&h>>>0>1)){f=1;g=37;break}if(m>>>0>>0){k=e;do{j=k;k=k+-1|0;h=c[n>>2]|0;c[h+(j<<2)>>2]=c[h+(k<<2)>>2]}while(k>>>0>m>>>0);k=c[a>>2]|0}c[(c[n>>2]|0)+(m<<2)>>2]=k+(l*40|0);m=m+1|0;if(m>>>0<=e>>>0){g=m;k=m;do{j=c[n>>2]|0;h=c[j+(g<<2)>>2]|0;if((h|0)!=((c[a>>2]|0)+(l*40|0)|0)){c[j+(k<<2)>>2]=h;k=k+1|0}g=g+1|0}while(g>>>0<=e>>>0)}g=c[b+(m*12|0)+4>>2]|0;if(g>>>0>=3){f=0;g=37;break}}if((g|0)==37){i=q;return f|0}return 0}function hc(a,b,d,e,f,g,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var 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,G=0,H=0,I=0,J=0,K=0;K=i;I=c[d>>2]|0;J=c[a+8>>2]|0;if((I|0)!=(c[J>>2]|0)){D=1;i=K;return D|0}B=a+52|0;c[B>>2]=0;G=c[a+56>>2]|0;o=(G|0)==0;H=o&1;do if(!b){c[J+20>>2]=0;c[J+12>>2]=e;c[J+8>>2]=e;c[J+16>>2]=f;c[J+24>>2]=H;if(o){d=a+44|0;c[d>>2]=(c[d>>2]|0)+1;d=0;r=0}else{d=G;r=0}}else{if(g){k=a+20|0;c[k>>2]=0;l=a+16|0;c[l>>2]=0;r=c[a>>2]|0;s=a+44|0;q=0;do{p=r+(q*40|0)+20|0;if((c[p>>2]|0)!=0?(c[p>>2]=0,(c[r+(q*40|0)+24>>2]|0)==0):0)c[s>>2]=(c[s>>2]|0)+-1;q=q+1|0}while((q|0)!=16);a:do if(o){n=c[a+28>>2]|0;m=a+12|0;q=0;while(1){e=0;p=2147483647;o=0;do{if(c[r+(e*40|0)+24>>2]|0){C=c[r+(e*40|0)+16>>2]|0;D=(C|0)<(p|0);p=D?C:p;o=D?r+(e*40|0)|0:o}e=e+1|0}while(e>>>0<=n>>>0);if(!o){d=0;break a}D=c[m>>2]|0;c[D+(q<<4)>>2]=c[o>>2];c[D+(q<<4)+12>>2]=c[o+36>>2];c[D+(q<<4)+4>>2]=c[o+28>>2];c[D+(q<<4)+8>>2]=c[o+32>>2];q=q+1|0;c[l>>2]=q;c[o+24>>2]=0;if(c[o+20>>2]|0)continue;c[s>>2]=(c[s>>2]|0)+-1}}else d=G;while(0);p=a+40|0;c[p>>2]=0;o=a+36|0;c[o>>2]=65535;c[a+48>>2]=0;if(!(c[b>>2]|d))d=0;else{c[l>>2]=0;c[k>>2]=0}r=(c[b+4>>2]|0)==0;c[J+20>>2]=r?2:3;c[o>>2]=r?65535:0;c[J+12>>2]=0;c[J+8>>2]=0;c[J+16>>2]=0;c[J+24>>2]=H;c[s>>2]=1;c[p>>2]=1;r=0;break}if(!(c[b+8>>2]|0)){d=a+40|0;q=c[d>>2]|0;p=c[a+24>>2]|0;if(q>>>0>=p>>>0)if(q){l=c[a>>2]|0;m=0;o=-1;n=0;do{if(((c[l+(m*40|0)+20>>2]|0)+-1|0)>>>0<2){D=c[l+(m*40|0)+8>>2]|0;C=(D|0)<(n|0)|(o|0)==-1;o=C?m:o;n=C?D:n}m=m+1|0}while((m|0)!=(q|0));if((o|0)>-1){q=q+-1|0;c[l+(o*40|0)+20>>2]=0;c[d>>2]=q;if(!(c[l+(o*40|0)+24>>2]|0)){d=a+44|0;c[d>>2]=(c[d>>2]|0)+-1;d=G;n=0}else{d=G;n=0}}else{d=G;n=1}}else{q=0;d=G;n=1}else{d=G;n=0}}else{E=a+24|0;C=a+40|0;v=a+44|0;x=a+36|0;A=a+48|0;u=a+28|0;y=a+16|0;z=a+12|0;r=G;d=G;t=0;w=0;b:while(1){switch(c[b+(t*20|0)+12>>2]|0){case 4:{l=c[b+(t*20|0)+28>>2]|0;c[x>>2]=l;m=c[E>>2]|0;if(!m)s=w;else{n=c[a>>2]|0;s=l;o=0;do{k=n+(o*40|0)+20|0;do if((c[k>>2]|0)==3){if((c[n+(o*40|0)+8>>2]|0)>>>0<=l>>>0)if((s|0)==65535)s=65535;else break;c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[n+(o*40|0)+24>>2]|0))c[v>>2]=(c[v>>2]|0)+-1}while(0);o=o+1|0}while((o|0)!=(m|0));s=w}break}case 1:{n=e-(c[b+(t*20|0)+16>>2]|0)|0;l=c[E>>2]|0;if(!l){n=1;break b}m=c[a>>2]|0;s=0;while(1){k=m+(s*40|0)+20|0;if(((c[k>>2]|0)+-1|0)>>>0<2?(c[m+(s*40|0)+8>>2]|0)==(n|0):0)break;s=s+1|0;if(s>>>0>=l>>>0){n=1;break b}}if((s|0)<0){n=1;break b}c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[m+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=w}else s=w;break}case 6:{m=c[b+(t*20|0)+24>>2]|0;s=c[x>>2]|0;if((s|0)==65535|s>>>0>>0){n=1;F=101;break b}r=c[E>>2]|0;c:do if(r){l=c[a>>2]|0;s=0;while(1){k=l+(s*40|0)+20|0;if((c[k>>2]|0)==3?(c[l+(s*40|0)+8>>2]|0)==(m|0):0)break;s=s+1|0;if(s>>>0>=r>>>0){F=88;break c}}c[k>>2]=0;k=(c[C>>2]|0)+-1|0;c[C>>2]=k;if(!(c[l+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=k}else s=k}else{r=0;F=88}while(0);if((F|0)==88){F=0;s=c[C>>2]|0}if(s>>>0>=r>>>0){n=1;F=101;break b}c[J+12>>2]=e;c[J+8>>2]=m;c[J+16>>2]=f;c[J+20>>2]=3;c[J+24>>2]=H;c[C>>2]=s+1;c[v>>2]=(c[v>>2]|0)+1;r=G;d=G;s=1;break}case 2:{l=c[b+(t*20|0)+20>>2]|0;m=c[E>>2]|0;if(!m){n=1;break b}n=c[a>>2]|0;s=0;while(1){k=n+(s*40|0)+20|0;if((c[k>>2]|0)==3?(c[n+(s*40|0)+8>>2]|0)==(l|0):0)break;s=s+1|0;if(s>>>0>=m>>>0){n=1;break b}}if((s|0)<0){n=1;break b}c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[n+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=w}else s=w;break}case 3:{s=c[b+(t*20|0)+16>>2]|0;n=c[b+(t*20|0)+24>>2]|0;k=c[x>>2]|0;if((k|0)==65535|k>>>0>>0){n=1;break b}o=c[E>>2]|0;if(!o){n=1;break b}p=c[a>>2]|0;k=0;while(1){m=p+(k*40|0)+20|0;if((c[m>>2]|0)==3?(c[p+(k*40|0)+8>>2]|0)==(n|0):0){F=47;break}l=k+1|0;if(l>>>0>>0)k=l;else break}if((F|0)==47?(F=0,c[m>>2]=0,c[C>>2]=(c[C>>2]|0)+-1,(c[p+(k*40|0)+24>>2]|0)==0):0)c[v>>2]=(c[v>>2]|0)+-1;m=e-s|0;s=0;while(1){l=p+(s*40|0)+20|0;k=c[l>>2]|0;if((k+-1|0)>>>0<2?(D=p+(s*40|0)+8|0,(c[D>>2]|0)==(m|0)):0)break;s=s+1|0;if(s>>>0>=o>>>0){n=1;break b}}if(!((s|0)>-1&k>>>0>1)){n=1;break b}c[l>>2]=3;c[D>>2]=n;s=w;break}case 5:{n=c[a>>2]|0;q=0;do{p=n+(q*40|0)+20|0;if((c[p>>2]|0)!=0?(c[p>>2]=0,(c[n+(q*40|0)+24>>2]|0)==0):0)c[v>>2]=(c[v>>2]|0)+-1;q=q+1|0}while((q|0)!=16);d:do if(!d){l=c[u>>2]|0;m=r;while(1){d=0;s=2147483647;k=0;do{if(c[n+(d*40|0)+24>>2]|0){o=c[n+(d*40|0)+16>>2]|0;e=(o|0)<(s|0);s=e?o:s;k=e?n+(d*40|0)|0:k}d=d+1|0}while(d>>>0<=l>>>0);if(!k){r=m;d=0;break d}s=c[y>>2]|0;d=c[z>>2]|0;c[d+(s<<4)>>2]=c[k>>2];c[d+(s<<4)+12>>2]=c[k+36>>2];c[d+(s<<4)+4>>2]=c[k+28>>2];c[d+(s<<4)+8>>2]=c[k+32>>2];c[y>>2]=s+1;c[k+24>>2]=0;if(!(c[k+20>>2]|0))c[v>>2]=(c[v>>2]|0)+-1;if(!m)m=0;else{r=m;d=m;break}}}while(0);c[C>>2]=0;c[x>>2]=65535;c[A>>2]=0;c[B>>2]=1;e=0;s=w;break}case 0:{n=0;F=101;break b}default:{n=1;break b}}t=t+1|0;w=s}if(w){r=n;break}q=c[C>>2]|0;p=c[E>>2]|0}if(q>>>0

>>0){c[J+12>>2]=e;c[J+8>>2]=e;c[J+16>>2]=f;c[J+20>>2]=2;c[J+24>>2]=H;r=a+44|0;c[r>>2]=(c[r>>2]|0)+1;c[a+40>>2]=q+1;r=n}else r=1}while(0);c[J+36>>2]=g;c[J+28>>2]=h;c[J+32>>2]=j;if(!d){o=a+44|0;d=c[o>>2]|0;k=c[a+28>>2]|0;if(d>>>0>k>>>0){p=a+16|0;q=a+12|0;do{n=c[a>>2]|0;e=0;l=2147483647;m=0;do{if(c[n+(e*40|0)+24>>2]|0){C=c[n+(e*40|0)+16>>2]|0;D=(C|0)<(l|0);l=D?C:l;m=D?n+(e*40|0)|0:m}e=e+1|0}while(e>>>0<=k>>>0);if((m|0)!=0?(D=c[p>>2]|0,C=c[q>>2]|0,c[C+(D<<4)>>2]=c[m>>2],c[C+(D<<4)+12>>2]=c[m+36>>2],c[C+(D<<4)+4>>2]=c[m+28>>2],c[C+(D<<4)+8>>2]=c[m+32>>2],c[p>>2]=D+1,c[m+24>>2]=0,(c[m+20>>2]|0)==0):0){d=d+-1|0;c[o>>2]=d}}while(d>>>0>k>>>0)}}else{k=a+16|0;D=c[k>>2]|0;C=c[a+12>>2]|0;c[C+(D<<4)>>2]=I;c[C+(D<<4)+12>>2]=g;c[C+(D<<4)+4>>2]=h;c[C+(D<<4)+8>>2]=j;c[k>>2]=D+1;k=c[a+28>>2]|0}rc(c[a>>2]|0,k+1|0);D=r;i=K;return D|0}function ic(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;if((b>>>0<=16?(d=c[(c[a+4>>2]|0)+(b<<2)>>2]|0,(d|0)!=0):0)?(c[d+20>>2]|0)>>>0>1:0)d=c[d>>2]|0;else d=0;i=e;return d|0}function jc(a){a=a|0;var b=0;b=(c[a>>2]|0)+((c[a+28>>2]|0)*40|0)|0;c[a+8>>2]=b;return c[b>>2]|0}function kc(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,j=0;j=i;c[a+36>>2]=65535;e=e>>>0>1?e:1;c[a+24>>2]=e;h=a+28|0;c[h>>2]=(g|0)==0?d:e;c[a+32>>2]=f;c[a+56>>2]=g;c[a+44>>2]=0;c[a+40>>2]=0;c[a+48>>2]=0;g=fd(680)|0;c[a>>2]=g;if(!g){g=65535;i=j;return g|0}id(g,0,680);a:do if((c[h>>2]|0)!=-1){f=b*384|47;e=0;while(1){d=fd(f)|0;g=c[a>>2]|0;c[g+(e*40|0)+4>>2]=d;if(!d){g=65535;break}c[g+(e*40|0)>>2]=d+(0-d&15);e=e+1|0;if(e>>>0>=((c[h>>2]|0)+1|0)>>>0)break a}i=j;return g|0}while(0);g=a+4|0;c[g>>2]=fd(68)|0;f=fd((c[h>>2]<<4)+16|0)|0;c[a+12>>2]=f;g=c[g>>2]|0;if((g|0)==0|(f|0)==0){g=65535;i=j;return g|0}id(g,0,68);c[a+20>>2]=0;c[a+16>>2]=0;g=0;i=j;return g|0}function lc(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,j=0,k=0,l=0;l=i;h=c[a>>2]|0;if(h){k=a+28|0;if((c[k>>2]|0)!=-1){j=0;do{gd(c[h+(j*40|0)+4>>2]|0);h=c[a>>2]|0;c[h+(j*40|0)+4>>2]=0;j=j+1|0}while(j>>>0<((c[k>>2]|0)+1|0)>>>0)}}else h=0;gd(h);c[a>>2]=0;h=a+4|0;gd(c[h>>2]|0);c[h>>2]=0;h=a+12|0;gd(c[h>>2]|0);c[h>>2]=0;h=kc(a,b,d,e,f,g)|0;i=l;return h|0}function mc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;b=c[a>>2]|0;if(b){e=a+28|0;if((c[e>>2]|0)!=-1){d=0;do{gd(c[b+(d*40|0)+4>>2]|0);b=c[a>>2]|0;c[b+(d*40|0)+4>>2]=0;d=d+1|0}while(d>>>0<((c[e>>2]|0)+1|0)>>>0)}}else b=0;gd(b);c[a>>2]=0;b=a+4|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+12|0;gd(c[b>>2]|0);c[b>>2]=0;i=f;return}function nc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;b=c[a+40>>2]|0;if(!b){i=f;return}e=a+4|0;d=0;do{c[(c[e>>2]|0)+(d<<2)>>2]=(c[a>>2]|0)+(d*40|0);d=d+1|0}while(d>>>0>>0);i=f;return}function oc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=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;y=i;v=a+16|0;c[v>>2]=0;c[a+20>>2]=0;if(!e){b=0;i=y;return b|0}x=a+48|0;e=c[x>>2]|0;f=(e|0)==(b|0);a:do if(!f?(u=a+32|0,l=c[u>>2]|0,k=((e+1|0)>>>0)%(l>>>0)|0,(k|0)!=(b|0)):0){t=a+28|0;w=c[(c[a>>2]|0)+((c[t>>2]|0)*40|0)>>2]|0;r=a+40|0;p=a+24|0;o=a+44|0;q=a+56|0;s=a+12|0;n=k;while(1){k=c[r>>2]|0;if(!k)k=0;else{j=c[a>>2]|0;h=0;do{if(((c[j+(h*40|0)+20>>2]|0)+-1|0)>>>0<2){e=c[j+(h*40|0)+12>>2]|0;c[j+(h*40|0)+8>>2]=e-(e>>>0>n>>>0?l:0)}h=h+1|0}while((h|0)!=(k|0))}if(k>>>0>=(c[p>>2]|0)>>>0){if(!k){e=1;g=46;break}f=c[a>>2]|0;h=0;l=-1;j=0;while(1){if(((c[f+(h*40|0)+20>>2]|0)+-1|0)>>>0<2){e=c[f+(h*40|0)+8>>2]|0;m=(e|0)<(j|0)|(l|0)==-1;g=m?h:l;j=m?e:j}else g=l;h=h+1|0;if((h|0)==(k|0))break;else l=g}if((g|0)<=-1){e=1;g=46;break}l=k+-1|0;c[f+(g*40|0)+20>>2]=0;c[r>>2]=l;if(!(c[f+(g*40|0)+24>>2]|0)){c[o>>2]=(c[o>>2]|0)+-1;k=l}else k=l}l=c[o>>2]|0;m=c[t>>2]|0;if(l>>>0>=m>>>0){e=(c[q>>2]|0)==0;do if(e){g=c[a>>2]|0;f=0;j=2147483647;h=0;do{if(c[g+(f*40|0)+24>>2]|0){A=c[g+(f*40|0)+16>>2]|0;z=(A|0)<(j|0);j=z?A:j;h=z?g+(f*40|0)|0:h}f=f+1|0}while(f>>>0<=m>>>0);if((h|0)!=0?(f=c[v>>2]|0,g=c[s>>2]|0,c[g+(f<<4)>>2]=c[h>>2],c[g+(f<<4)+12>>2]=c[h+36>>2],c[g+(f<<4)+4>>2]=c[h+28>>2],c[g+(f<<4)+8>>2]=c[h+32>>2],c[v>>2]=f+1,c[h+24>>2]=0,(c[h+20>>2]|0)==0):0){l=l+-1|0;c[o>>2]=l}}while(l>>>0>=m>>>0)}e=c[a>>2]|0;c[e+(m*40|0)+20>>2]=1;c[e+(m*40|0)+12>>2]=n;c[e+(m*40|0)+8>>2]=n;c[e+(m*40|0)+16>>2]=0;c[e+(m*40|0)+24>>2]=0;c[o>>2]=l+1;c[r>>2]=k+1;rc(e,m+1|0);l=c[u>>2]|0;n=((n+1|0)>>>0)%(l>>>0)|0;if((n|0)==(b|0)){g=31;break}}if((g|0)==31){g=c[v>>2]|0;if(!g){g=41;break}e=c[s>>2]|0;h=c[t>>2]|0;j=c[a>>2]|0;l=j+(h*40|0)|0;k=c[l>>2]|0;f=0;while(1){if((c[e+(f<<4)>>2]|0)==(k|0))break;f=f+1|0;if(f>>>0>=g>>>0){g=41;break a}}if(!h){g=41;break}else e=0;while(1){f=j+(e*40|0)|0;e=e+1|0;if((c[f>>2]|0)==(w|0))break;if(e>>>0>=h>>>0){g=41;break a}}c[f>>2]=k;c[l>>2]=w;g=41;break}else if((g|0)==46){i=y;return e|0}}else g=39;while(0);if((g|0)==39)if(d)if(f){b=1;i=y;return b|0}else g=41;do if((g|0)==41){if(!d){e=c[x>>2]|0;break}c[x>>2]=b;b=0;i=y;return b|0}while(0);if((e|0)==(b|0)){b=0;i=y;return b|0}a=c[a+32>>2]|0;c[x>>2]=((b+-1+a|0)>>>0)%(a>>>0)|0;b=0;i=y;return b|0}function pc(a){a=a|0;var b=0,d=0,e=0;e=i;d=a+20|0;b=c[d>>2]|0;if(b>>>0>=(c[a+16>>2]|0)>>>0){b=0;i=e;return b|0}a=c[a+12>>2]|0;c[d>>2]=b+1;b=a+(b<<4)|0;i=e;return b|0}function qc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;k=i;f=c[a>>2]|0;if(!f){i=k;return}c[a+60>>2]=1;if(c[a+56>>2]|0){i=k;return}g=c[a+28>>2]|0;h=a+16|0;j=a+12|0;e=a+44|0;a=0;b=2147483647;d=0;while(1){if(c[f+(a*40|0)+24>>2]|0){m=c[f+(a*40|0)+16>>2]|0;l=(m|0)<(b|0);b=l?m:b;d=l?f+(a*40|0)|0:d}a=a+1|0;if(a>>>0<=g>>>0)continue;if(!d)break;l=c[h>>2]|0;b=c[j>>2]|0;c[b+(l<<4)>>2]=c[d>>2];c[b+(l<<4)+12>>2]=c[d+36>>2];c[b+(l<<4)+4>>2]=c[d+28>>2];c[b+(l<<4)+8>>2]=c[d+32>>2];c[h>>2]=l+1;c[d+24>>2]=0;if(c[d+20>>2]|0){a=0;b=2147483647;d=0;continue}c[e>>2]=(c[e>>2]|0)+-1;a=0;b=2147483647;d=0}i=k;return}function rc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=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;v=i;i=i+32|0;q=v+16|0;t=v;o=7;do{if(o>>>0>>0){n=o;do{m=a+(n*40|0)|0;l=c[m>>2]|0;m=c[m+4>>2]|0;p=c[a+(n*40|0)+8>>2]|0;k=a+(n*40|0)+12|0;s=c[k+4>>2]|0;r=q;c[r>>2]=c[k>>2];c[r+4>>2]=s;r=c[a+(n*40|0)+20>>2]|0;s=c[a+(n*40|0)+24>>2]|0;k=a+(n*40|0)+28|0;c[t+0>>2]=c[k+0>>2];c[t+4>>2]=c[k+4>>2];c[t+8>>2]=c[k+8>>2];a:do if(n>>>0>>0){d=n;u=8}else{f=(s|0)==0;j=r+-1|0;k=j>>>0<2;b:do if(!r){e=n;while(1){d=e-o|0;if(c[a+(d*40|0)+20>>2]|0){d=e;break b}if((c[a+(d*40|0)+24>>2]|0)!=0|f){d=e;break b}e=a+(e*40|0)+0|0;g=a+(d*40|0)+0|0;h=e+40|0;do{c[e>>2]=c[g>>2];e=e+4|0;g=g+4|0}while((e|0)<(h|0));if(d>>>0>>0){u=8;break a}else e=d}}else{d=n;while(1){f=d-o|0;e=c[a+(f*40|0)+20>>2]|0;do if(e){e=e+-1|0;if((e|j)>>>0<2){e=c[a+(f*40|0)+8>>2]|0;if((e|0)>(p|0))break b;d=a+(d*40|0)|0;if((e|0)<(p|0))break;else break a}if(e>>>0<2)break b;if(!k?(c[a+(f*40|0)+8>>2]|0)<=(p|0):0)break b;else u=16}else u=16;while(0);if((u|0)==16){u=0;d=a+(d*40|0)|0}e=d+0|0;g=a+(f*40|0)+0|0;h=e+40|0;do{c[e>>2]=c[g>>2];e=e+4|0;g=g+4|0}while((e|0)<(h|0));if(f>>>0>>0){d=f;u=8;break a}else d=f}}while(0);d=a+(d*40|0)|0}while(0);if((u|0)==8){u=0;d=a+(d*40|0)|0}k=d;c[k>>2]=l;c[k+4>>2]=m;c[d+8>>2]=p;k=q;l=c[k+4>>2]|0;m=d+12|0;c[m>>2]=c[k>>2];c[m+4>>2]=l;c[d+20>>2]=r;c[d+24>>2]=s;m=d+28|0;c[m+0>>2]=c[t+0>>2];c[m+4>>2]=c[t+4>>2];c[m+8>>2]=c[t+8>>2];n=n+1|0}while((n|0)!=(b|0))}o=o>>>1}while((o|0)!=0);i=v;return}function sc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;e=c[a+4>>2]|0;f=c[a+16>>2]|0;g=c[a+20>>2]|0;j=e<<2;k=b+256|0;h=16;a=c[a+12>>2]|0;d=b;while(1){m=c[d+4>>2]|0;c[a>>2]=c[d>>2];c[a+4>>2]=m;m=c[d+12>>2]|0;c[a+8>>2]=c[d+8>>2];c[a+12>>2]=m;h=h+-1|0;if(!h)break;else{a=a+(j<<2)|0;d=d+16|0}}j=e<<1&2147483646;h=c[b+260>>2]|0;c[f>>2]=c[k>>2];c[f+4>>2]=h;k=c[b+268>>2]|0;c[f+(j<<2)>>2]=c[b+264>>2];c[f+((j|1)<<2)>>2]=k;k=e<<2;h=c[b+276>>2]|0;c[f+(k<<2)>>2]=c[b+272>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+284>>2]|0;c[f+(k<<2)>>2]=c[b+280>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+292>>2]|0;c[f+(k<<2)>>2]=c[b+288>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+300>>2]|0;c[f+(k<<2)>>2]=c[b+296>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+308>>2]|0;c[f+(k<<2)>>2]=c[b+304>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+316>>2]|0;c[f+(k<<2)>>2]=c[b+312>>2];c[f+((k|1)<<2)>>2]=h;k=c[b+324>>2]|0;c[g>>2]=c[b+320>>2];c[g+4>>2]=k;k=c[b+332>>2]|0;c[g+(j<<2)>>2]=c[b+328>>2];c[g+((j|1)<<2)>>2]=k;k=e<<2;h=c[b+340>>2]|0;c[g+(k<<2)>>2]=c[b+336>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+348>>2]|0;c[g+(k<<2)>>2]=c[b+344>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+356>>2]|0;c[g+(k<<2)>>2]=c[b+352>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+364>>2]|0;c[g+(k<<2)>>2]=c[b+360>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+372>>2]|0;c[g+(k<<2)>>2]=c[b+368>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;j=c[b+380>>2]|0;c[g+(k<<2)>>2]=c[b+376>>2];c[g+((k|1)<<2)>>2]=j;i=l;return}function tc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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;y=i;r=c[b+4>>2]|0;s=Z(c[b+8>>2]|0,r)|0;w=(e>>>0)%(r>>>0)|0;x=c[b>>2]|0;u=e-w|0;b=(u<<8)+(w<<4)|0;v=s<<8;w=w<<3;p=r<<4;o=r<<2&1073741820;l=o<<1;m=l+o|0;n=0;do{k=c[3344+(n<<2)>>2]|0;j=c[3408+(n<<2)>>2]|0;e=(j<<4)+k|0;h=f+e|0;j=b+k+(Z(j,p)|0)|0;k=x+j|0;q=c[g+(n<<6)>>2]|0;if((q|0)==16777215){j=c[f+(e+16)>>2]|0;c[k>>2]=c[h>>2];c[k+(o<<2)>>2]=j;j=c[f+(e+48)>>2]|0;c[k+(l<<2)>>2]=c[f+(e+32)>>2];c[k+(m<<2)>>2]=j}else{A=d[f+(e+1)>>0]|0;z=c[g+(n<<6)+4>>2]|0;a[k>>0]=a[3472+(q+512+(d[h>>0]|0))>>0]|0;q=d[f+(e+2)>>0]|0;t=c[g+(n<<6)+8>>2]|0;a[x+(j+1)>>0]=a[3472+((A|512)+z)>>0]|0;k=d[f+(e+3)>>0]|0;h=c[g+(n<<6)+12>>2]|0;a[x+(j+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(j+3)>>0]=a[3472+(h+512+k)>>0]|0;k=j+p|0;h=d[f+(e+17)>>0]|0;j=c[g+(n<<6)+20>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+16>>2]|0)+512+(d[f+(e+16)>>0]|0))>>0]|0;q=d[f+(e+18)>>0]|0;t=c[g+(n<<6)+24>>2]|0;a[x+(k+1)>>0]=a[3472+((h|512)+j)>>0]|0;j=d[f+(e+19)>>0]|0;h=c[g+(n<<6)+28>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(h+512+j)>>0]|0;k=k+p|0;j=d[f+(e+33)>>0]|0;h=c[g+(n<<6)+36>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+32>>2]|0)+512+(d[f+(e+32)>>0]|0))>>0]|0;q=d[f+(e+34)>>0]|0;t=c[g+(n<<6)+40>>2]|0;a[x+(k+1)>>0]=a[3472+((j|512)+h)>>0]|0;h=d[f+(e+35)>>0]|0;j=c[g+(n<<6)+44>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(j+512+h)>>0]|0;k=k+p|0;h=d[f+(e+49)>>0]|0;j=c[g+(n<<6)+52>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+48>>2]|0)+512+(d[f+(e+48)>>0]|0))>>0]|0;q=d[f+(e+50)>>0]|0;t=c[g+(n<<6)+56>>2]|0;a[x+(k+1)>>0]=a[3472+((h|512)+j)>>0]|0;j=d[f+(e+51)>>0]|0;h=c[g+(n<<6)+60>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(h+512+j)>>0]|0}n=n+1|0}while((n|0)!=16);t=s<<6;s=r<<3&2147483640;r=f+256|0;f=f+320|0;l=w+v+(u<<6)|0;p=s>>>2;j=s>>>1;k=j+p|0;o=16;do{q=o&3;h=c[3344+(q<<2)>>2]|0;q=c[3408+(q<<2)>>2]|0;e=o>>>0>19;m=e?f:r;n=(q<<3)+h|0;b=m+n|0;q=l+(e?t:0)+h+(Z(q,s)|0)|0;h=x+q|0;e=c[g+(o<<6)>>2]|0;if((e|0)==16777215){z=c[m+(n+8)>>2]|0;c[h>>2]=c[b>>2];c[h+(p<<2)>>2]=z;z=c[m+(n+24)>>2]|0;c[h+(j<<2)>>2]=c[m+(n+16)>>2];c[h+(k<<2)>>2]=z}else{v=d[m+(n+1)>>0]|0;z=c[g+(o<<6)+4>>2]|0;a[h>>0]=a[3472+(e+512+(d[b>>0]|0))>>0]|0;w=d[m+(n+2)>>0]|0;u=c[g+(o<<6)+8>>2]|0;a[x+(q+1)>>0]=a[3472+((v|512)+z)>>0]|0;z=d[m+(n+3)>>0]|0;v=c[g+(o<<6)+12>>2]|0;a[x+(q+2)>>0]=a[3472+(u+512+w)>>0]|0;a[x+(q+3)>>0]=a[3472+(v+512+z)>>0]|0;z=q+s|0;v=d[m+(n+9)>>0]|0;w=c[g+(o<<6)+20>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+16>>2]|0)+512+(d[m+(n+8)>>0]|0))>>0]|0;u=d[m+(n+10)>>0]|0;q=c[g+(o<<6)+24>>2]|0;a[x+(z+1)>>0]=a[3472+((v|512)+w)>>0]|0;w=d[m+(n+11)>>0]|0;v=c[g+(o<<6)+28>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(v+512+w)>>0]|0;z=z+s|0;w=d[m+(n+17)>>0]|0;v=c[g+(o<<6)+36>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+32>>2]|0)+512+(d[m+(n+16)>>0]|0))>>0]|0;u=d[m+(n+18)>>0]|0;q=c[g+(o<<6)+40>>2]|0;a[x+(z+1)>>0]=a[3472+((w|512)+v)>>0]|0;v=d[m+(n+19)>>0]|0;w=c[g+(o<<6)+44>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(w+512+v)>>0]|0;z=z+s|0;v=d[m+(n+25)>>0]|0;w=c[g+(o<<6)+52>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+48>>2]|0)+512+(d[m+(n+24)>>0]|0))>>0]|0;u=d[m+(n+26)>>0]|0;q=c[g+(o<<6)+56>>2]|0;a[x+(z+1)>>0]=a[3472+((v|512)+w)>>0]|0;w=d[m+(n+27)>>0]|0;v=c[g+(o<<6)+60>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(v+512+w)>>0]|0}o=o+1|0}while((o|0)!=24);i=y;return}function uc(e,f){e=e|0;f=f|0;var g=0,h=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,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,_=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,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;bb=i;i=i+176|0;ia=bb+40|0;La=bb;ea=c[e+4>>2]|0;ka=e+8|0;Wa=c[ka>>2]|0;g=Z(Wa,ea)|0;if(!Wa){i=bb;return}Za=ia+24|0;_a=ia+16|0;$a=ia+8|0;la=ia+100|0;ma=ia+68|0;na=ia+36|0;oa=ia+4|0;Ma=ia+120|0;Na=ia+112|0;Pa=ia+104|0;Qa=ia+96|0;Ra=ia+88|0;Sa=ia+80|0;Ta=ia+72|0;Ua=ia+64|0;Va=ia+56|0;Wa=ia+48|0;Xa=ia+40|0;Ya=ia+32|0;pa=ia+124|0;qa=ia+116|0;ra=ia+108|0;sa=ia+92|0;ta=ia+84|0;ua=ia+76|0;va=ia+60|0;wa=ia+52|0;xa=ia+44|0;ya=ia+28|0;za=ia+20|0;Aa=ia+12|0;ha=La+28|0;ja=La+32|0;Ka=La+24|0;Da=ea<<4;Ja=0-Da|0;Ca=Ja<<1;Ha=Z(ea,-48)|0;Ia=ea<<5;Ea=Ja<<2;Ga=ea*48|0;Ba=ea<<6;ga=La+24|0;fa=La+12|0;Fa=g<<8;ba=g<<6;ca=ea<<3;W=Da|4;Y=La+16|0;$=La+20|0;da=La+12|0;X=La+4|0;_=La+8|0;U=0;aa=0;V=f;while(1){f=c[V+8>>2]|0;do if((f|0)!=1){T=V+200|0;n=c[T>>2]|0;do if(!n)g=1;else{if((f|0)==2?(c[V+4>>2]|0)!=(c[n+4>>2]|0):0){g=1;break}g=5}while(0);S=V+204|0;l=c[S>>2]|0;do if(l){if((f|0)==2?(c[V+4>>2]|0)!=(c[l+4>>2]|0):0)break;g=g|2}while(0);R=(g&2|0)==0;do if(R){c[Za>>2]=0;c[_a>>2]=0;c[$a>>2]=0;c[ia>>2]=0;m=0}else{if((c[V>>2]|0)>>>0<=5?(c[l>>2]|0)>>>0<=5:0){if((b[V+28>>1]|0)==0?(b[l+48>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[l+124>>2]|0)?(B=(b[V+132>>1]|0)-(b[l+172>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){h=(b[V+134>>1]|0)-(b[l+174>>1]|0)|0;h=(((h|0)>-1?h:0-h|0)|0)>3&1}else h=1;else h=2;c[ia>>2]=h;if((b[V+30>>1]|0)==0?(b[l+50>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[l+124>>2]|0)?(B=(b[V+136>>1]|0)-(b[l+176>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){j=(b[V+138>>1]|0)-(b[l+178>>1]|0)|0;j=(((j|0)>-1?j:0-j|0)|0)>3&1}else j=1;else j=2;c[$a>>2]=j;if((b[V+36>>1]|0)==0?(b[l+56>>1]|0)==0:0)if((c[V+120>>2]|0)==(c[l+128>>2]|0)?(B=(b[V+148>>1]|0)-(b[l+188>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){k=(b[V+150>>1]|0)-(b[l+190>>1]|0)|0;k=(((k|0)>-1?k:0-k|0)|0)>3&1}else k=1;else k=2;c[_a>>2]=k;if((b[V+38>>1]|0)==0?(b[l+58>>1]|0)==0:0)if((c[V+120>>2]|0)==(c[l+128>>2]|0)?(B=(b[V+152>>1]|0)-(b[l+192>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){f=(b[V+154>>1]|0)-(b[l+194>>1]|0)|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=1;else f=2;c[Za>>2]=f;m=(j|h|k|f|0)!=0&1;break}c[Za>>2]=4;c[_a>>2]=4;c[$a>>2]=4;c[ia>>2]=4;m=1}while(0);Q=(g&4|0)==0;do if(Q){c[la>>2]=0;c[ma>>2]=0;c[na>>2]=0;c[oa>>2]=0;k=c[V>>2]|0}else{k=c[V>>2]|0;if(k>>>0<=5?(c[n>>2]|0)>>>0<=5:0){if((b[V+28>>1]|0)==0?(b[n+38>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[n+120>>2]|0)?(B=(b[V+132>>1]|0)-(b[n+152>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){j=(b[V+134>>1]|0)-(b[n+154>>1]|0)|0;j=(((j|0)>-1?j:0-j|0)|0)>3&1}else j=1;else j=2;c[oa>>2]=j;if((b[V+32>>1]|0)==0?(b[n+42>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[n+120>>2]|0)?(B=(b[V+140>>1]|0)-(b[n+160>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){h=(b[V+142>>1]|0)-(b[n+162>>1]|0)|0;h=(((h|0)>-1?h:0-h|0)|0)>3&1}else h=1;else h=2;c[na>>2]=h;if((b[V+44>>1]|0)==0?(b[n+54>>1]|0)==0:0)if((c[V+124>>2]|0)==(c[n+128>>2]|0)?(B=(b[V+164>>1]|0)-(b[n+184>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){f=(b[V+166>>1]|0)-(b[n+186>>1]|0)|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=1;else f=2;c[ma>>2]=f;if((b[V+48>>1]|0)==0?(b[n+58>>1]|0)==0:0)if((c[V+124>>2]|0)==(c[n+128>>2]|0)?(B=(b[V+172>>1]|0)-(b[n+192>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){l=(b[V+174>>1]|0)-(b[n+194>>1]|0)|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=1;else l=2;c[la>>2]=l;if(m)break;m=(h|j|f|l|0)!=0&1;break}c[la>>2]=4;c[ma>>2]=4;c[na>>2]=4;c[oa>>2]=4;m=1}while(0);if(k>>>0<=5){do if((db(k)|0)!=1){f=c[V>>2]|0;if((f|0)==2){w=V+28|0;x=b[V+32>>1]|0;if(!(x<<16>>16))f=(b[w>>1]|0)!=0?2:0;else f=2;c[Ya>>2]=f;q=b[V+34>>1]|0;A=q<<16>>16==0;if(A)f=(b[V+30>>1]|0)!=0?2:0;else f=2;c[Xa>>2]=f;g=b[V+40>>1]|0;z=g<<16>>16==0;if(z)l=(b[V+36>>1]|0)!=0?2:0;else l=2;c[Wa>>2]=l;v=b[V+42>>1]|0;y=v<<16>>16==0;if(y)l=(b[V+38>>1]|0)!=0?2:0;else l=2;c[Va>>2]=l;h=b[V+48>>1]|0;if(!(h<<16>>16))l=(b[V+44>>1]|0)!=0?2:0;else l=2;c[Qa>>2]=l;k=b[V+50>>1]|0;B=k<<16>>16==0;if(B)l=(b[V+46>>1]|0)!=0?2:0;else l=2;c[Pa>>2]=l;p=b[V+56>>1]|0;f=p<<16>>16==0;if(f)n=(b[V+52>>1]|0)!=0?2:0;else n=2;c[Na>>2]=n;j=(b[V+58>>1]|0)==0;if(j)n=(b[V+54>>1]|0)!=0?2:0;else n=2;c[Ma>>2]=n;r=b[V+44>>1]|0;o=b[V+166>>1]|0;n=b[V+142>>1]|0;do if(!((r|x)<<16>>16)){u=(b[V+164>>1]|0)-(b[V+140>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){n=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){n=1;break}n=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else n=2;while(0);c[Ua>>2]=n;s=b[V+46>>1]|0;o=b[V+170>>1]|0;n=b[V+146>>1]|0;do if(!((s|q)<<16>>16)){u=(b[V+168>>1]|0)-(b[V+144>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[Ta>>2]=o;t=b[V+52>>1]|0;o=b[V+182>>1]|0;n=b[V+158>>1]|0;do if(!((t|g)<<16>>16)){u=(b[V+180>>1]|0)-(b[V+156>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Sa>>2]=o;u=b[V+54>>1]|0;o=b[V+186>>1]|0;n=b[V+162>>1]|0;do if(!((u|v)<<16>>16)){v=(b[V+184>>1]|0)-(b[V+160>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){o=1;break}v=o-n|0;if((((v|0)>-1?v:0-v|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Ra>>2]=o;l=b[V+30>>1]|0;if(!(l<<16>>16))o=(b[w>>1]|0)!=0?2:0;else o=2;c[Aa>>2]=o;n=b[V+36>>1]|0;if(!(n<<16>>16))o=l<<16>>16!=0?2:0;else o=2;c[za>>2]=o;if(!(b[V+38>>1]|0))o=n<<16>>16!=0?2:0;else o=2;c[ya>>2]=o;if(A)n=x<<16>>16!=0?2:0;else n=2;c[xa>>2]=n;if(z)l=q<<16>>16!=0?2:0;else l=2;c[wa>>2]=l;if(y)l=g<<16>>16!=0?2:0;else l=2;c[va>>2]=l;if(!(s<<16>>16))l=r<<16>>16!=0?2:0;else l=2;c[ua>>2]=l;if(!(t<<16>>16))l=s<<16>>16!=0?2:0;else l=2;c[ta>>2]=l;if(!(u<<16>>16))l=t<<16>>16!=0?2:0;else l=2;c[sa>>2]=l;if(B)h=h<<16>>16!=0?2:0;else h=2;c[ra>>2]=h;if(f)f=k<<16>>16!=0?2:0;else f=2;c[qa>>2]=f;if(j)f=p<<16>>16!=0?2:0;else f=2;c[pa>>2]=f;break}else if((f|0)==3){j=V+28|0;v=b[V+32>>1]|0;if(!(v<<16>>16))f=(b[j>>1]|0)!=0?2:0;else f=2;c[Ya>>2]=f;B=b[V+34>>1]|0;p=B<<16>>16==0;if(p)h=(b[V+30>>1]|0)!=0?2:0;else h=2;c[Xa>>2]=h;z=b[V+40>>1]|0;if(!(z<<16>>16))k=(b[V+36>>1]|0)!=0?2:0;else k=2;c[Wa>>2]=k;o=b[V+42>>1]|0;h=o<<16>>16==0;if(h)l=(b[V+38>>1]|0)!=0?2:0;else l=2;c[Va>>2]=l;f=b[V+44>>1]|0;if(!(f<<16>>16))l=v<<16>>16!=0?2:0;else l=2;c[Ua>>2]=l;A=b[V+46>>1]|0;g=A<<16>>16==0;if(g)l=B<<16>>16!=0?2:0;else l=2;c[Ta>>2]=l;y=b[V+52>>1]|0;if(!(y<<16>>16))l=z<<16>>16!=0?2:0;else l=2;c[Sa>>2]=l;k=b[V+54>>1]|0;q=k<<16>>16==0;if(q)l=o<<16>>16!=0?2:0;else l=2;c[Ra>>2]=l;r=b[V+48>>1]|0;if(!(r<<16>>16))n=f<<16>>16!=0?2:0;else n=2;c[Qa>>2]=n;x=b[V+50>>1]|0;s=x<<16>>16==0;if(s)n=A<<16>>16!=0?2:0;else n=2;c[Pa>>2]=n;w=b[V+56>>1]|0;if(!(w<<16>>16))o=y<<16>>16!=0?2:0;else o=2;c[Na>>2]=o;u=(b[V+58>>1]|0)==0;if(u)o=k<<16>>16!=0?2:0;else o=2;c[Ma>>2]=o;t=b[V+30>>1]|0;if(!(t<<16>>16))o=(b[j>>1]|0)!=0?2:0;else o=2;c[Aa>>2]=o;if(!(b[V+38>>1]|0))o=(b[V+36>>1]|0)!=0?2:0;else o=2;c[ya>>2]=o;if(p)n=v<<16>>16!=0?2:0;else n=2;c[xa>>2]=n;if(h)n=z<<16>>16!=0?2:0;else n=2;c[va>>2]=n;if(g)l=f<<16>>16!=0?2:0;else l=2;c[ua>>2]=l;if(q)l=y<<16>>16!=0?2:0;else l=2;c[sa>>2]=l;if(s)l=r<<16>>16!=0?2:0;else l=2;c[ra>>2]=l;if(u)l=w<<16>>16!=0?2:0;else l=2;c[pa>>2]=l;l=b[V+150>>1]|0;k=b[V+138>>1]|0;do if(!((b[V+36>>1]|t)<<16>>16)){v=(b[V+148>>1]|0)-(b[V+136>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){l=1;break}v=l-k|0;if((((v|0)>-1?v:0-v|0)|0)>3){l=1;break}l=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else l=2;while(0);c[za>>2]=l;l=b[V+158>>1]|0;k=b[V+146>>1]|0;do if(!((z|B)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+144>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}B=l-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}k=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else k=2;while(0);c[wa>>2]=k;l=b[V+182>>1]|0;k=b[V+170>>1]|0;do if(!((y|A)<<16>>16)){B=(b[V+180>>1]|0)-(b[V+168>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}B=l-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else f=2;while(0);c[ta>>2]=f;f=b[V+190>>1]|0;g=b[V+178>>1]|0;do if(!((w|x)<<16>>16)){B=(b[V+188>>1]|0)-(b[V+176>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}B=f-g|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else f=2;while(0);c[qa>>2]=f;break}else{K=b[V+32>>1]|0;z=b[V+28>>1]|0;P=b[V+142>>1]|0;q=b[V+134>>1]|0;if(!((z|K)<<16>>16)){B=(b[V+140>>1]|0)-(b[V+132>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)k=1;else{k=P-q|0;k=(((k|0)>-1?k:0-k|0)|0)>3&1}}else k=2;c[Ya>>2]=k;L=b[V+34>>1]|0;y=b[V+30>>1]|0;O=b[V+146>>1]|0;r=b[V+138>>1]|0;if(!((y|L)<<16>>16)){B=(b[V+144>>1]|0)-(b[V+136>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)l=1;else{l=O-r|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}}else l=2;c[Xa>>2]=l;M=b[V+40>>1]|0;x=b[V+36>>1]|0;N=b[V+158>>1]|0;s=b[V+150>>1]|0;if(!((x|M)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+148>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)n=1;else{n=N-s|0;n=(((n|0)>-1?n:0-n|0)|0)>3&1}}else n=2;c[Wa>>2]=n;n=b[V+42>>1]|0;B=b[V+38>>1]|0;J=b[V+162>>1]|0;A=b[V+154>>1]|0;if(!((B|n)<<16>>16)){w=(b[V+160>>1]|0)-(b[V+152>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3)o=1;else{o=J-A|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}}else o=2;c[Va>>2]=o;D=b[V+44>>1]|0;I=b[V+166>>1]|0;do if(!((D|K)<<16>>16)){w=(b[V+164>>1]|0)-(b[V+140>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3)o=1;else{w=I-P|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}}else o=2;while(0);c[Ua>>2]=o;E=b[V+46>>1]|0;H=b[V+170>>1]|0;do if(!((E|L)<<16>>16)){w=(b[V+168>>1]|0)-(b[V+144>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}w=H-O|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[Ta>>2]=o;F=b[V+52>>1]|0;G=b[V+182>>1]|0;do if(!((F|M)<<16>>16)){w=(b[V+180>>1]|0)-(b[V+156>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}w=G-N|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Sa>>2]=o;g=b[V+54>>1]|0;l=b[V+186>>1]|0;do if(!((g|n)<<16>>16)){w=(b[V+184>>1]|0)-(b[V+160>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}w=l-J|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else u=2;while(0);c[Ra>>2]=u;f=b[V+48>>1]|0;C=b[V+174>>1]|0;do if(!((f|D)<<16>>16)){w=(b[V+172>>1]|0)-(b[V+164>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=C-I|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Qa>>2]=u;h=b[V+50>>1]|0;k=b[V+178>>1]|0;do if(!((h|E)<<16>>16)){w=(b[V+176>>1]|0)-(b[V+168>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=k-H|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Pa>>2]=u;j=b[V+56>>1]|0;p=b[V+190>>1]|0;do if(!((j|F)<<16>>16)){w=(b[V+188>>1]|0)-(b[V+180>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=p-G|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Na>>2]=u;w=b[V+58>>1]|0;t=b[V+194>>1]|0;do if(!((w|g)<<16>>16)){v=(b[V+192>>1]|0)-(b[V+184>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){v=1;break}v=t-l|0;v=(((v|0)>-1?v:0-v|0)|0)>3&1}else v=2;while(0);c[Ma>>2]=v;do if(!((y|z)<<16>>16)){z=(b[V+136>>1]|0)-(b[V+132>>1]|0)|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}u=r-q|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Aa>>2]=u;do if(!((x|y)<<16>>16)){z=(b[V+148>>1]|0)-(b[V+136>>1]|0)|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}z=s-r|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}u=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else u=2;while(0);c[za>>2]=u;do if(!((B|x)<<16>>16)){B=(b[V+152>>1]|0)-(b[V+148>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){u=1;break}u=A-s|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[ya>>2]=u;do if(!((L|K)<<16>>16)){B=(b[V+144>>1]|0)-(b[V+140>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=O-P|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}else o=2;while(0);c[xa>>2]=o;do if(!((M|L)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+144>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}B=N-O|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[wa>>2]=o;do if(!((n|M)<<16>>16)){B=(b[V+160>>1]|0)-(b[V+156>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=J-N|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}else o=2;while(0);c[va>>2]=o;do if(!((E|D)<<16>>16)){B=(b[V+168>>1]|0)-(b[V+164>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}n=H-I|0;n=(((n|0)>-1?n:0-n|0)|0)>3&1}else n=2;while(0);c[ua>>2]=n;do if(!((F|E)<<16>>16)){B=(b[V+180>>1]|0)-(b[V+168>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}B=G-H|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}n=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else n=2;while(0);c[ta>>2]=n;do if(!((g|F)<<16>>16)){B=(b[V+184>>1]|0)-(b[V+180>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){l=1;break}l=l-G|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=2;while(0);c[sa>>2]=l;do if(!((h|f)<<16>>16)){B=(b[V+176>>1]|0)-(b[V+172>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){l=1;break}l=k-C|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=2;while(0);c[ra>>2]=l;do if(!((j|h)<<16>>16)){B=(b[V+188>>1]|0)-(b[V+176>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}B=p-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}k=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else k=2;while(0);c[qa>>2]=k;do if(!((w|j)<<16>>16)){B=(b[V+192>>1]|0)-(b[V+188>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=t-p|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=2;while(0);c[pa>>2]=f;break}}else vc(V,ia);while(0);if(!(m|c[Ya>>2]|c[Xa>>2]|c[Wa>>2]|c[Va>>2]|c[Ua>>2]|c[Ta>>2]|c[Sa>>2]|c[Ra>>2]|c[Qa>>2]|c[Pa>>2]|c[Na>>2]|c[Ma>>2]|c[Aa>>2]|c[za>>2]|c[ya>>2]|c[xa>>2]|c[wa>>2]|c[va>>2]|c[ua>>2]|c[ta>>2]|c[sa>>2]|c[ra>>2]|c[qa>>2]|c[pa>>2]))break}else{c[Ma>>2]=3;c[Na>>2]=3;c[Pa>>2]=3;c[Qa>>2]=3;c[Ra>>2]=3;c[Sa>>2]=3;c[Ta>>2]=3;c[Ua>>2]=3;c[Va>>2]=3;c[Wa>>2]=3;c[Xa>>2]=3;c[Ya>>2]=3;c[pa>>2]=3;c[qa>>2]=3;c[ra>>2]=3;c[sa>>2]=3;c[ta>>2]=3;c[ua>>2]=3;c[va>>2]=3;c[wa>>2]=3;c[xa>>2]=3;c[ya>>2]=3;c[za>>2]=3;c[Aa>>2]=3}J=V+20|0;g=c[J>>2]|0;L=V+12|0;k=Oa(0,51,(c[L>>2]|0)+g|0)|0;K=V+16|0;h=Oa(0,51,(c[K>>2]|0)+g|0)|0;j=d[6864+k>>0]|0;c[ha>>2]=j;h=d[6920+h>>0]|0;c[ja>>2]=h;k=6976+(k*3|0)|0;c[Ka>>2]=k;do if(!R){l=c[(c[S>>2]|0)+20>>2]|0;if((l|0)==(g|0)){c[X>>2]=j;c[_>>2]=h;c[La>>2]=k;break}else{A=(g+1+l|0)>>>1;B=Oa(0,51,(c[L>>2]|0)+A|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[X>>2]=d[6864+B>>0];c[_>>2]=d[6920+A>>0];c[La>>2]=6976+(B*3|0);break}}while(0);do if(!Q){f=c[(c[T>>2]|0)+20>>2]|0;if((f|0)==(g|0)){c[Y>>2]=c[ha>>2];c[$>>2]=c[ja>>2];c[da>>2]=c[Ka>>2];break}else{A=(g+1+f|0)>>>1;B=Oa(0,51,(c[L>>2]|0)+A|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[Y>>2]=d[6864+B>>0];c[$>>2]=d[6920+A>>0];c[da>>2]=6976+(B*3|0);break}}while(0);M=Z(aa,ea)|0;P=3;o=0;O=(c[e>>2]|0)+((M<<8)+(U<<4))|0;N=ia;while(1){l=c[N+4>>2]|0;if(l)wc(O,l,fa,Da);l=c[N+12>>2]|0;if(l)wc(O+4|0,l,ga,Da);k=N+16|0;m=c[N+20>>2]|0;if(m)wc(O+8|0,m,ga,Da);j=N+24|0;m=c[N+28>>2]|0;if(m)wc(O+12|0,m,ga,Da);n=c[N>>2]|0;l=N+8|0;m=c[l>>2]|0;a:do if(((n|0)==(m|0)?(n|0)==(c[k>>2]|0):0)?(n|0)==(c[j>>2]|0):0){if(!n)break;y=c[La+(o*12|0)+4>>2]|0;x=c[La+(o*12|0)+8>>2]|0;if(n>>>0<4){t=d[(c[La+(o*12|0)>>2]|0)+(n+-1)>>0]|0;k=0-t|0;j=t+1|0;f=O;h=16;while(1){o=f+Ca|0;s=d[o>>0]|0;u=f+Ja|0;r=d[u>>0]|0;q=d[f>>0]|0;m=f+Da|0;g=d[m>>0]|0;B=r-q|0;do if(((B|0)>-1?B:0-B|0)>>>0>>0){B=s-r|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=g-q|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;n=d[f+Ha>>0]|0;B=n-r|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[o>>0]=(Oa(k,t,((r+1+q|0)>>>1)-(s<<1)+n>>1)|0)+s;o=j}else o=t;n=d[f+Ia>>0]|0;B=n-q|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[m>>0]=(Oa(k,t,((r+1+q|0)>>>1)-(g<<1)+n>>1)|0)+g;o=o+1|0}A=Oa(0-o|0,o,s+4-g+(q-r<<2)>>3)|0;B=a[3472+((q|512)-A)>>0]|0;a[u>>0]=a[3472+(A+(r|512))>>0]|0;a[f>>0]=B}while(0);h=h+-1|0;if(!h)break a;else f=f+1|0}}n=(y>>>2)+2|0;t=O;u=16;while(1){m=t+Ca|0;f=d[m>>0]|0;l=t+Ja|0;g=d[l>>0]|0;p=d[t>>0]|0;k=t+Da|0;q=d[k>>0]|0;o=g-p|0;o=(o|0)>-1?o:0-o|0;b:do if(o>>>0>>0){B=f-g|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=q-p|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;j=t+Ha|0;r=d[j>>0]|0;h=t+Ia|0;s=d[h>>0]|0;do if(o>>>0>>0){B=r-g|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){B=g+f+p|0;a[l>>0]=(q+4+(B<<1)+r|0)>>>3;a[m>>0]=(B+2+r|0)>>>2;a[j>>0]=(B+4+(r*3|0)+(d[t+Ea>>0]<<1)|0)>>>3}else a[l>>0]=(g+2+(f<<1)+q|0)>>>2;B=s-p|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=p+g+q|0;a[t>>0]=(f+4+(B<<1)+s|0)>>>3;a[k>>0]=(B+2+s|0)>>>2;a[h>>0]=(B+4+(s*3|0)+(d[t+Ga>>0]<<1)|0)>>>3;break b}else a[l>>0]=(g+2+(f<<1)+q|0)>>>2;while(0);a[t>>0]=(f+2+p+(q<<1)|0)>>>2}while(0);u=u+-1|0;if(!u)break;else t=t+1|0}}else ab=311;while(0);do if((ab|0)==311){ab=0;if(n){xc(O,n,La+(o*12|0)|0,Da);m=c[l>>2]|0}if(m)xc(O+4|0,m,La+(o*12|0)|0,Da);m=c[k>>2]|0;if(m)xc(O+8|0,m,La+(o*12|0)|0,Da);l=c[j>>2]|0;if(!l)break;xc(O+12|0,l,La+(o*12|0)|0,Da)}while(0);if(!P)break;else{P=P+-1|0;o=2;O=O+Ba|0;N=N+32|0}}h=c[V+24>>2]|0;g=c[192+((Oa(0,51,(c[J>>2]|0)+h|0)|0)<<2)>>2]|0;m=Oa(0,51,(c[L>>2]|0)+g|0)|0;j=Oa(0,51,(c[K>>2]|0)+g|0)|0;k=d[6864+m>>0]|0;c[ha>>2]=k;j=d[6920+j>>0]|0;c[ja>>2]=j;m=6976+(m*3|0)|0;c[Ka>>2]=m;do if(!R){l=c[(c[S>>2]|0)+20>>2]|0;if((l|0)==(c[J>>2]|0)){c[X>>2]=k;c[_>>2]=j;c[La>>2]=m;break}else{A=(g+1+(c[192+((Oa(0,51,l+h|0)|0)<<2)>>2]|0)|0)>>>1;B=Oa(0,51,A+(c[L>>2]|0)|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[X>>2]=d[6864+B>>0];c[_>>2]=d[6920+A>>0];c[La>>2]=6976+(B*3|0);break}}while(0);do if(!Q){f=c[(c[T>>2]|0)+20>>2]|0;if((f|0)==(c[J>>2]|0)){c[Y>>2]=c[ha>>2];c[$>>2]=c[ja>>2];c[da>>2]=c[Ka>>2];break}else{A=(g+1+(c[192+((Oa(0,51,f+h|0)|0)<<2)>>2]|0)|0)>>>1;B=Oa(0,51,A+(c[L>>2]|0)|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[Y>>2]=d[6864+B>>0];c[$>>2]=d[6920+A>>0];c[da>>2]=6976+(B*3|0);break}}while(0);j=c[e>>2]|0;l=(U<<3)+Fa+(M<<6)|0;n=j+l|0;l=j+(l+ba)|0;j=0;h=ia;o=0;while(1){g=h+4|0;f=c[g>>2]|0;if(f){yc(n,f,fa,ca);yc(l,c[g>>2]|0,fa,ca)}g=h+36|0;f=c[g>>2]|0;if(f){yc(n+Da|0,f,fa,ca);yc(l+Da|0,c[g>>2]|0,fa,ca)}m=h+16|0;g=h+20|0;f=c[g>>2]|0;if(f){yc(n+4|0,f,ga,ca);yc(l+4|0,c[g>>2]|0,ga,ca)}g=h+52|0;f=c[g>>2]|0;if(f){yc(n+W|0,f,ga,ca);yc(l+W|0,c[g>>2]|0,ga,ca)}g=c[h>>2]|0;k=h+8|0;f=c[k>>2]|0;do if((g|0)==(f|0)){if((g|0)!=(c[m>>2]|0)){ab=342;break}if((g|0)!=(c[h+24>>2]|0)){ab=342;break}if(!g)break;B=La+(j*12|0)|0;zc(n,g,B,ca);zc(l,c[h>>2]|0,B,ca)}else ab=342;while(0);do if((ab|0)==342){ab=0;if(g){f=La+(j*12|0)|0;Ac(n,g,f,ca);Ac(l,c[h>>2]|0,f,ca);f=c[k>>2]|0}if(f){B=La+(j*12|0)|0;Ac(n+2|0,f,B,ca);Ac(l+2|0,c[k>>2]|0,B,ca)}f=c[m>>2]|0;if(f){B=La+(j*12|0)|0;Ac(n+4|0,f,B,ca);Ac(l+4|0,c[m>>2]|0,B,ca)}g=h+24|0;f=c[g>>2]|0;if(!f)break;B=La+(j*12|0)|0;Ac(n+6|0,f,B,ca);Ac(l+6|0,c[g>>2]|0,B,ca)}while(0);o=o+1|0;if((o|0)==2)break;else{n=n+Ia|0;l=l+Ia|0;j=2;h=h+64|0}}}while(0);f=U+1|0;g=(f|0)==(ea|0);aa=(g&1)+aa|0;if(aa>>>0>=(c[ka>>2]|0)>>>0)break;else{U=g?0:f;V=V+216|0}}i=bb;return}function vc(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=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;B=i;l=a+28|0;y=b[a+32>>1]|0;if(!(y<<16>>16))e=(b[l>>1]|0)!=0?2:0;else e=2;c[d+32>>2]=e;z=b[a+34>>1]|0;x=z<<16>>16==0;if(x)e=(b[a+30>>1]|0)!=0?2:0;else e=2;c[d+40>>2]=e;A=b[a+40>>1]|0;v=A<<16>>16==0;if(v)e=(b[a+36>>1]|0)!=0?2:0;else e=2;c[d+48>>2]=e;f=b[a+42>>1]|0;w=f<<16>>16==0;if(w)e=(b[a+38>>1]|0)!=0?2:0;else e=2;c[d+56>>2]=e;s=b[a+44>>1]|0;if(!(s<<16>>16))e=y<<16>>16!=0?2:0;else e=2;c[d+64>>2]=e;t=b[a+46>>1]|0;p=t<<16>>16==0;if(p)e=z<<16>>16!=0?2:0;else e=2;c[d+72>>2]=e;u=b[a+52>>1]|0;q=u<<16>>16==0;if(q)e=A<<16>>16!=0?2:0;else e=2;c[d+80>>2]=e;g=b[a+54>>1]|0;r=g<<16>>16==0;if(r)e=f<<16>>16!=0?2:0;else e=2;c[d+88>>2]=e;m=b[a+48>>1]|0;if(!(m<<16>>16))e=s<<16>>16!=0?2:0;else e=2;c[d+96>>2]=e;n=b[a+50>>1]|0;h=n<<16>>16==0;if(h)e=t<<16>>16!=0?2:0;else e=2;c[d+104>>2]=e;o=b[a+56>>1]|0;j=o<<16>>16==0;if(j)f=u<<16>>16!=0?2:0;else f=2;c[d+112>>2]=f;k=(b[a+58>>1]|0)==0;if(k)f=g<<16>>16!=0?2:0;else f=2;c[d+120>>2]=f;g=b[a+30>>1]|0;if(!(g<<16>>16))f=(b[l>>1]|0)!=0?2:0;else f=2;c[d+12>>2]=f;e=b[a+36>>1]|0;if(!(e<<16>>16))f=g<<16>>16!=0?2:0;else f=2;c[d+20>>2]=f;if(!(b[a+38>>1]|0))e=e<<16>>16!=0?2:0;else e=2;c[d+28>>2]=e;if(x)e=y<<16>>16!=0?2:0;else e=2;c[d+44>>2]=e;if(v)e=z<<16>>16!=0?2:0;else e=2;c[d+52>>2]=e;if(w)e=A<<16>>16!=0?2:0;else e=2;c[d+60>>2]=e;if(p)e=s<<16>>16!=0?2:0;else e=2;c[d+76>>2]=e;if(q)e=t<<16>>16!=0?2:0;else e=2;c[d+84>>2]=e;if(r)e=u<<16>>16!=0?2:0;else e=2;c[d+92>>2]=e;if(h)e=m<<16>>16!=0?2:0;else e=2;c[d+108>>2]=e;if(j)e=n<<16>>16!=0?2:0;else e=2;c[d+116>>2]=e;if(!k){y=2;z=d+124|0;c[z>>2]=y;i=B;return}y=o<<16>>16!=0?2:0;z=d+124|0;c[z>>2]=y;i=B;return}function wc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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;w=i;u=c[f+4>>2]|0;v=c[f+8>>2]|0;if(e>>>0<4){l=d[(c[f>>2]|0)+(e+-1)>>0]|0;n=0-l|0;m=l+1|0;k=4;while(1){f=b+-2|0;s=d[f>>0]|0;t=b+-1|0;r=d[t>>0]|0;q=d[b>>0]|0;j=b+1|0;h=d[j>>0]|0;o=r-q|0;if((((o|0)>-1?o:0-o|0)>>>0>>0?(o=s-r|0,((o|0)>-1?o:0-o|0)>>>0>>0):0)?(o=h-q|0,((o|0)>-1?o:0-o|0)>>>0>>0):0){e=d[b+-3>>0]|0;p=d[b+2>>0]|0;o=e-r|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){a[f>>0]=(Oa(n,l,((r+1+q|0)>>>1)-(s<<1)+e>>1)|0)+s;f=m}else f=l;o=p-q|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){a[j>>0]=(Oa(n,l,((r+1+q|0)>>>1)-(h<<1)+p>>1)|0)+h;f=f+1|0}j=Oa(0-f|0,f,s+4-h+(q-r<<2)>>3)|0;o=a[3472+((q|512)-j)>>0]|0;a[t>>0]=a[3472+((r|512)+j)>>0]|0;a[b>>0]=o}k=k+-1|0;if(!k)break;else b=b+g|0}i=w;return}t=(u>>>2)+2|0;s=4;while(1){k=b+-2|0;q=d[k>>0]|0;l=b+-1|0;r=d[l>>0]|0;m=d[b>>0]|0;e=b+1|0;n=d[e>>0]|0;f=r-m|0;f=(f|0)>-1?f:0-f|0;do if((f>>>0>>0?(o=q-r|0,((o|0)>-1?o:0-o|0)>>>0>>0):0)?(o=n-m|0,((o|0)>-1?o:0-o|0)>>>0>>0):0){h=b+-3|0;o=d[h>>0]|0;j=b+2|0;p=d[j>>0]|0;if(f>>>0>>0){f=o-r|0;if(((f|0)>-1?f:0-f|0)>>>0>>0){f=r+q+m|0;a[l>>0]=(n+4+(f<<1)+o|0)>>>3;a[k>>0]=(f+2+o|0)>>>2;a[h>>0]=(f+4+(o*3|0)+((d[b+-4>>0]|0)<<1)|0)>>>3}else a[l>>0]=(r+2+(q<<1)+n|0)>>>2;o=p-m|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){o=m+r+n|0;a[b>>0]=(q+4+(o<<1)+p|0)>>>3;a[e>>0]=(o+2+p|0)>>>2;a[j>>0]=(o+4+(p*3|0)+((d[b+3>>0]|0)<<1)|0)>>>3;break}}else a[l>>0]=(r+2+(q<<1)+n|0)>>>2;a[b>>0]=(q+2+m+(n<<1)|0)>>>2}while(0);s=s+-1|0;if(!s)break;else b=b+g|0}i=w;return}function xc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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=i;u=d[(c[f>>2]|0)+(e+-1)>>0]|0;w=0-g|0;v=w<<1;t=f+4|0;o=f+8|0;q=Z(g,-3)|0;s=0-u|0;p=u+1|0;r=g<<1;n=4;while(1){e=b+v|0;k=b+w|0;j=b+g|0;f=a[j>>0]|0;l=d[k>>0]|0;m=d[b>>0]|0;h=l-m|0;if((((h|0)>-1?h:0-h|0)>>>0<(c[t>>2]|0)>>>0?(y=d[e>>0]|0,h=y-l|0,x=c[o>>2]|0,((h|0)>-1?h:0-h|0)>>>0>>0):0)?(z=f&255,f=z-m|0,((f|0)>-1?f:0-f|0)>>>0>>0):0){f=d[b+q>>0]|0;h=f-l|0;if(((h|0)>-1?h:0-h|0)>>>0>>0){a[e>>0]=(Oa(s,u,((l+1+m|0)>>>1)-(y<<1)+f>>1)|0)+y;e=c[o>>2]|0;f=p}else{e=x;f=u}h=d[b+r>>0]|0;B=h-m|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[j>>0]=(Oa(s,u,((l+1+m|0)>>>1)-(z<<1)+h>>1)|0)+z;f=f+1|0}f=Oa(0-f|0,f,4-z+(m-l<<2)+y>>3)|0;e=a[3472+((m|512)-f)>>0]|0;a[k>>0]=a[3472+((l|512)+f)>>0]|0;a[b>>0]=e}n=n+-1|0;if(!n)break;else b=b+1|0}i=A;return} +function ya(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+15&-16;return b|0}function za(){return i|0}function Aa(a){a=a|0;i=a}function Ba(a,b){a=a|0;b=b|0;if(!m){m=a;n=b}}function Ca(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Da(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Ea(a){a=a|0;B=a}function Fa(){return B|0}function Ga(a,b,e,f){a=a|0;b=b|0;e=e|0;f=f|0;var g=0,h=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;k=i;g=d[8+b>>0]|0;j=d[64+b>>0]|0;b=c[120+(j*12|0)>>2]<>2]<>2]<>2]=Z(c[a>>2]|0,b)|0;a:do if(!(f&65436)){if(f&98){n=a+4|0;l=Z(c[n>>2]|0,h)|0;j=a+20|0;m=Z(c[j>>2]|0,b)|0;e=a+24|0;g=Z(c[e>>2]|0,h)|0;h=c[a>>2]|0;b=(l>>1)-g|0;g=l+(g>>1)|0;l=m+h+32|0;f=l+g>>6;c[a>>2]=f;m=h-m+32|0;h=m+b>>6;c[n>>2]=h;b=m-b>>6;c[a+8>>2]=b;g=l-g>>6;c[a+12>>2]=g;c[a+48>>2]=f;c[a+32>>2]=f;c[a+16>>2]=f;c[a+52>>2]=h;c[a+36>>2]=h;c[j>>2]=h;c[a+56>>2]=b;c[a+40>>2]=b;c[e>>2]=b;c[a+60>>2]=g;c[a+44>>2]=g;c[a+28>>2]=g;if((f+512|0)>>>0>1023|(h+512|0)>>>0>1023|(b+512|0)>>>0>1023|(g+512|0)>>>0>1023)g=1;else break;i=k;return g|0}g=(c[a>>2]|0)+32>>6;if((g+512|0)>>>0>1023){m=1;i=k;return m|0}else{c[a+60>>2]=g;c[a+56>>2]=g;c[a+52>>2]=g;c[a+48>>2]=g;c[a+44>>2]=g;c[a+40>>2]=g;c[a+36>>2]=g;c[a+32>>2]=g;c[a+28>>2]=g;c[a+24>>2]=g;c[a+20>>2]=g;c[a+16>>2]=g;c[a+12>>2]=g;c[a+8>>2]=g;c[a+4>>2]=g;c[a>>2]=g;break}}else{z=a+4|0;s=a+56|0;w=a+60|0;t=c[w>>2]|0;u=Z(c[z>>2]|0,h)|0;c[s>>2]=Z(c[s>>2]|0,h)|0;c[w>>2]=Z(t,g)|0;w=a+8|0;t=c[w>>2]|0;s=a+16|0;y=Z(c[a+20>>2]|0,b)|0;o=Z(c[s>>2]|0,g)|0;q=a+12|0;p=c[q>>2]|0;f=Z(c[a+32>>2]|0,h)|0;e=Z(c[a+24>>2]|0,h)|0;r=c[a+28>>2]|0;j=Z(c[a+48>>2]|0,g)|0;n=Z(c[a+36>>2]|0,h)|0;l=c[a+44>>2]|0;m=Z(c[a+40>>2]|0,g)|0;g=Z(c[a+52>>2]|0,h)|0;x=c[a>>2]|0;v=y+x|0;y=x-y|0;x=(u>>1)-e|0;u=(e>>1)+u|0;e=u+v|0;c[a>>2]=e;c[z>>2]=x+y;c[w>>2]=y-x;c[q>>2]=v-u;q=Z(h,r+t|0)|0;r=Z(t-r|0,h)|0;h=(o>>1)-j|0;o=(j>>1)+o|0;j=o+q|0;c[s>>2]=j;c[a+20>>2]=h+r;c[a+24>>2]=r-h;c[a+28>>2]=q-o;o=Z(b,l+p|0)|0;b=Z(p-l|0,b)|0;l=(f>>1)-g|0;f=(g>>1)+f|0;h=f+o|0;c[a+32>>2]=h;c[a+36>>2]=l+b;c[a+40>>2]=b-l;c[a+44>>2]=o-f;f=a+56|0;o=c[f>>2]|0;l=o+n|0;o=n-o|0;b=a+60|0;g=c[b>>2]|0;n=(m>>1)-g|0;m=(g>>1)+m|0;g=m+l|0;c[a+48>>2]=g;c[a+52>>2]=n+o;c[f>>2]=o-n;c[b>>2]=l-m;b=j;j=3;while(1){v=(b>>1)-g|0;g=(g>>1)+b|0;w=h+e+32|0;x=w+g>>6;c[a>>2]=x;b=e-h+32|0;y=b+v>>6;c[a+16>>2]=y;b=b-v>>6;c[a+32>>2]=b;g=w-g>>6;c[a+48>>2]=g;if((x+512|0)>>>0>1023|(y+512|0)>>>0>1023){g=1;b=14;break}if((b+512|0)>>>0>1023|(g+512|0)>>>0>1023){g=1;b=14;break}f=a+4|0;if(!j)break a;e=c[f>>2]|0;h=c[a+36>>2]|0;b=c[a+20>>2]|0;g=c[a+52>>2]|0;a=f;j=j+-1|0}if((b|0)==14){i=k;return g|0}}while(0);y=0;i=k;return y|0}function Ha(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=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;B=i;e=a[64+d>>0]|0;s=a[8+d>>0]|0;D=b+8|0;u=c[D>>2]|0;j=c[b+20>>2]|0;q=b+16|0;y=c[q>>2]|0;r=b+32|0;z=c[r>>2]|0;E=b+12|0;v=c[E>>2]|0;f=c[b+24>>2]|0;m=c[b+28>>2]|0;o=b+48|0;g=c[o>>2]|0;C=c[b+36>>2]|0;A=c[b+40>>2]|0;F=c[b+44>>2]|0;h=c[b+52>>2]|0;p=c[b>>2]|0;l=j+p|0;j=p-j|0;p=b+4|0;x=c[p>>2]|0;t=x-f|0;x=f+x|0;f=x+l|0;c[b>>2]=f;k=t+j|0;c[p>>2]=k;t=j-t|0;c[D>>2]=t;x=l-x|0;c[E>>2]=x;E=m+u|0;m=u-m|0;u=y-g|0;y=g+y|0;g=y+E|0;c[q>>2]=g;l=u+m|0;c[b+20>>2]=l;u=m-u|0;c[b+24>>2]=u;y=E-y|0;c[b+28>>2]=y;E=F+v|0;F=v-F|0;v=z-h|0;z=h+z|0;h=z+E|0;c[b+32>>2]=h;m=v+F|0;c[b+36>>2]=m;v=F-v|0;c[b+40>>2]=v;z=E-z|0;c[b+44>>2]=z;E=b+56|0;F=c[E>>2]|0;D=F+C|0;F=C-F|0;C=b+60|0;j=c[C>>2]|0;w=A-j|0;A=j+A|0;j=A+D|0;c[b+48>>2]=j;n=w+F|0;c[b+52>>2]=n;w=F-w|0;c[E>>2]=w;A=D-A|0;c[C>>2]=A;s=s&255;e=c[120+((e&255)*12|0)>>2]|0;if(d>>>0>11){d=e<>2]=Z(e+s|0,d)|0;c[q>>2]=Z(f+h|0,d)|0;c[r>>2]=Z(h-f|0,d)|0;c[o>>2]=Z(s-e|0,d)|0;r=m+k|0;e=k-m|0;q=l-n|0;s=n+l|0;c[p>>2]=Z(s+r|0,d)|0;c[b+20>>2]=Z(q+e|0,d)|0;c[b+36>>2]=Z(e-q|0,d)|0;c[b+52>>2]=Z(r-s|0,d)|0;s=v+t|0;t=t-v|0;v=u-w|0;w=w+u|0;c[b+8>>2]=Z(w+s|0,d)|0;c[b+24>>2]=Z(v+t|0,d)|0;c[b+40>>2]=Z(t-v|0,d)|0;c[b+56>>2]=Z(s-w|0,d)|0;w=z+x|0;v=x-z|0;x=y-A|0;y=A+y|0;c[b+12>>2]=Z(y+w|0,d)|0;c[b+28>>2]=Z(x+v|0,d)|0;c[b+44>>2]=Z(v-x|0,d)|0;c[b+60>>2]=Z(w-y|0,d)|0;i=B;return}else{C=(d+-6|0)>>>0<6?1:2;d=2-s|0;s=h+f|0;D=f-h|0;h=g-j|0;f=j+g|0;c[b>>2]=(Z(f+s|0,e)|0)+C>>d;c[q>>2]=(Z(h+D|0,e)|0)+C>>d;c[r>>2]=(Z(D-h|0,e)|0)+C>>d;c[o>>2]=(Z(s-f|0,e)|0)+C>>d;r=m+k|0;f=k-m|0;q=l-n|0;s=n+l|0;c[p>>2]=(Z(s+r|0,e)|0)+C>>d;c[b+20>>2]=(Z(q+f|0,e)|0)+C>>d;c[b+36>>2]=(Z(f-q|0,e)|0)+C>>d;c[b+52>>2]=(Z(r-s|0,e)|0)+C>>d;s=v+t|0;t=t-v|0;v=u-w|0;w=w+u|0;c[b+8>>2]=(Z(w+s|0,e)|0)+C>>d;c[b+24>>2]=(Z(v+t|0,e)|0)+C>>d;c[b+40>>2]=(Z(t-v|0,e)|0)+C>>d;c[b+56>>2]=(Z(s-w|0,e)|0)+C>>d;w=z+x|0;v=x-z|0;x=y-A|0;y=A+y|0;c[b+12>>2]=(Z(y+w|0,e)|0)+C>>d;c[b+28>>2]=(Z(x+v|0,e)|0)+C>>d;c[b+44>>2]=(Z(v-x|0,e)|0)+C>>d;c[b+60>>2]=(Z(w-y|0,e)|0)+C>>d;i=B;return}}function Ia(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;e=c[120+((d[64+b>>0]|0)*12|0)>>2]|0;if(b>>>0>5){e=e<<(d[8+b>>0]|0)+-1;b=0}else b=1;k=c[a>>2]|0;g=a+8|0;h=c[g>>2]|0;m=h+k|0;h=k-h|0;k=a+4|0;j=c[k>>2]|0;l=a+12|0;f=c[l>>2]|0;i=j-f|0;j=f+j|0;c[a>>2]=(Z(j+m|0,e)|0)>>b;c[k>>2]=(Z(m-j|0,e)|0)>>b;c[g>>2]=(Z(i+h|0,e)|0)>>b;c[l>>2]=(Z(h-i|0,e)|0)>>b;l=a+16|0;i=c[l>>2]|0;h=a+24|0;g=c[h>>2]|0;k=g+i|0;g=i-g|0;i=a+20|0;j=c[i>>2]|0;a=a+28|0;m=c[a>>2]|0;f=j-m|0;j=m+j|0;c[l>>2]=(Z(j+k|0,e)|0)>>b;c[i>>2]=(Z(k-j|0,e)|0)>>b;c[h>>2]=(Z(f+g|0,e)|0)>>b;c[a>>2]=(Z(g-f|0,e)|0)>>b;return}function Ja(a,b){a=a|0;b=b|0;var c=0,d=0;d=i;b=1<>>1}while((c|0)!=0&(c&a|0)==0);i=d;return b|0}function Ka(a){a=a|0;var b=0,d=0;d=i;b=8-(c[a+8>>2]|0)|0;a=jb(a,b)|0;if((a|0)==-1){a=1;i=d;return a|0}a=(a|0)!=(c[400+(b+-1<<2)>>2]|0)&1;i=d;return a|0}function La(a){a=a|0;var b=0,d=0,e=0,f=0;d=i;f=c[a+12>>2]<<3;e=c[a+16>>2]|0;b=f-e|0;if((f|0)==(e|0)){a=0;i=d;return a|0}if(b>>>0>8){a=1;i=d;return a|0}else{a=((kb(a)|0)>>>(32-b|0)|0)!=(1<>2]|0;do{d=d+1|0;if(d>>>0>=b>>>0)break}while((c[a+(d<<2)>>2]|0)!=(e|0));i=f;return ((d|0)==(b|0)?0:d)|0}function Na(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=c[a+4>>2]|0;f=(b>>>0)%(e>>>0)|0;d=b-f|0;b=Z(c[a+8>>2]|0,e)|0;e=c[a>>2]|0;c[a+12>>2]=e+((d<<8)+(f<<4));d=(f<<3)+(b<<8)+(d<<6)|0;c[a+16>>2]=e+d;c[a+20>>2]=e+(d+(b<<6));return}function Oa(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)>=(a|0))a=(c|0)>(b|0)?b:c;return a|0}function Pa(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=i;a:do if(((e>>>0>3?(a[b>>0]|0)==0:0)?(a[b+1>>0]|0)==0:0)?(h=a[b+2>>0]|0,(h&255)<2):0){b:do if((e|0)!=3){p=-3;q=3;k=b+3|0;j=2;while(1){if(h<<24>>24)if(h<<24>>24==1&j>>>0>1){o=q;h=0;m=0;l=0;break}else j=0;else j=j+1|0;l=q+1|0;if((l|0)==(e|0))break b;h=a[k>>0]|0;p=~q;q=l;k=k+1|0}while(1){r=a[k>>0]|0;n=o+1|0;j=r<<24>>24!=0;l=(j&1^1)+l|0;h=r<<24>>24==3&(l|0)==2?1:h;if(r<<24>>24==1&l>>>0>1){r=14;break}if(j){m=l>>>0>2?1:m;l=0}if((n|0)==(e|0)){r=18;break}else{o=n;k=k+1|0}}if((r|0)==14){n=p+o-l|0;c[f+12>>2]=n;j=q;l=l-(l>>>0<3?l:3)|0;break a}else if((r|0)==18){n=p+e-l|0;c[f+12>>2]=n;j=q;break a}}while(0);c[g>>2]=e;q=1;i=s;return q|0}else r=19;while(0);if((r|0)==19){c[f+12>>2]=e;n=e;h=1;j=0;m=0;l=0}k=b+j|0;c[f>>2]=k;c[f+4>>2]=k;c[f+8>>2]=0;c[f+16>>2]=0;o=f+12|0;c[g>>2]=l+j+n;if(m){q=1;i=s;return q|0}if(!h){q=0;i=s;return q|0}l=c[o>>2]|0;h=k;m=k;j=0;c:while(1){while(1){q=l;l=l+-1|0;if(!q){r=31;break c}k=a[h>>0]|0;if((j|0)!=2)break;if(k<<24>>24!=3){r=29;break}if(!l){h=1;r=32;break c}h=h+1|0;if((d[h>>0]|0)>3){h=1;r=32;break c}else j=0}if((r|0)==29){r=0;if((k&255)<3){h=1;r=32;break}else j=2}a[m>>0]=k;h=h+1|0;m=m+1|0;j=k<<24>>24==0?j+1|0:0}if((r|0)==31){c[o>>2]=m-h+(c[o>>2]|0);q=0;i=s;return q|0}else if((r|0)==32){i=s;return h|0}return 0}function Qa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;i=i+16|0;n=o;id(b,0,92);f=jb(a,8)|0;a:do if((((f|0)!=-1?(c[b>>2]=f,jb(a,1)|0,jb(a,1)|0,(jb(a,1)|0)!=-1):0)?(jb(a,5)|0)!=-1:0)?(e=jb(a,8)|0,(e|0)!=-1):0){m=b+4|0;c[m>>2]=e;f=b+8|0;d=nb(a,f)|0;if(!d)if((c[f>>2]|0)>>>0<=31){d=nb(a,n)|0;if(!d){f=c[n>>2]|0;if(f>>>0<=12){c[b+12>>2]=1<>2]|0;if(f>>>0<=2){c[b+16>>2]=f;b:do if(!f){d=nb(a,n)|0;if(d)break a;f=c[n>>2]|0;if(f>>>0>12){d=1;break a}c[b+20>>2]=1<>2]=(f|0)==1&1;d=ob(a,b+28|0)|0;if(d)break a;d=ob(a,b+32|0)|0;if(d)break a;h=b+36|0;d=nb(a,h)|0;if(d)break a;f=c[h>>2]|0;if(f>>>0>255){d=1;break a}if(!f){c[b+40>>2]=0;break}f=fd(f<<2)|0;g=b+40|0;c[g>>2]=f;if(!f){d=65535;break a}if(c[h>>2]|0){e=0;while(1){d=ob(a,f+(e<<2)|0)|0;e=e+1|0;if(d)break a;if(e>>>0>=(c[h>>2]|0)>>>0)break b;f=c[g>>2]|0}}}while(0);l=b+44|0;d=nb(a,l)|0;if(!d)if((c[l>>2]|0)>>>0<=16?(k=jb(a,1)|0,(k|0)!=-1):0){c[b+48>>2]=(k|0)==1&1;d=nb(a,n)|0;if(!d){e=b+52|0;c[e>>2]=(c[n>>2]|0)+1;d=nb(a,n)|0;if(!d){k=b+56|0;c[k>>2]=(c[n>>2]|0)+1;h=jb(a,1)|0;if((!((h|0)==0|(h|0)==-1)?(jb(a,1)|0)!=-1:0)?(j=jb(a,1)|0,(j|0)!=-1):0){j=(j|0)==1;c[b+60>>2]=j&1;if(j){j=b+64|0;d=nb(a,j)|0;if(d)break;f=b+68|0;d=nb(a,f)|0;if(d)break;h=b+72|0;d=nb(a,h)|0;if(d)break;g=b+76|0;d=nb(a,g)|0;if(d)break;e=c[e>>2]|0;if((c[j>>2]|0)>((e<<3)+~c[f>>2]|0)){d=1;break}f=c[k>>2]|0;if((c[h>>2]|0)>((f<<3)+~c[g>>2]|0)){d=1;break}}else{e=c[e>>2]|0;f=c[k>>2]|0}d=Z(f,e)|0;do switch(c[m>>2]|0){case 11:{f=396;e=345600;g=58;break}case 12:{f=396;e=912384;g=58;break}case 13:{f=396;e=912384;g=58;break}case 20:{f=396;e=912384;g=58;break}case 21:{f=792;e=1824768;g=58;break}case 22:{f=1620;e=3110400;g=58;break}case 30:{f=1620;e=3110400;g=58;break}case 31:{f=3600;e=6912e3;g=58;break}case 32:{f=5120;e=7864320;g=58;break}case 40:{f=8192;e=12582912;g=58;break}case 41:{f=8192;e=12582912;g=58;break}case 42:{f=8704;e=13369344;g=58;break}case 50:{f=22080;e=42393600;g=58;break}case 51:{f=36864;e=70778880;g=58;break}case 10:{f=99;e=152064;g=58;break}default:g=60}while(0);do if((g|0)==58){if(f>>>0>>0){g=60;break}e=(e>>>0)/((d*384|0)>>>0)|0;e=e>>>0<16?e:16;c[n>>2]=e;f=c[l>>2]|0;if(f>>>0>e>>>0){e=f;g=61}}while(0);if((g|0)==60){c[n>>2]=2147483647;e=c[l>>2]|0;g=61}if((g|0)==61)c[n>>2]=e;g=b+88|0;c[g>>2]=e;e=jb(a,1)|0;if((e|0)==-1){d=1;break}n=(e|0)==1;c[b+80>>2]=n&1;do if(n){e=fd(952)|0;f=b+84|0;c[f>>2]=e;if(!e){d=65535;break a}d=Ec(a,e)|0;if(d)break a;d=c[f>>2]|0;if(!(c[d+920>>2]|0))break;e=c[d+948>>2]|0;if((c[d+944>>2]|0)>>>0>e>>>0){d=1;break a}if(e>>>0<(c[l>>2]|0)>>>0){d=1;break a}if(e>>>0>(c[g>>2]|0)>>>0){d=1;break a}c[g>>2]=(e|0)==0?1:e}while(0);Ka(a)|0;d=0}else d=1}}}else d=1}else d=1}}else d=1}}else d=1}else d=1;while(0);i=o;return d|0}function Ra(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;j=i;if((c[a>>2]|0)!=(c[b>>2]|0)){d=1;i=j;return d|0}if((c[a+4>>2]|0)!=(c[b+4>>2]|0)){d=1;i=j;return d|0}if((c[a+12>>2]|0)!=(c[b+12>>2]|0)){d=1;i=j;return d|0}d=c[a+16>>2]|0;if((d|0)!=(c[b+16>>2]|0)){d=1;i=j;return d|0}if((c[a+44>>2]|0)!=(c[b+44>>2]|0)){d=1;i=j;return d|0}if((c[a+48>>2]|0)!=(c[b+48>>2]|0)){d=1;i=j;return d|0}if((c[a+52>>2]|0)!=(c[b+52>>2]|0)){d=1;i=j;return d|0}if((c[a+56>>2]|0)!=(c[b+56>>2]|0)){d=1;i=j;return d|0}h=c[a+60>>2]|0;if((h|0)!=(c[b+60>>2]|0)){d=1;i=j;return d|0}if((c[a+80>>2]|0)!=(c[b+80>>2]|0)){d=1;i=j;return d|0}a:do if(!d){if((c[a+20>>2]|0)!=(c[b+20>>2]|0)){d=1;i=j;return d|0}}else if((d|0)==1){if((c[a+24>>2]|0)!=(c[b+24>>2]|0)){d=1;i=j;return d|0}if((c[a+28>>2]|0)!=(c[b+28>>2]|0)){d=1;i=j;return d|0}if((c[a+32>>2]|0)!=(c[b+32>>2]|0)){d=1;i=j;return d|0}d=c[a+36>>2]|0;if((d|0)!=(c[b+36>>2]|0)){d=1;i=j;return d|0}if(d){e=c[a+40>>2]|0;f=c[b+40>>2]|0;g=0;while(1){if((c[e+(g<<2)>>2]|0)!=(c[f+(g<<2)>>2]|0)){d=1;break}g=g+1|0;if(g>>>0>=d>>>0)break a}i=j;return d|0}}while(0);if(h){if((c[a+64>>2]|0)!=(c[b+64>>2]|0)){d=1;i=j;return d|0}if((c[a+68>>2]|0)!=(c[b+68>>2]|0)){d=1;i=j;return d|0}if((c[a+72>>2]|0)!=(c[b+72>>2]|0)){d=1;i=j;return d|0}if((c[a+76>>2]|0)!=(c[b+76>>2]|0)){d=1;i=j;return d|0}}d=0;i=j;return d|0}function Sa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;i=i+16|0;j=l+4|0;k=l;id(b,0,72);d=nb(a,b)|0;if(d){i=l;return d|0}if((c[b>>2]|0)>>>0>255){d=1;i=l;return d|0}e=b+4|0;d=nb(a,e)|0;if(d){i=l;return d|0}if((c[e>>2]|0)>>>0>31){d=1;i=l;return d|0}if(jb(a,1)|0){d=1;i=l;return d|0}d=jb(a,1)|0;if((d|0)==-1){d=1;i=l;return d|0}c[b+8>>2]=(d|0)==1&1;d=nb(a,j)|0;if(d){i=l;return d|0}d=(c[j>>2]|0)+1|0;h=b+12|0;c[h>>2]=d;if(d>>>0>8){d=1;i=l;return d|0}a:do if(d>>>0>1){d=b+16|0;e=nb(a,d)|0;if(e){d=e;i=l;return d|0}d=c[d>>2]|0;if(d>>>0>6){d=1;i=l;return d|0}switch(d|0){case 5:case 4:case 3:{d=jb(a,1)|0;if((d|0)==-1){d=1;i=l;return d|0}c[b+32>>2]=(d|0)==1&1;d=nb(a,j)|0;if(!d){c[b+36>>2]=(c[j>>2]|0)+1;break a}else{i=l;return d|0}}case 0:{d=fd(c[h>>2]<<2)|0;f=b+20|0;c[f>>2]=d;if(!d){d=65535;i=l;return d|0}if(!(c[h>>2]|0))break a;else e=0;while(1){d=nb(a,j)|0;if(d)break;c[(c[f>>2]|0)+(e<<2)>>2]=(c[j>>2]|0)+1;e=e+1|0;if(e>>>0>=(c[h>>2]|0)>>>0)break a}i=l;return d|0}case 2:{e=b+24|0;c[e>>2]=fd((c[h>>2]<<2)+-4|0)|0;d=fd((c[h>>2]<<2)+-4|0)|0;g=b+28|0;c[g>>2]=d;if((c[e>>2]|0)==0|(d|0)==0){d=65535;i=l;return d|0}if((c[h>>2]|0)==1)break a;else f=0;while(1){d=nb(a,j)|0;if(d){e=46;break}c[(c[e>>2]|0)+(f<<2)>>2]=c[j>>2];d=nb(a,j)|0;if(d){e=46;break}c[(c[g>>2]|0)+(f<<2)>>2]=c[j>>2];f=f+1|0;if(f>>>0>=((c[h>>2]|0)+-1|0)>>>0)break a}if((e|0)==46){i=l;return d|0}break}case 6:{d=nb(a,j)|0;if(d){i=l;return d|0}e=(c[j>>2]|0)+1|0;d=b+40|0;c[d>>2]=e;e=fd(e<<2)|0;g=b+44|0;c[g>>2]=e;if(!e){d=65535;i=l;return d|0}f=c[432+((c[h>>2]|0)+-1<<2)>>2]|0;if(!(c[d>>2]|0))break a;else e=0;while(1){m=jb(a,f)|0;c[(c[g>>2]|0)+(e<<2)>>2]=m;e=e+1|0;if(m>>>0>=(c[h>>2]|0)>>>0){d=1;break}if(e>>>0>=(c[d>>2]|0)>>>0)break a}i=l;return d|0}default:break a}}while(0);d=nb(a,j)|0;if(d){a=d;i=l;return a|0}d=c[j>>2]|0;if(d>>>0>31){a=1;i=l;return a|0}c[b+48>>2]=d+1;d=nb(a,j)|0;if(d){a=d;i=l;return a|0}if((c[j>>2]|0)>>>0>31){a=1;i=l;return a|0}if(jb(a,1)|0){a=1;i=l;return a|0}if((jb(a,2)|0)>>>0>2){a=1;i=l;return a|0}d=ob(a,k)|0;if(d){a=d;i=l;return a|0}d=(c[k>>2]|0)+26|0;if(d>>>0>51){a=1;i=l;return a|0}c[b+52>>2]=d;d=ob(a,k)|0;if(d){a=d;i=l;return a|0}if(((c[k>>2]|0)+26|0)>>>0>51){a=1;i=l;return a|0}d=ob(a,k)|0;if(d){a=d;i=l;return a|0}d=c[k>>2]|0;if((d+12|0)>>>0>24){a=1;i=l;return a|0}c[b+56>>2]=d;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+60>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+64>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+68>>2]=(d|0)==1&1;Ka(a)|0;a=0;i=l;return a|0}function Ta(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,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;w=i;i=i+32|0;s=w+20|0;q=w+16|0;o=w+12|0;l=w+8|0;v=w+4|0;t=w;id(b,0,988);u=Z(c[d+56>>2]|0,c[d+52>>2]|0)|0;k=nb(a,v)|0;if(k){f=k;i=w;return f|0}n=c[v>>2]|0;c[b>>2]=n;if(n>>>0>=u>>>0){f=1;i=w;return f|0}k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;m=b+4|0;c[m>>2]=k;if((k|0)==5|(k|0)==0)j=5;else if(!((k|0)==7|(k|0)==2)){f=1;i=w;return f|0}if((j|0)==5){if((c[f>>2]|0)==5){f=1;i=w;return f|0}if(!(c[d+44>>2]|0)){f=1;i=w;return f|0}}k=nb(a,v)|0;if(k){f=k;i=w;return f|0}n=c[v>>2]|0;c[b+8>>2]=n;if((n|0)!=(c[e>>2]|0)){f=1;i=w;return f|0}n=d+12|0;k=c[n>>2]|0;j=0;while(1)if(!(k>>>j))break;else j=j+1|0;k=jb(a,j+-1|0)|0;if((k|0)==-1){f=1;i=w;return f|0}j=(c[f>>2]|0)==5;if(j&(k|0)!=0){f=1;i=w;return f|0}c[b+12>>2]=k;if(j){k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;c[b+16>>2]=k;if(k>>>0>65535){f=1;i=w;return f|0}}g=d+16|0;k=c[g>>2]|0;if(!k){h=d+20|0;k=c[h>>2]|0;j=0;while(1)if(!(k>>>j))break;else j=j+1|0;k=jb(a,j+-1|0)|0;if((k|0)==-1){f=1;i=w;return f|0}j=b+20|0;c[j>>2]=k;do if(c[e+8>>2]|0){k=ob(a,t)|0;if(!k){c[b+24>>2]=c[t>>2];break}else{f=k;i=w;return f|0}}while(0);if((c[f>>2]|0)==5){k=c[j>>2]|0;if(k>>>0>(c[h>>2]|0)>>>1>>>0){f=1;i=w;return f|0}j=c[b+24>>2]|0;if((k|0)!=(((j|0)>0?0:0-j|0)|0)){f=1;i=w;return f|0}}k=c[g>>2]|0}if((k|0)==1?(c[d+24>>2]|0)==0:0){k=ob(a,t)|0;if(k){f=k;i=w;return f|0}k=b+28|0;c[k>>2]=c[t>>2];do if(c[e+8>>2]|0){j=ob(a,t)|0;if(!j){c[b+32>>2]=c[t>>2];break}else{f=j;i=w;return f|0}}while(0);if((c[f>>2]|0)==5?(j=c[k>>2]|0,k=(c[d+32>>2]|0)+j+(c[b+32>>2]|0)|0,(((j|0)<(k|0)?j:k)|0)!=0):0){f=1;i=w;return f|0}}if(c[e+68>>2]|0){k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;c[b+36>>2]=k;if(k>>>0>127){f=1;i=w;return f|0}}k=c[m>>2]|0;if((k|0)==5|(k|0)==0){k=jb(a,1)|0;if((k|0)==-1){f=1;i=w;return f|0}c[b+40>>2]=k;do if(!k){k=c[e+48>>2]|0;if(k>>>0>16){f=1;i=w;return f|0}else{c[b+44>>2]=k;break}}else{k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;if(k>>>0>15){f=1;i=w;return f|0}else{c[b+44>>2]=k+1;break}}while(0);k=c[m>>2]|0}do if((k|0)==5|(k|0)==0){g=c[b+44>>2]|0;j=c[n>>2]|0;k=jb(a,1)|0;if((k|0)==-1){f=1;i=w;return f|0}c[b+68>>2]=k;if(k){h=0;a:while(1){if(h>>>0>g>>>0){r=1;j=110;break}k=nb(a,l)|0;if(k){r=k;j=110;break}k=c[l>>2]|0;if(k>>>0>3){r=1;j=110;break}c[b+(h*12|0)+72>>2]=k;do if(k>>>0<2){k=nb(a,o)|0;if(k){r=k;j=110;break a}k=c[o>>2]|0;if(k>>>0>=j>>>0){r=1;j=110;break a}c[b+(h*12|0)+76>>2]=k+1}else{if((k|0)!=2)break;k=nb(a,o)|0;if(k){r=k;j=110;break a}c[b+(h*12|0)+80>>2]=c[o>>2]}while(0);if((c[l>>2]|0)==3){j=61;break}else h=h+1|0}if((j|0)==61){if(!h)r=1;else break;i=w;return r|0}else if((j|0)==110){i=w;return r|0}}}while(0);do if(c[f+4>>2]|0){n=c[d+44>>2]|0;f=(c[f>>2]|0)==5;k=jb(a,1)|0;j=(k|0)==-1;if(f){if(j){f=1;i=w;return f|0}c[b+276>>2]=k;g=jb(a,1)|0;if((g|0)==-1){f=1;i=w;return f|0}c[b+280>>2]=g;if((n|0)!=0|(g|0)==0)break;else r=1;i=w;return r|0}if(j){f=1;i=w;return f|0}c[b+284>>2]=k;if(k){j=(n<<1)+2|0;h=0;d=0;g=0;l=0;m=0;while(1){if(h>>>0>j>>>0){r=1;j=110;break}k=nb(a,q)|0;if(k){r=k;j=110;break}k=c[q>>2]|0;if(k>>>0>6){r=1;j=110;break}c[b+(h*20|0)+288>>2]=k;if((k&-3|0)==1){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+292>>2]=(c[s>>2]|0)+1;k=c[q>>2]|0}if((k|0)==2){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+296>>2]=c[s>>2];k=c[q>>2]|0}if((k|0)==3|(k|0)==6){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+300>>2]=c[s>>2];k=c[q>>2]|0}if((k|0)==4){k=nb(a,s)|0;if(k){r=k;j=110;break}k=c[s>>2]|0;if(k>>>0>n>>>0){r=1;j=110;break}if(!k)c[b+(h*20|0)+304>>2]=65535;else c[b+(h*20|0)+304>>2]=k+-1;k=c[q>>2]|0;p=g+1|0}else p=g;l=((k|0)==5&1)+l|0;d=((k|0)!=0&k>>>0<4&1)+d|0;m=((k|0)==6&1)+m|0;if(!k){j=90;break}else{h=h+1|0;g=p}}if((j|0)==90){if(p>>>0>1|l>>>0>1|m>>>0>1){f=1;i=w;return f|0}if((d|0)!=0&(l|0)!=0)r=1;else break;i=w;return r|0}else if((j|0)==110){i=w;return r|0}}}while(0);g=ob(a,t)|0;if(g){f=g;i=w;return f|0}f=c[t>>2]|0;c[b+48>>2]=f;f=f+(c[e+52>>2]|0)|0;c[t>>2]=f;if(f>>>0>51){f=1;i=w;return f|0}do if(c[e+60>>2]|0){g=nb(a,v)|0;if(g){f=g;i=w;return f|0}g=c[v>>2]|0;c[b+52>>2]=g;if(g>>>0>2){f=1;i=w;return f|0}if((g|0)==1)break;g=ob(a,t)|0;if(g){f=g;i=w;return f|0}g=c[t>>2]|0;if((g+6|0)>>>0>12){f=1;i=w;return f|0}c[b+56>>2]=g<<1;g=ob(a,t)|0;if(g){f=g;i=w;return f|0}g=c[t>>2]|0;if((g+6|0)>>>0>12){f=1;i=w;return f|0}else{c[b+60>>2]=g<<1;break}}while(0);do if((c[e+12>>2]|0)>>>0>1?((c[e+16>>2]|0)+-3|0)>>>0<3:0){k=e+36|0;j=c[k>>2]|0;j=(((u>>>0)%(j>>>0)|0|0)==0?1:2)+((u>>>0)/(j>>>0)|0)|0;h=0;while(1){g=h+1|0;if(!(-1<>2]=g;if((g|0)==-1){f=1;i=w;return f|0}c[b+64>>2]=g;f=c[k>>2]|0;if(g>>>0>(((u+-1+f|0)>>>0)/(f>>>0)|0)>>>0)r=1;else break;i=w;return r|0}while(0);f=0;i=w;return f|0}function Ua(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;i=i+32|0;e=f+20|0;d=f;c[d+0>>2]=c[a+0>>2];c[d+4>>2]=c[a+4>>2];c[d+8>>2]=c[a+8>>2];c[d+12>>2]=c[a+12>>2];c[d+16>>2]=c[a+16>>2];a=nb(d,e)|0;if(!a){a=nb(d,e)|0;if(!a){a=nb(d,e)|0;if(!a){a=c[e>>2]|0;if(a>>>0>255)a=1;else{c[b>>2]=a;a=0}}}}i=f;return a|0}function Va(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+32|0;e=g+20|0;f=g;c[f+0>>2]=c[a+0>>2];c[f+4>>2]=c[a+4>>2];c[f+8>>2]=c[a+8>>2];c[f+12>>2]=c[a+12>>2];c[f+16>>2]=c[a+16>>2];a=nb(f,e)|0;if(a){i=g;return a|0}a=nb(f,e)|0;if(a){i=g;return a|0}a=nb(f,e)|0;if(!a)a=0;else{i=g;return a|0}while(1)if(!(b>>>a))break;else a=a+1|0;a=jb(f,a+-1|0)|0;if((a|0)==-1){a=1;i=g;return a|0}c[d>>2]=a;a=0;i=g;return a|0}function Wa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;h=i;i=i+32|0;f=h+20|0;g=h;if((d|0)!=5){d=1;i=h;return d|0};c[g+0>>2]=c[a+0>>2];c[g+4>>2]=c[a+4>>2];c[g+8>>2]=c[a+8>>2];c[g+12>>2]=c[a+12>>2];c[g+16>>2]=c[a+16>>2];d=nb(g,f)|0;if(d){i=h;return d|0}d=nb(g,f)|0;if(d){i=h;return d|0}d=nb(g,f)|0;if(!d)d=0;else{i=h;return d|0}while(1)if(!(b>>>d))break;else d=d+1|0;if((jb(g,d+-1|0)|0)==-1){d=1;i=h;return d|0}d=nb(g,e)|0;i=h;return d|0}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,j=0,k=0;k=i;i=i+32|0;h=k+20|0;j=k;c[j+0>>2]=c[a+0>>2];c[j+4>>2]=c[a+4>>2];c[j+8>>2]=c[a+8>>2];c[j+12>>2]=c[a+12>>2];c[j+16>>2]=c[a+16>>2];a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=c[b+12>>2]|0;f=0;while(1)if(!(a>>>f))break;else f=f+1|0;if((jb(j,f+-1|0)|0)==-1){f=1;i=k;return f|0}if((d|0)==5?(g=nb(j,h)|0,(g|0)!=0):0){f=g;i=k;return f|0}f=c[b+20>>2]|0;a=0;while(1)if(!(f>>>a))break;else a=a+1|0;f=jb(j,a+-1|0)|0;if((f|0)==-1){f=1;i=k;return f|0}c[e>>2]=f;f=0;i=k;return f|0}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,j=0,k=0;k=i;i=i+32|0;h=k+20|0;j=k;c[j+0>>2]=c[a+0>>2];c[j+4>>2]=c[a+4>>2];c[j+8>>2]=c[a+8>>2];c[j+12>>2]=c[a+12>>2];c[j+16>>2]=c[a+16>>2];a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=c[b+12>>2]|0;f=0;while(1)if(!(a>>>f))break;else f=f+1|0;if((jb(j,f+-1|0)|0)==-1){f=1;i=k;return f|0}if((d|0)==5?(g=nb(j,h)|0,(g|0)!=0):0){f=g;i=k;return f|0}f=c[b+20>>2]|0;a=0;while(1)if(!(f>>>a))break;else a=a+1|0;if((jb(j,a+-1|0)|0)==-1){f=1;i=k;return f|0}f=ob(j,e)|0;i=k;return f|0}function Za(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,j=0,k=0,l=0,m=0;m=i;i=i+32|0;j=m+20|0;l=m;c[l+0>>2]=c[a+0>>2];c[l+4>>2]=c[a+4>>2];c[l+8>>2]=c[a+8>>2];c[l+12>>2]=c[a+12>>2];c[l+16>>2]=c[a+16>>2];g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=c[b+12>>2]|0;a=0;while(1)if(!(g>>>a))break;else a=a+1|0;if((jb(l,a+-1|0)|0)==-1){l=1;i=m;return l|0}if((d|0)==5?(h=nb(l,j)|0,(h|0)!=0):0){l=h;i=m;return l|0}g=ob(l,f)|0;if(g){l=g;i=m;return l|0}if((e|0)!=0?(k=ob(l,f+4|0)|0,(k|0)!=0):0){l=k;i=m;return l|0}l=0;i=m;return l|0}function _a(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,j=0,k=0,l=0,m=0,n=0,o=0;m=i;i=i+32|0;l=m+24|0;j=m+20|0;k=m;c[k+0>>2]=c[b+0>>2];c[k+4>>2]=c[b+4>>2];c[k+8>>2]=c[b+8>>2];c[k+12>>2]=c[b+12>>2];c[k+16>>2]=c[b+16>>2];f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=c[d+12>>2]|0;b=0;while(1)if(!(f>>>b))break;else b=b+1|0;if((jb(k,b+-1|0)|0)==-1){n=1;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}g=d+16|0;f=c[g>>2]|0;if(!f){b=c[d+20>>2]|0;f=0;while(1)if(!(b>>>f))break;else f=f+1|0;if((jb(k,f+-1|0)|0)==-1){n=1;i=m;return n|0}if((c[e+8>>2]|0)!=0?(h=ob(k,j)|0,(h|0)!=0):0){n=h;i=m;return n|0}f=c[g>>2]|0}if((f|0)==1?(c[d+24>>2]|0)==0:0){f=ob(k,j)|0;if(f){n=f;i=m;return n|0}if((c[e+8>>2]|0)!=0?(n=ob(k,j)|0,(n|0)!=0):0){i=m;return n|0}}if((c[e+68>>2]|0)!=0?(o=nb(k,l)|0,(o|0)!=0):0){n=o;i=m;return n|0}n=jb(k,1)|0;c[a>>2]=n;n=(n|0)==-1&1;i=m;return n|0}function $a(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=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;C=i;i=i+448|0;p=C+8|0;x=C+4|0;v=C;p=p+(0-p&15)|0;n=c[b+3376>>2]|0;j=c[e>>2]|0;c[x>>2]=0;y=b+1192|0;c[y>>2]=(c[y>>2]|0)+1;q=b+1200|0;c[q>>2]=0;o=b+12|0;c[v>>2]=(c[e+48>>2]|0)+(c[(c[o>>2]|0)+52>>2]|0);w=e+36|0;r=b+1212|0;s=e+52|0;t=e+56|0;u=e+60|0;z=e+4|0;l=e+44|0;h=b+1220|0;m=b+1172|0;B=b+1176|0;k=n+12|0;A=0;f=0;while(1){e=c[r>>2]|0;if((c[w>>2]|0)==0?(c[e+(j*216|0)+196>>2]|0)!=0:0){f=1;e=22;break}g=c[(c[o>>2]|0)+56>>2]|0;F=c[s>>2]|0;E=c[t>>2]|0;D=c[u>>2]|0;c[e+(j*216|0)+4>>2]=c[y>>2];c[e+(j*216|0)+8>>2]=F;c[e+(j*216|0)+12>>2]=E;c[e+(j*216|0)+16>>2]=D;c[e+(j*216|0)+24>>2]=g;e=c[z>>2]|0;if((e|0)!=2?!((e|0)==7|(f|0)!=0):0){f=nb(a,x)|0;if(f){e=22;break}e=c[x>>2]|0;if(e>>>0>((c[B>>2]|0)-j|0)>>>0){f=1;e=22;break}if(!e)f=0;else{id(k,0,164);c[n>>2]=0;f=1}}e=c[x>>2]|0;if(!e){f=bb(a,n,(c[r>>2]|0)+(j*216|0)|0,c[z>>2]|0,c[l>>2]|0)|0;if(!f)g=0;else{e=22;break}}else{c[x>>2]=e+-1;g=f}f=gb((c[r>>2]|0)+(j*216|0)|0,n,d,h,v,j,c[(c[o>>2]|0)+64>>2]|0,p)|0;if(f){e=22;break}A=((c[(c[r>>2]|0)+(j*216|0)+196>>2]|0)==1&1)+A|0;if(!(La(a)|0))e=(c[x>>2]|0)!=0;else e=1;f=c[z>>2]|0;if((f|0)==7|(f|0)==2)c[q>>2]=j;j=Ma(c[m>>2]|0,c[B>>2]|0,j)|0;if(!((j|0)!=0|e^1)){f=1;e=22;break}if(!e){e=20;break}else f=g}if((e|0)==20){e=b+1196|0;f=(c[e>>2]|0)+A|0;if(f>>>0>(c[B>>2]|0)>>>0){y=1;i=C;return y|0}c[e>>2]=f;y=0;i=C;return y|0}else if((e|0)==22){i=C;return f|0}return 0}function ab(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;h=c[a+1192>>2]|0;d=c[a+1200>>2]|0;j=a+1212|0;a:do if(!d)d=b;else{e=a+16|0;f=0;do{do{d=d+-1|0;if(d>>>0<=b>>>0)break a}while((c[(c[j>>2]|0)+(d*216|0)+4>>2]|0)!=(h|0));f=f+1|0;g=c[(c[e>>2]|0)+52>>2]|0}while(f>>>0<(g>>>0>10?g:10)>>>0)}while(0);g=a+1172|0;b=a+1176|0;while(1){e=c[j>>2]|0;if((c[e+(d*216|0)+4>>2]|0)!=(h|0)){d=11;break}f=e+(d*216|0)+196|0;e=c[f>>2]|0;if(!e){d=11;break}c[f>>2]=e+-1;d=Ma(c[g>>2]|0,c[b>>2]|0,d)|0;if(!d){d=11;break}}if((d|0)==11){i=k;return}}function bb(a,d,e,f,g){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=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;B=i;i=i+32|0;u=B+20|0;v=B+16|0;q=B+12|0;p=B+8|0;z=B+4|0;y=B;id(d,0,2088);l=nb(a,z)|0;m=c[z>>2]|0;do if((f|0)==2|(f|0)==7){m=m+6|0;if(m>>>0>31|(l|0)!=0){e=1;i=B;return e|0}else{c[d>>2]=m;o=m;break}}else{m=m+1|0;if(m>>>0>31|(l|0)!=0){e=1;i=B;return e|0}else{c[d>>2]=m;o=m;break}}while(0);a:do if((o|0)!=31){b:do if(o>>>0>=6){o=(o|0)!=6;p=o&1;if(!p){c[v>>2]=0;q=0;while(1){f=kb(a)|0;c[u>>2]=f;t=f>>>31;c[d+(q<<2)+12>>2]=t;if(!t){c[d+(q<<2)+76>>2]=f>>>28&7;m=f<<4;n=1}else{m=f<<1;n=0}f=q|1;t=m>>>31;c[d+(f<<2)+12>>2]=t;if(!t){c[d+(f<<2)+76>>2]=m>>>28&7;l=m<<4;n=n+1|0}else l=m<<1;m=f+1|0;t=l>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=l>>>28&7;m=l<<4;n=n+1|0}else m=l<<1;l=q|3;t=m>>>31;c[d+(l<<2)+12>>2]=t;if(!t){c[d+(l<<2)+76>>2]=m>>>28&7;f=m<<4;n=n+1|0}else f=m<<1;m=l+1|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=l+2|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=l+3|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=q|7;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;m=f<<4;n=n+1|0}else m=f<<1;c[u>>2]=m;if((lb(a,(n*3|0)+8|0)|0)==-1){w=1;t=68;break b}t=(c[v>>2]|0)+1|0;c[v>>2]=t;if((t|0)<2)q=q+8|0;else{t=52;break}}}else if((p|0)==1)t=52;if((t|0)==52){v=(nb(a,u)|0)!=0;l=c[u>>2]|0;if(v|l>>>0>3){w=1;t=68;break}c[d+140>>2]=l}if(o){v=c[d>>2]|0;s=v+-7|0;u=s>>>2;c[d+4>>2]=(s>>>0>11?u+268435453|0:u)<<4|(v>>>0>18?15:0)}else{x=p;t=70}}else{if((o|0)==0|(o|0)==1){r=v;s=u}else if(!((o|0)==3|(o|0)==2)){f=0;do{l=(nb(a,q)|0)!=0;m=c[q>>2]|0;if(l|m>>>0>3){n=1;t=96;break}c[d+(f<<2)+176>>2]=m;f=f+1|0}while(f>>>0<4);if((t|0)==96){i=B;return n|0}c:do if(g>>>0>1&(o|0)!=5){m=g>>>0>2&1;f=0;while(1){if(qb(a,q,m)|0){n=1;t=96;break}n=c[q>>2]|0;if(n>>>0>=g>>>0){n=1;t=96;break}c[d+(f<<2)+192>>2]=n;f=f+1|0;if(f>>>0>=4){h=0;break c}}if((t|0)==96){i=B;return n|0}}else h=0;while(0);d:while(1){n=c[d+(h<<2)+176>>2]|0;if(!n)n=0;else if((n|0)==2|(n|0)==1)n=1;else n=3;c[q>>2]=n;m=0;while(1){n=ob(a,p)|0;if(n){t=96;break d}b[d+(h<<4)+(m<<2)+208>>1]=c[p>>2];n=ob(a,p)|0;if(n){t=96;break d}b[d+(h<<4)+(m<<2)+210>>1]=c[p>>2];t=c[q>>2]|0;c[q>>2]=t+-1;if(!t)break;else m=m+1|0}h=h+1|0;if(h>>>0>=4){x=2;t=70;break b}}if((t|0)==96){i=B;return n|0}}else{r=v;s=u}if(g>>>0>1){if((o|0)==0|(o|0)==1)n=0;else if((o|0)==3|(o|0)==2)n=1;else n=3;l=g>>>0>2&1;f=0;while(1){if(qb(a,u,l)|0){w=1;t=68;break b}m=c[u>>2]|0;if(m>>>0>=g>>>0){w=1;t=68;break b}c[d+(f<<2)+144>>2]=m;if(!n)break;else{n=n+-1|0;f=f+1|0}}}if((o|0)==0|(o|0)==1){l=0;m=0}else if((o|0)==3|(o|0)==2){l=1;m=0}else{l=3;m=0}while(1){f=ob(a,v)|0;if(f){w=f;t=68;break b}b[d+(m<<2)+160>>1]=c[v>>2];f=ob(a,v)|0;if(f){w=f;t=68;break b}b[d+(m<<2)+162>>1]=c[v>>2];if(!l){x=2;t=70;break}else{l=l+-1|0;m=m+1|0}}}while(0);if((t|0)==68){e=w;i=B;return e|0}do if((t|0)==70){h=pb(a,z,(x|0)==0&1)|0;if(!h){z=c[z>>2]|0;c[d+4>>2]=z;if(!z)break a;else break}else{e=h;i=B;return e|0}}while(0);z=(ob(a,y)|0)!=0;h=c[y>>2]|0;if(z|(h|0)<-26|(h|0)>25){e=1;i=B;return e|0}c[d+8>>2]=h;l=c[d+4>>2]|0;o=d+272|0;e:do if((c[d>>2]|0)>>>0>=7){h=rb(a,d+1864|0,ib(e,0,o)|0,16)|0;if(!(h&15)){b[d+320>>1]=h>>>4&255;h=0;m=3;while(1){n=l>>>1;if(!(l&1))h=h+4|0;else{f=3;while(1){l=rb(a,d+(h<<6)+332|0,ib(e,h,o)|0,15)|0;c[d+(h<<2)+1992>>2]=l>>>15;if(l&15){j=l;break e}b[d+(h<<1)+272>>1]=l>>>4&255;h=h+1|0;if(!f)break;else f=f+-1|0}}if(!m){k=h;A=n;t=87;break}else{l=n;m=m+-1|0}}}else j=h}else{h=0;m=3;while(1){n=l>>>1;if(!(l&1))h=h+4|0;else{f=3;while(1){l=rb(a,d+(h<<6)+328|0,ib(e,h,o)|0,16)|0;c[d+(h<<2)+1992>>2]=l>>>16;if(l&15){j=l;break e}b[d+(h<<1)+272>>1]=l>>>4&255;h=h+1|0;if(!f)break;else f=f+-1|0}}if(!m){k=h;A=n;t=87;break}else{l=n;m=m+-1|0}}}while(0);f:do if((t|0)==87){if(A&3){j=rb(a,d+1928|0,-1,4)|0;if(j&15)break;b[d+322>>1]=j>>>4&255;j=rb(a,d+1944|0,-1,4)|0;if(j&15)break;b[d+324>>1]=j>>>4&255}if(!(A&2))j=0;else{h=7;while(1){j=rb(a,d+(k<<6)+332|0,ib(e,k,o)|0,15)|0;if(j&15)break f;b[d+(k<<1)+272>>1]=j>>>4&255;c[d+(k<<2)+1992>>2]=j>>>15;if(!h){j=0;break}else{k=k+1|0;h=h+-1|0}}}}while(0);c[a+16>>2]=((c[a+4>>2]|0)-(c[a>>2]|0)<<3)+(c[a+8>>2]|0);if(j){e=j;i=B;return e|0}}else{while(1){if(mb(a)|0)break;if(jb(a,1)|0){n=1;t=96;break}}if((t|0)==96){i=B;return n|0}k=0;j=d+328|0;while(1){h=jb(a,8)|0;c[z>>2]=h;if((h|0)==-1){n=1;break}c[j>>2]=h;k=k+1|0;if(k>>>0>=384)break a;else j=j+4|0}i=B;return n|0}while(0);e=0;i=B;return e|0}function cb(a){a=a|0;if(a>>>0<6)a=2;else a=(a|0)!=6&1;return a|0}function db(a){a=a|0;var b=0;b=i;if((a|0)==0|(a|0)==1)a=1;else if((a|0)==3|(a|0)==2)a=2;else a=4;i=b;return a|0}function eb(a){a=a|0;var b=0;b=i;if(!a)a=1;else if((a|0)==2|(a|0)==1)a=2;else a=4;i=b;return a|0}function fb(a){a=a|0;return a+1&3|0}function gb(d,e,f,g,h,j,k,l){d=d|0;e=e|0;f=f|0;g=g|0;h=h|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;v=i;s=c[e>>2]|0;c[d>>2]=s;o=d+196|0;c[o>>2]=(c[o>>2]|0)+1;Na(f,j);if((s|0)==31){m=d+28|0;c[d+20>>2]=0;if((c[o>>2]|0)>>>0>1){b[m>>1]=16;b[d+30>>1]=16;b[d+32>>1]=16;b[d+34>>1]=16;b[d+36>>1]=16;b[d+38>>1]=16;b[d+40>>1]=16;b[d+42>>1]=16;b[d+44>>1]=16;b[d+46>>1]=16;b[d+48>>1]=16;b[d+50>>1]=16;b[d+52>>1]=16;b[d+54>>1]=16;b[d+56>>1]=16;b[d+58>>1]=16;b[d+60>>1]=16;b[d+62>>1]=16;b[d+64>>1]=16;b[d+66>>1]=16;b[d+68>>1]=16;b[d+70>>1]=16;b[d+72>>1]=16;b[d+74>>1]=16;t=0;i=v;return t|0}o=23;h=e+328|0;n=l;while(1){b[m>>1]=16;a[n>>0]=c[h>>2];a[n+1>>0]=c[h+4>>2];a[n+2>>0]=c[h+8>>2];a[n+3>>0]=c[h+12>>2];a[n+4>>0]=c[h+16>>2];a[n+5>>0]=c[h+20>>2];a[n+6>>0]=c[h+24>>2];a[n+7>>0]=c[h+28>>2];a[n+8>>0]=c[h+32>>2];a[n+9>>0]=c[h+36>>2];a[n+10>>0]=c[h+40>>2];a[n+11>>0]=c[h+44>>2];a[n+12>>0]=c[h+48>>2];a[n+13>>0]=c[h+52>>2];a[n+14>>0]=c[h+56>>2];a[n+15>>0]=c[h+60>>2];if(!o)break;else{o=o+-1|0;h=h+64|0;n=n+16|0;m=m+2|0}}sc(f,l);t=0;i=v;return t|0}m=d+28|0;if(s){hd(m,e+272|0,54);n=c[e+8>>2]|0;o=c[h>>2]|0;do if(n){o=o+n|0;c[h>>2]=o;if((o|0)<0){o=o+52|0;c[h>>2]=o;break}if((o|0)>51){o=o+-52|0;c[h>>2]=o}}while(0);r=d+20|0;c[r>>2]=o;n=e+328|0;h=e+1992|0;a:do if((c[d>>2]|0)>>>0<7){q=15;o=m;while(1){if(b[o>>1]|0){if(Ga(n,c[r>>2]|0,0,c[h>>2]|0)|0){m=1;break}}else c[n>>2]=16777215;n=n+64|0;o=o+2|0;h=h+4|0;if(!q)break a;else q=q+-1|0}i=v;return m|0}else{if(!(b[d+76>>1]|0)){q=464;p=15;o=m}else{Ha(e+1864|0,o);q=464;p=15;o=m}while(1){m=c[e+(c[q>>2]<<2)+1864>>2]|0;q=q+4|0;c[n>>2]=m;if((m|0)==0?(b[o>>1]|0)==0:0)c[n>>2]=16777215;else u=18;if((u|0)==18?(u=0,(Ga(n,c[r>>2]|0,1,c[h>>2]|0)|0)!=0):0){m=1;break}n=n+64|0;o=o+2|0;h=h+4|0;if(!p)break a;else p=p+-1|0}i=v;return m|0}while(0);q=c[192+((Oa(0,51,(c[d+24>>2]|0)+(c[r>>2]|0)|0)|0)<<2)>>2]|0;if((b[d+78>>1]|0)==0?(b[d+80>>1]|0)==0:0){p=e+1928|0;m=7}else{p=e+1928|0;Ia(p,q);m=7}while(1){r=c[p>>2]|0;p=p+4|0;c[n>>2]=r;if((r|0)==0?(b[o>>1]|0)==0:0)c[n>>2]=16777215;else u=31;if((u|0)==31?(u=0,(Ga(n,q,1,c[h>>2]|0)|0)!=0):0){m=1;u=39;break}if(!m)break;else{n=n+64|0;h=h+4|0;m=m+-1|0;o=o+2|0}}if((u|0)==39){i=v;return m|0}if(s>>>0>=6){o=Mb(d,e,f,j,k,l)|0;if(o){t=o;i=v;return t|0}}else u=37}else{id(m,0,54);c[d+20>>2]=c[h>>2];u=37}if((u|0)==37?(t=Sb(d,e,g,j,f,l)|0,(t|0)!=0):0){i=v;return t|0}t=0;i=v;return t|0}function hb(a){a=a|0;return a|0}function ib(d,e,f){d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0;k=i;l=vb(e)|0;g=wb(e)|0;h=a[l+4>>0]|0;j=a[g+4>>0]|0;g=(c[g>>2]|0)==4;if((c[l>>2]|0)==4){e=b[f+((h&255)<<1)>>1]|0;if(g){e=e+1+(b[f+((j&255)<<1)>>1]|0)>>1;i=k;return e|0}g=d+204|0;if(!(zb(d,c[g>>2]|0)|0)){i=k;return e|0}e=e+1+(b[(c[g>>2]|0)+((j&255)<<1)+28>>1]|0)>>1;i=k;return e|0}if(g){e=b[f+((j&255)<<1)>>1]|0;g=d+200|0;if(!(zb(d,c[g>>2]|0)|0)){i=k;return e|0}e=e+1+(b[(c[g>>2]|0)+((h&255)<<1)+28>>1]|0)>>1;i=k;return e|0}g=d+200|0;if(!(zb(d,c[g>>2]|0)|0)){h=0;f=0}else{h=b[(c[g>>2]|0)+((h&255)<<1)+28>>1]|0;f=1}g=d+204|0;if(!(zb(d,c[g>>2]|0)|0)){e=h;i=k;return e|0}e=b[(c[g>>2]|0)+((j&255)<<1)+28>>1]|0;if(!f){i=k;return e|0}e=h+1+e>>1;i=k;return e|0}function jb(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;n=a+4|0;j=c[n>>2]|0;m=c[a+12>>2]<<3;o=a+16|0;l=c[o>>2]|0;g=m-l|0;if((g|0)>31){e=a+8|0;g=c[e>>2]|0;f=(d[j+1>>0]|0)<<16|(d[j>>0]|0)<<24|(d[j+2>>0]|0)<<8|(d[j+3>>0]|0);if(!g)h=e;else{h=e;f=(d[j+4>>0]|0)>>>(8-g|0)|f<0){e=c[h>>2]|0;k=e+24|0;f=(d[j>>0]|0)<0){e=g;g=k;do{j=j+1|0;g=g+-8|0;f=(d[j>>0]|0)<0)}}else f=0}e=l+b|0;c[o>>2]=e;c[h>>2]=e&7;if(e>>>0>m>>>0){n=-1;i=p;return n|0}c[n>>2]=(c[a>>2]|0)+(e>>>3);n=f>>>(32-b|0);i=p;return n|0}function kb(a){a=a|0;var b=0,e=0,f=0,g=0,h=0;g=i;f=c[a+4>>2]|0;e=(c[a+12>>2]<<3)-(c[a+16>>2]|0)|0;if((e|0)>31){b=c[a+8>>2]|0;a=(d[f+1>>0]|0)<<16|(d[f>>0]|0)<<24|(d[f+2>>0]|0)<<8|(d[f+3>>0]|0);if(!b){b=a;i=g;return b|0}b=(d[f+4>>0]|0)>>>(8-b|0)|a<>2]|0;a=h+24|0;b=(d[f>>0]|0)<>0]|0)<0);i=g;return b|0}function lb(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;e=a+16|0;b=(c[e>>2]|0)+b|0;c[e>>2]=b;c[a+8>>2]=b&7;if(b>>>0>c[a+12>>2]<<3>>>0){b=-1;i=d;return b|0}c[a+4>>2]=(c[a>>2]|0)+(b>>>3);b=0;i=d;return b|0}function mb(a){a=a|0;return (c[a+8>>2]|0)==0|0}function nb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=i;d=kb(a)|0;do if((d|0)>=0){if(d>>>0>1073741823){if((lb(a,3)|0)==-1){d=1;break}c[b>>2]=(d>>>29&1)+1;d=0;break}if(d>>>0>536870911){if((lb(a,5)|0)==-1){d=1;break}c[b>>2]=(d>>>27&3)+3;d=0;break}if(d>>>0>268435455){if((lb(a,7)|0)==-1){d=1;break}c[b>>2]=(d>>>25&7)+7;d=0;break}d=Ja(d,28)|0;e=d+4|0;if((e|0)!=32){lb(a,d+5|0)|0;d=jb(a,e)|0;if((d|0)==-1){d=1;break}c[b>>2]=(1<>2]=0;lb(a,32)|0;if((jb(a,1)|0)==1?(f=kb(a)|0,(lb(a,32)|0)!=-1):0)if((f|0)==1){c[b>>2]=-1;d=1;break}else if(!f){c[b>>2]=-1;d=0;break}else{d=1;break}else d=1}else{lb(a,1)|0;c[b>>2]=0;d=0}while(0);i=g;return d|0}function ob(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;f=e;c[f>>2]=0;d=nb(a,f)|0;a=c[f>>2]|0;d=(d|0)==0;if((a|0)==-1)if(d)a=1;else{c[b>>2]=-2147483648;a=0}else if(d){d=(a+1|0)>>>1;c[b>>2]=(a&1|0)!=0?d:0-d|0;a=0}else a=1;i=e;return a|0}function pb(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0;g=i;i=i+16|0;f=g;if(nb(a,f)|0){f=1;i=g;return f|0}f=c[f>>2]|0;if(f>>>0>47){f=1;i=g;return f|0}c[b>>2]=d[((e|0)==0?576:528)+f>>0];f=0;i=g;return f|0}function qb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=i;if(!d){d=jb(a,1)|0;c[b>>2]=d;if((d|0)==-1)d=1;else{c[b>>2]=d^1;d=0}}else d=nb(a,b)|0;i=e;return d|0}function rb(a,b,f,g){a=a|0;b=b|0;f=f|0;g=g|0;var h=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,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0;O=i;i=i+128|0;M=O+64|0;N=O;n=kb(a)|0;p=n>>>16;do if(f>>>0<2)if((n|0)>=0){if(n>>>0>201326591){o=e[1264+(n>>>26<<1)>>1]|0;k=25;break}if(n>>>0>16777215){o=e[1328+(n>>>22<<1)>>1]|0;k=25;break}if(n>>>0>2097151){o=e[1424+((n>>>18)+-8<<1)>>1]|0;k=25;break}else{o=e[1536+(p<<1)>>1]|0;k=25;break}}else q=1;else if(f>>>0<4){if((n|0)<0){q=(p&16384|0)!=0?2:2082;break}if(n>>>0>268435455){o=e[1600+(n>>>26<<1)>>1]|0;k=25;break}if(n>>>0>33554431){o=e[1664+(n>>>23<<1)>>1]|0;k=25;break}else{o=e[1728+(n>>>18<<1)>>1]|0;k=25;break}}else{if(f>>>0<8){f=n>>>26;if((f+-8|0)>>>0<56){o=e[1984+(f<<1)>>1]|0;k=25;break}o=e[2112+(n>>>22<<1)>>1]|0;k=25;break}if(f>>>0<17){o=e[2368+(n>>>26<<1)>>1]|0;k=25;break}f=n>>>29;if(f){o=e[2496+(f<<1)>>1]|0;k=25;break}o=e[2512+(n>>>24<<1)>>1]|0;k=25;break}while(0);if((k|0)==25)if(!o){C=1;i=O;return C|0}else q=o;o=q&31;f=n<>>11&31;if(I>>>0>g>>>0){C=1;i=O;return C|0}v=q>>>5&63;do if(I){if(!v)o=0;else{do if(p>>>0>>0)if((lb(a,o)|0)==-1){C=1;i=O;return C|0}else{p=32;f=kb(a)|0;break}while(0);n=f>>>(32-v|0);f=f<>2]=(o&n|0)!=0?-1:1;o=o>>>1;k=k+1|0}while((o|0)!=0);p=p-v|0;o=k}u=v>>>0<3;a:do if(o>>>0>>0){t=o;s=I>>>0>10&u&1;b:while(1){if(p>>>0<16){if((lb(a,32-p|0)|0)==-1){J=1;k=127;break}r=32;f=kb(a)|0}else r=p;do if((f|0)>=0)if(f>>>0<=1073741823)if(f>>>0<=536870911)if(f>>>0<=268435455)if(f>>>0<=134217727)if(f>>>0<=67108863)if(f>>>0<=33554431)if(f>>>0<=16777215)if(f>>>0<=8388607)if(f>>>0>4194303){H=9;k=59}else{if(f>>>0>2097151){H=10;k=59;break}if(f>>>0>1048575){H=11;k=59;break}if(f>>>0>524287){H=12;k=59;break}if(f>>>0>262143){H=13;k=59;break}if(f>>>0>131071){p=14;o=f<<15;n=r+-15|0;q=s;k=(s|0)!=0?s:4}else{if(f>>>0<65536){J=1;k=127;break b}p=15;o=f<<16;n=r+-16|0;q=(s|0)!=0?s:1;k=12}G=p<>>0>>0){if((lb(a,32-y|0)|0)==-1){J=1;k=127;break}o=32;f=kb(a)|0}else{o=y;f=B}E=o-x|0;F=f<>>(32-x|0))+G|0;C=z;D=w}s=(t|0)==(v|0)&u?A+2|0:A;o=(s+2|0)>>>1;n=D?1:C;c[M+(t<<2)>>2]=(s&1|0)==0?o:0-o|0;t=t+1|0;if(t>>>0>=I>>>0){l=E;m=F;break a}else{p=E;f=F;s=((o|0)>(3<>>0<6&1)+n|0}}if((k|0)==127){i=O;return J|0}}else{l=p;m=f}while(0);if(I>>>0>>0){do if(l>>>0<9)if((lb(a,32-l|0)|0)==-1){C=1;i=O;return C|0}else{l=32;m=kb(a)|0;break}while(0);k=m>>>23;c:do if((g|0)==4)if((m|0)>=0)if((I|0)!=3)if(m>>>0<=1073741823)if((I|0)==2)k=34;else k=m>>>0>536870911?35:51;else k=18;else k=17;else k=1;else{do switch(I|0){case 8:{k=d[1056+(m>>>26)>>0]|0;break}case 9:{k=d[1120+(m>>>26)>>0]|0;break}case 2:{k=d[736+(m>>>26)>>0]|0;break}case 1:{if(m>>>0>268435455)k=d[672+(m>>>27)>>0]|0;else k=d[704+k>>0]|0;break}case 13:{k=d[1248+(m>>>29)>>0]|0;break}case 14:{k=d[1256+(m>>>30)>>0]|0;break}case 3:{k=d[800+(m>>>26)>>0]|0;break}case 4:{k=d[864+(m>>>27)>>0]|0;break}case 5:{k=d[896+(m>>>27)>>0]|0;break}case 10:{k=d[1184+(m>>>27)>>0]|0;break}case 6:{k=d[928+(m>>>26)>>0]|0;break}case 7:{k=d[992+(m>>>26)>>0]|0;break}case 11:{k=d[1216+(m>>>28)>>0]|0;break}case 12:{k=d[1232+(m>>>28)>>0]|0;break}default:{k=m>>31&16|1;break c}}while(0);if(!k){C=1;i=O;return C|0}}while(0);n=k&15;l=l-n|0;m=m<>>4&15}else n=0;p=I+-1|0;f=(p|0)==0;if(f){c[b+(n<<2)>>2]=c[M+(p<<2)>>2];K=l;h=1<>2]=1;L=l;j=0}else{if(l>>>0<11){if((lb(a,32-l|0)|0)==-1){J=1;k=127;break}l=32;k=kb(a)|0}switch(n|0){case 4:{m=d[648+(k>>>29)>>0]|0;break}case 5:{m=d[656+(k>>>29)>>0]|0;break}case 6:{m=d[664+(k>>>29)>>0]|0;break}case 1:{m=d[624+(k>>>31)>>0]|0;break}case 2:{m=d[632+(k>>>30)>>0]|0;break}case 3:{m=d[640+(k>>>30)>>0]|0;break}default:{do if(k>>>0<=536870911)if(k>>>0<=268435455)if(k>>>0<=134217727)if(k>>>0<=67108863)if(k>>>0<=33554431)if(k>>>0>16777215)m=184;else{if(k>>>0>8388607){m=201;break}if(k>>>0>4194303){m=218;break}m=k>>>0<2097152?0:235}else m=167;else m=150;else m=133;else m=116;else m=k>>>29<<4^115;while(0);if((m>>>4&15)>>>0>n>>>0){J=1;k=127;break d}}}if(!m){J=1;k=127;break}C=m&15;j=m>>>4&15;c[N+(o<<2)>>2]=j+1;L=l-C|0;k=k<>>0>=p>>>0){k=122;break}else{l=L;n=j}}if((k|0)==122){c[b+(j<<2)>>2]=c[M+(p<<2)>>2];h=1<>2]|0)+j|0;h=1<>2]=c[M+(k<<2)>>2];if(!k){K=L;break}else k=k+-1|0}}else if((k|0)==127){i=O;return J|0}}else{K=p;h=0}while(0);if(lb(a,32-K|0)|0){C=1;i=O;return C|0}C=h<<16|I<<4;i=O;return C|0}function sb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;a:do if((jb(a,1)|0)!=-1?(e=b+4|0,c[e>>2]=jb(a,2)|0,d=jb(a,5)|0,c[b>>2]=d,(d+-2|0)>>>0>=3):0){switch(d|0){case 6:case 9:case 10:case 11:case 12:{if(c[e>>2]|0){d=1;break a}break}case 5:case 7:case 8:{if(!(c[e>>2]|0)){d=1;break a}switch(d|0){case 6:case 9:case 10:case 11:case 12:{d=1;break a}default:{}}break}default:{}}d=0}else d=1;while(0);i=f;return d|0}function tb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;if(!d){i=o;return}m=b+-1|0;j=1-b|0;k=~b;g=0;h=0;l=0;while(1){f=(g|0)!=0;if(f)c[a+(h*216|0)+200>>2]=a+((h+-1|0)*216|0);else c[a+(h*216|0)+200>>2]=0;e=(l|0)!=0;if(e){c[a+(h*216|0)+204>>2]=a+((h-b|0)*216|0);if(g>>>0>>0)c[a+(h*216|0)+208>>2]=a+((j+h|0)*216|0);else n=10}else{c[a+(h*216|0)+204>>2]=0;n=10}if((n|0)==10){n=0;c[a+(h*216|0)+208>>2]=0}if(e&f)c[a+(h*216|0)+212>>2]=a+((h+k|0)*216|0);else c[a+(h*216|0)+212>>2]=0;e=g+1|0;f=(e|0)==(b|0);h=h+1|0;if((h|0)==(d|0))break;else{g=f?0:e;l=(f&1)+l|0}}i=o;return}function ub(a,b){a=a|0;b=b|0;var d=0;d=i;switch(b|0){case 1:{a=c[a+204>>2]|0;break}case 3:{a=c[a+212>>2]|0;break}case 4:break;case 2:{a=c[a+208>>2]|0;break}case 0:{a=c[a+200>>2]|0;break}default:a=0}i=d;return a|0}function vb(a){a=a|0;return 3152+(a<<3)|0}function wb(a){a=a|0;return 2960+(a<<3)|0}function xb(a){a=a|0;return 2768+(a<<3)|0}function yb(a){a=a|0;return 2576+(a<<3)|0}function zb(a,b){a=a|0;b=b|0;var d=0;d=i;if(!b){i=d;return 0}else{i=d;return (c[a+4>>2]|0)==(c[b+4>>2]|0)|0}return 0}function Ab(a){a=a|0;var b=0;b=i;id(a,0,3388);c[a+8>>2]=32;c[a+4>>2]=256;c[a+1332>>2]=1;i=b;return}function Bb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;f=c[b+8>>2]|0;g=a+(f<<2)+20|0;e=c[g>>2]|0;do if(!e){d=fd(92)|0;c[g>>2]=d;if(!d){d=65535;i=h;return d|0}}else{d=a+8|0;if((f|0)!=(c[d>>2]|0)){gd(c[e+40>>2]|0);c[(c[g>>2]|0)+40>>2]=0;gd(c[(c[g>>2]|0)+84>>2]|0);c[(c[g>>2]|0)+84>>2]=0;break}f=a+16|0;if(Ra(b,c[f>>2]|0)|0){gd(c[(c[g>>2]|0)+40>>2]|0);c[(c[g>>2]|0)+40>>2]=0;gd(c[(c[g>>2]|0)+84>>2]|0);c[(c[g>>2]|0)+84>>2]=0;c[d>>2]=33;c[a+4>>2]=257;c[f>>2]=0;c[a+12>>2]=0;break}d=b+40|0;gd(c[d>>2]|0);c[d>>2]=0;d=b+84|0;gd(c[d>>2]|0);c[d>>2]=0;d=0;i=h;return d|0}while(0);f=(c[g>>2]|0)+0|0;d=b+0|0;e=f+92|0;do{c[f>>2]=c[d>>2];f=f+4|0;d=d+4|0}while((f|0)<(e|0));d=0;i=h;return d|0}function Cb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;f=c[b>>2]|0;g=a+(f<<2)+148|0;d=c[g>>2]|0;do if(!d){d=fd(72)|0;c[g>>2]=d;if(!d){d=65535;i=h;return d|0}}else{e=a+4|0;if((f|0)!=(c[e>>2]|0)){gd(c[d+20>>2]|0);c[(c[g>>2]|0)+20>>2]=0;gd(c[(c[g>>2]|0)+24>>2]|0);c[(c[g>>2]|0)+24>>2]=0;gd(c[(c[g>>2]|0)+28>>2]|0);c[(c[g>>2]|0)+28>>2]=0;gd(c[(c[g>>2]|0)+44>>2]|0);c[(c[g>>2]|0)+44>>2]=0;break}if((c[b+4>>2]|0)!=(c[a+8>>2]|0)){c[e>>2]=257;d=c[g>>2]|0}gd(c[d+20>>2]|0);c[(c[g>>2]|0)+20>>2]=0;gd(c[(c[g>>2]|0)+24>>2]|0);c[(c[g>>2]|0)+24>>2]=0;gd(c[(c[g>>2]|0)+28>>2]|0);c[(c[g>>2]|0)+28>>2]=0;gd(c[(c[g>>2]|0)+44>>2]|0);c[(c[g>>2]|0)+44>>2]=0}while(0);f=(c[g>>2]|0)+0|0;d=b+0|0;e=f+72|0;do{c[f>>2]=c[d>>2];f=f+4|0;d=d+4|0}while((f|0)<(e|0));d=0;i=h;return d|0}function Db(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;o=a+(b<<2)+148|0;f=c[o>>2]|0;if(!f){o=1;i=q;return o|0}n=c[f+4>>2]|0;g=c[a+(n<<2)+20>>2]|0;if(!g){o=1;i=q;return o|0}l=c[g+52>>2]|0;m=Z(c[g+56>>2]|0,l)|0;h=c[f+12>>2]|0;a:do if(h>>>0>1){g=c[f+16>>2]|0;if((g|0)==2){k=c[f+24>>2]|0;j=c[f+28>>2]|0;h=h+-1|0;e=0;while(1){f=c[k+(e<<2)>>2]|0;g=c[j+(e<<2)>>2]|0;if(!(f>>>0<=g>>>0&g>>>0>>0)){e=1;g=33;break}e=e+1|0;if(((f>>>0)%(l>>>0)|0)>>>0>((g>>>0)%(l>>>0)|0)>>>0){e=1;g=33;break}if(e>>>0>=h>>>0)break a}if((g|0)==33){i=q;return e|0}}else if(!g){g=c[f+20>>2]|0;f=0;while(1){if((c[g+(f<<2)>>2]|0)>>>0>m>>>0){e=1;break}f=f+1|0;if(f>>>0>=h>>>0)break a}i=q;return e|0}else{if((g+-3|0)>>>0<3){if((c[f+36>>2]|0)>>>0>m>>>0)e=1;else break;i=q;return e|0}if((g|0)!=6)break;if((c[f+40>>2]|0)>>>0>>0)e=1;else break;i=q;return e|0}}while(0);f=a+4|0;g=c[f>>2]|0;do if((g|0)!=256){e=a+3380|0;if(!(c[e>>2]|0)){if((g|0)==(b|0))break;g=a+8|0;if((n|0)==(c[g>>2]|0)){c[f>>2]=b;c[a+12>>2]=c[o>>2];break}if(!d){o=1;i=q;return o|0}else{c[f>>2]=b;o=c[o>>2]|0;c[a+12>>2]=o;o=c[o+4>>2]|0;c[g>>2]=o;o=c[a+(o<<2)+20>>2]|0;c[a+16>>2]=o;n=c[o+52>>2]|0;o=c[o+56>>2]|0;c[a+1176>>2]=Z(o,n)|0;c[a+1340>>2]=n;c[a+1344>>2]=o;c[e>>2]=1;break}}c[e>>2]=0;e=a+1212|0;gd(c[e>>2]|0);c[e>>2]=0;f=a+1172|0;gd(c[f>>2]|0);c[f>>2]=0;g=a+1176|0;c[e>>2]=fd((c[g>>2]|0)*216|0)|0;o=fd(c[g>>2]<<2)|0;c[f>>2]=o;f=c[e>>2]|0;if((f|0)==0|(o|0)==0){o=65535;i=q;return o|0}id(f,0,(c[g>>2]|0)*216|0);f=a+16|0;tb(c[e>>2]|0,c[(c[f>>2]|0)+52>>2]|0,c[g>>2]|0);f=c[f>>2]|0;do if((c[a+1216>>2]|0)==0?(c[f+16>>2]|0)!=2:0){if(((c[f+80>>2]|0)!=0?(p=c[f+84>>2]|0,(c[p+920>>2]|0)!=0):0)?(c[p+944>>2]|0)==0:0){e=1;break}e=0}else e=1;while(0);o=Z(c[f+56>>2]|0,c[f+52>>2]|0)|0;e=lc(a+1220|0,o,c[f+88>>2]|0,c[f+44>>2]|0,c[f+12>>2]|0,e)|0;if(e){o=e;i=q;return o|0}}else{c[f>>2]=b;o=c[o>>2]|0;c[a+12>>2]=o;o=c[o+4>>2]|0;c[a+8>>2]=o;o=c[a+(o<<2)+20>>2]|0;c[a+16>>2]=o;n=c[o+52>>2]|0;o=c[o+56>>2]|0;c[a+1176>>2]=Z(o,n)|0;c[a+1340>>2]=n;c[a+1344>>2]=o;c[a+3380>>2]=1}while(0);o=0;i=q;return o|0}function Eb(a){a=a|0;var b=0,d=0,e=0;e=i;c[a+1196>>2]=0;c[a+1192>>2]=0;d=c[a+1176>>2]|0;if(!d){i=e;return}a=c[a+1212>>2]|0;b=0;do{c[a+(b*216|0)+4>>2]=0;c[a+(b*216|0)+196>>2]=0;b=b+1|0}while(b>>>0>>0);i=e;return}function Fb(a){a=a|0;return (c[a+1188>>2]|0)==0|0}function Gb(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;if(!(c[a+1404>>2]|0)){if((c[a+1196>>2]|0)==(c[a+1176>>2]|0)){a=1;i=f;return a|0}}else{e=c[a+1176>>2]|0;if(!e){a=1;i=f;return a|0}a=c[a+1212>>2]|0;b=0;d=0;do{d=((c[a+(b*216|0)+196>>2]|0)!=0&1)+d|0;b=b+1|0}while(b>>>0>>0);if((d|0)==(e|0)){a=1;i=f;return a|0}}a=0;i=f;return a|0}function Hb(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;e=c[a+16>>2]|0;Kb(c[a+1172>>2]|0,c[a+12>>2]|0,b,c[e+52>>2]|0,c[e+56>>2]|0);i=d;return}function Ib(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;i=i+32|0;g=t+24|0;j=t+20|0;k=t+16|0;n=t+12|0;r=t+8|0;q=t;c[e>>2]=0;switch(c[b>>2]|0){case 5:case 1:{s=d+1300|0;h=d+1332|0;if(c[h>>2]|0){c[e>>2]=1;c[h>>2]=0}h=Ua(a,g)|0;if(h){o=h;i=t;return o|0}l=c[d+(c[g>>2]<<2)+148>>2]|0;if(!l){o=65520;i=t;return o|0}h=c[l+4>>2]|0;m=c[d+(h<<2)+20>>2]|0;if(!m){o=65520;i=t;return o|0}g=c[d+8>>2]|0;if(!((g|0)==32|(h|0)==(g|0))?(c[b>>2]|0)!=5:0){o=65520;i=t;return o|0}g=c[d+1304>>2]|0;h=c[b+4>>2]|0;if((g|0)!=(h|0)?(g|0)==0|(h|0)==0:0)c[e>>2]=1;h=(c[b>>2]|0)==5;if((c[s>>2]|0)==5){if(!h)f=16}else if(h)f=16;if((f|0)==16)c[e>>2]=1;g=m+12|0;if(Va(a,c[g>>2]|0,j)|0){o=1;i=t;return o|0}f=d+1308|0;h=c[j>>2]|0;if((c[f>>2]|0)!=(h|0)){c[f>>2]=h;c[e>>2]=1}if((c[b>>2]|0)==5){if(Wa(a,c[g>>2]|0,5,k)|0){o=1;i=t;return o|0}if((c[s>>2]|0)==5){h=d+1312|0;f=c[h>>2]|0;g=c[k>>2]|0;if((f|0)==(g|0))g=f;else c[e>>2]=1}else{g=c[k>>2]|0;h=d+1312|0}c[h>>2]=g}g=c[m+16>>2]|0;if((g|0)==1){if(!(c[m+24>>2]|0)){h=l+8|0;g=Za(a,m,c[b>>2]|0,c[h>>2]|0,q)|0;if(g){o=g;i=t;return o|0}f=d+1324|0;g=c[q>>2]|0;if((c[f>>2]|0)!=(g|0)){c[f>>2]=g;c[e>>2]=1}if((c[h>>2]|0)!=0?(p=d+1328|0,o=c[q+4>>2]|0,(c[p>>2]|0)!=(o|0)):0){c[p>>2]=o;c[e>>2]=1}}}else if(!g){if(Xa(a,m,c[b>>2]|0,n)|0){o=1;i=t;return o|0}f=d+1316|0;g=c[n>>2]|0;if((c[f>>2]|0)!=(g|0)){c[f>>2]=g;c[e>>2]=1}if(c[l+8>>2]|0){f=Ya(a,m,c[b>>2]|0,r)|0;if(f){o=f;i=t;return o|0}g=d+1320|0;f=c[r>>2]|0;if((c[g>>2]|0)!=(f|0)){c[g>>2]=f;c[e>>2]=1}}}n=b;a=c[n+4>>2]|0;o=s;c[o>>2]=c[n>>2];c[o+4>>2]=a;o=0;i=t;return o|0}case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 16:case 17:case 18:{c[e>>2]=1;o=0;i=t;return o|0}default:{o=0;i=t;return o|0}}return 0}function Jb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;n=i;l=0;a:while(1){b=c[a+(l<<2)+148>>2]|0;b:do if((b|0)!=0?(k=c[a+(c[b+4>>2]<<2)+20>>2]|0,(k|0)!=0):0){j=c[k+52>>2]|0;m=Z(c[k+56>>2]|0,j)|0;f=c[b+12>>2]|0;if(f>>>0<=1){b=0;d=18;break a}d=c[b+16>>2]|0;if((d|0)==2){h=c[b+24>>2]|0;g=c[b+28>>2]|0;f=f+-1|0;e=0;while(1){b=c[h+(e<<2)>>2]|0;d=c[g+(e<<2)>>2]|0;if(!(b>>>0<=d>>>0&d>>>0>>0))break b;e=e+1|0;if(((b>>>0)%(j>>>0)|0)>>>0>((d>>>0)%(j>>>0)|0)>>>0)break b;if(e>>>0>=f>>>0){b=0;d=18;break a}}}else if(d){if((d+-3|0)>>>0<3)if((c[b+36>>2]|0)>>>0>m>>>0)break;else{b=0;d=18;break a}if((d|0)!=6){b=0;d=18;break a}if((c[b+40>>2]|0)>>>0>>0)break;else{b=0;d=18;break a}}else{d=c[b+20>>2]|0;b=0;while(1){if((c[d+(b<<2)>>2]|0)>>>0>m>>>0)break b;b=b+1|0;if(b>>>0>=f>>>0){b=0;d=18;break a}}}}while(0);l=l+1|0;if(l>>>0>=256){b=1;d=18;break}}if((d|0)==18){i=n;return b|0}return 0}function Kb(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,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;v=i;t=Z(f,e)|0;o=c[b+12>>2]|0;if((o|0)==1){id(a,0,t<<2);i=v;return}k=c[b+16>>2]|0;if((k+-3|0)>>>0<3){d=Z(c[b+36>>2]|0,d)|0;d=d>>>0>>0?d:t;if((k&-2|0)==4){n=(c[b+32>>2]|0)==0?d:t-d|0;u=d}else{n=0;u=d}}else{n=0;u=0}switch(k|0){case 0:{l=c[b+20>>2]|0;if(!t){i=v;return}else{h=0;j=0}while(1){while(1)if(h>>>0>>0)break;else h=0;b=l+(h<<2)|0;d=c[b>>2]|0;a:do if(!d)d=0;else{k=0;do{g=k+j|0;if(g>>>0>=t>>>0)break a;c[a+(g<<2)>>2]=h;k=k+1|0;d=c[b>>2]|0}while(k>>>0>>0)}while(0);j=d+j|0;if(j>>>0>=t>>>0)break;else h=h+1|0}i=v;return}case 4:{h=c[b+32>>2]|0;if(!t){i=v;return}d=1-h|0;g=0;do{c[a+(g<<2)>>2]=g>>>0>>0?h:d;g=g+1|0}while((g|0)!=(t|0));i=v;return}case 1:{if(!t){i=v;return}else h=0;do{c[a+(h<<2)>>2]=((((Z((h>>>0)/(e>>>0)|0,o)|0)>>>1)+((h>>>0)%(e>>>0)|0)|0)>>>0)%(o>>>0)|0;h=h+1|0}while((h|0)!=(t|0));i=v;return}case 2:{n=c[b+24>>2]|0;m=c[b+28>>2]|0;h=o+-1|0;if(t){d=0;do{c[a+(d<<2)>>2]=h;d=d+1|0}while((d|0)!=(t|0))}if(!h){i=v;return}g=o+-2|0;while(1){j=c[n+(g<<2)>>2]|0;d=(j>>>0)/(e>>>0)|0;j=(j>>>0)%(e>>>0)|0;h=c[m+(g<<2)>>2]|0;l=(h>>>0)/(e>>>0)|0;h=(h>>>0)%(e>>>0)|0;b:do if(d>>>0<=l>>>0){if(j>>>0>h>>>0)while(1){d=d+1|0;if(d>>>0>l>>>0)break b}do{k=Z(d,e)|0;b=j;do{c[a+(b+k<<2)>>2]=g;b=b+1|0}while(b>>>0<=h>>>0);d=d+1|0}while(d>>>0<=l>>>0)}while(0);if(!g)break;else g=g+-1|0}i=v;return}case 5:{d=c[b+32>>2]|0;if(!e){i=v;return}k=1-d|0;if(!f){i=v;return}else{g=0;j=0}while(1){h=0;b=j;while(1){m=a+((Z(h,e)|0)+g<<2)|0;c[m>>2]=b>>>0>>0?d:k;h=h+1|0;if((h|0)==(f|0))break;else b=b+1|0}g=g+1|0;if((g|0)==(e|0))break;else j=j+f|0}i=v;return}case 3:{m=c[b+32>>2]|0;if(t){d=0;do{c[a+(d<<2)>>2]=1;d=d+1|0}while((d|0)!=(t|0))}l=(e-m|0)>>>1;n=(f-m|0)>>>1;if(!u){i=v;return}t=m<<1;r=t+-1|0;s=e+-1|0;t=1-t|0;q=f+-1|0;o=n;p=0;g=l;f=l;k=n;b=l;j=m+-1|0;d=n;while(1){n=a+((Z(d,e)|0)+b<<2)|0;l=(c[n>>2]|0)==1;h=l&1;if(l)c[n>>2]=0;do if(!((j|0)==-1&(b|0)==(g|0))){if((j|0)==1&(b|0)==(f|0)){b=f+1|0;b=(b|0)<(s|0)?b:s;n=o;l=g;f=b;j=0;m=t;break}if((m|0)==-1&(d|0)==(k|0)){d=k+-1|0;d=(d|0)>0?d:0;n=o;l=g;k=d;j=t;m=0;break}if((m|0)==1&(d|0)==(o|0)){d=o+1|0;d=(d|0)<(q|0)?d:q;n=d;l=g;j=r;m=0;break}else{n=o;l=g;b=b+j|0;d=d+m|0;break}}else{b=g+-1|0;b=(b|0)>0?b:0;n=o;l=b;j=0;m=r}while(0);p=h+p|0;if(p>>>0>=u>>>0)break;else{o=n;g=l}}i=v;return}default:{if(!t){i=v;return}g=c[b+44>>2]|0;h=0;do{c[a+(h<<2)>>2]=c[g+(h<<2)>>2];h=h+1|0}while((h|0)!=(t|0));i=v;return}}}function Lb(){return 3472}function Mb(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,j=0,k=0;k=i;i=i+80|0;h=k+32|0;j=k;Nb(d,h,j,e);if((cb(c[a>>2]|0)|0)==1){e=Ob(a,g,b+328|0,h,j,f)|0;if(e){i=k;return e|0}}else{e=Pb(a,g,b,h,j,f)|0;if(e){i=k;return e|0}}e=Qb(a,g+256|0,b+1352|0,h+21|0,j+16|0,c[b+140>>2]|0,f)|0;if(e){i=k;return e|0}if((c[a+196>>2]|0)>>>0>1){e=0;i=k;return e|0}sc(d,g);e=0;i=k;return e|0}function Nb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=i;if(!f){i=s;return}p=c[b+4>>2]|0;q=Z(c[b+8>>2]|0,p)|0;n=(f>>>0)/(p>>>0)|0;g=Z(n,p)|0;o=f-g|0;k=p<<4;h=c[b>>2]|0;j=(o<<4)+(Z(p<<8,n)|0)|0;r=(n|0)!=0;if(r){m=j-(k|1)|0;a[d>>0]=a[h+m>>0]|0;a[d+1>>0]=a[h+(m+1)>>0]|0;a[d+2>>0]=a[h+(m+2)>>0]|0;a[d+3>>0]=a[h+(m+3)>>0]|0;a[d+4>>0]=a[h+(m+4)>>0]|0;a[d+5>>0]=a[h+(m+5)>>0]|0;a[d+6>>0]=a[h+(m+6)>>0]|0;a[d+7>>0]=a[h+(m+7)>>0]|0;a[d+8>>0]=a[h+(m+8)>>0]|0;a[d+9>>0]=a[h+(m+9)>>0]|0;a[d+10>>0]=a[h+(m+10)>>0]|0;a[d+11>>0]=a[h+(m+11)>>0]|0;a[d+12>>0]=a[h+(m+12)>>0]|0;a[d+13>>0]=a[h+(m+13)>>0]|0;a[d+14>>0]=a[h+(m+14)>>0]|0;a[d+15>>0]=a[h+(m+15)>>0]|0;a[d+16>>0]=a[h+(m+16)>>0]|0;a[d+17>>0]=a[h+(m+17)>>0]|0;a[d+18>>0]=a[h+(m+18)>>0]|0;a[d+19>>0]=a[h+(m+19)>>0]|0;a[d+20>>0]=a[h+(m+20)>>0]|0;m=d+21|0}else m=d;l=(g|0)!=(f|0);if(l){j=j+-1|0;a[e>>0]=a[h+j>>0]|0;j=j+k|0;a[e+1>>0]=a[h+j>>0]|0;j=j+k|0;a[e+2>>0]=a[h+j>>0]|0;j=j+k|0;a[e+3>>0]=a[h+j>>0]|0;j=j+k|0;a[e+4>>0]=a[h+j>>0]|0;j=j+k|0;a[e+5>>0]=a[h+j>>0]|0;j=j+k|0;a[e+6>>0]=a[h+j>>0]|0;j=j+k|0;a[e+7>>0]=a[h+j>>0]|0;j=j+k|0;a[e+8>>0]=a[h+j>>0]|0;j=j+k|0;a[e+9>>0]=a[h+j>>0]|0;j=j+k|0;a[e+10>>0]=a[h+j>>0]|0;j=j+k|0;a[e+11>>0]=a[h+j>>0]|0;j=j+k|0;a[e+12>>0]=a[h+j>>0]|0;j=j+k|0;a[e+13>>0]=a[h+j>>0]|0;j=j+k|0;a[e+14>>0]=a[h+j>>0]|0;a[e+15>>0]=a[h+(j+k)>>0]|0;e=e+16|0}d=p<<3&2147483640;f=c[b>>2]|0;g=(Z(n<<3,d)|0)+(q<<8)+(o<<3)|0;if(r){b=g-(d|1)|0;a[m>>0]=a[f+b>>0]|0;a[m+1>>0]=a[f+(b+1)>>0]|0;a[m+2>>0]=a[f+(b+2)>>0]|0;a[m+3>>0]=a[f+(b+3)>>0]|0;a[m+4>>0]=a[f+(b+4)>>0]|0;a[m+5>>0]=a[f+(b+5)>>0]|0;a[m+6>>0]=a[f+(b+6)>>0]|0;a[m+7>>0]=a[f+(b+7)>>0]|0;a[m+8>>0]=a[f+(b+8)>>0]|0;b=b+(q<<6)|0;a[m+9>>0]=a[f+b>>0]|0;a[m+10>>0]=a[f+(b+1)>>0]|0;a[m+11>>0]=a[f+(b+2)>>0]|0;a[m+12>>0]=a[f+(b+3)>>0]|0;a[m+13>>0]=a[f+(b+4)>>0]|0;a[m+14>>0]=a[f+(b+5)>>0]|0;a[m+15>>0]=a[f+(b+6)>>0]|0;a[m+16>>0]=a[f+(b+7)>>0]|0;a[m+17>>0]=a[f+(b+8)>>0]|0}if(!l){i=s;return}m=g+-1|0;a[e>>0]=a[f+m>>0]|0;m=m+d|0;a[e+1>>0]=a[f+m>>0]|0;m=m+d|0;a[e+2>>0]=a[f+m>>0]|0;m=m+d|0;a[e+3>>0]=a[f+m>>0]|0;m=m+d|0;a[e+4>>0]=a[f+m>>0]|0;m=m+d|0;a[e+5>>0]=a[f+m>>0]|0;m=m+d|0;a[e+6>>0]=a[f+m>>0]|0;m=m+d|0;a[e+7>>0]=a[f+m>>0]|0;m=m+(d+((q<<6)-(p<<6)))|0;a[e+8>>0]=a[f+m>>0]|0;m=m+d|0;a[e+9>>0]=a[f+m>>0]|0;m=m+d|0;a[e+10>>0]=a[f+m>>0]|0;m=m+d|0;a[e+11>>0]=a[f+m>>0]|0;m=m+d|0;a[e+12>>0]=a[f+m>>0]|0;m=m+d|0;a[e+13>>0]=a[f+m>>0]|0;m=m+d|0;a[e+14>>0]=a[f+m>>0]|0;a[e+15>>0]=a[f+(m+d)>>0]|0;i=s;return}function Ob(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var 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;z=i;k=b+200|0;l=zb(b,c[k>>2]|0)|0;o=(j|0)!=0;if((l|0)!=0&o){n=(cb(c[c[k>>2]>>2]|0)|0)==2;n=n?0:l}else n=l;j=b+204|0;l=zb(b,c[j>>2]|0)|0;if((l|0)!=0&o){p=(cb(c[c[j>>2]>>2]|0)|0)==2;p=p?0:l}else p=l;j=b+212|0;l=zb(b,c[j>>2]|0)|0;if((l|0)!=0&o){r=(cb(c[c[j>>2]>>2]|0)|0)==2;l=r?0:l}j=fb(c[b>>2]|0)|0;if(!j){if(!p){r=1;i=z;return r|0}b=g+1|0;m=g+2|0;s=g+3|0;t=g+4|0;u=g+5|0;v=g+6|0;w=g+7|0;x=g+8|0;y=g+9|0;h=g+10|0;l=g+11|0;j=g+12|0;k=g+13|0;q=g+14|0;r=g+15|0;p=g+16|0;o=e;n=0;while(1){a[o>>0]=a[b>>0]|0;a[o+1>>0]=a[m>>0]|0;a[o+2>>0]=a[s>>0]|0;a[o+3>>0]=a[t>>0]|0;a[o+4>>0]=a[u>>0]|0;a[o+5>>0]=a[v>>0]|0;a[o+6>>0]=a[w>>0]|0;a[o+7>>0]=a[x>>0]|0;a[o+8>>0]=a[y>>0]|0;a[o+9>>0]=a[h>>0]|0;a[o+10>>0]=a[l>>0]|0;a[o+11>>0]=a[j>>0]|0;a[o+12>>0]=a[k>>0]|0;a[o+13>>0]=a[q>>0]|0;a[o+14>>0]=a[r>>0]|0;a[o+15>>0]=a[p>>0]|0;n=n+1|0;if((n|0)==16)break;else o=o+16|0}}else if((j|0)==2){l=g+1|0;k=(n|0)!=0;j=(p|0)!=0;do if(!(k&j)){if(k){k=((d[h>>0]|0)+8+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)+(d[h+4>>0]|0)+(d[h+5>>0]|0)+(d[h+6>>0]|0)+(d[h+7>>0]|0)+(d[h+8>>0]|0)+(d[h+9>>0]|0)+(d[h+10>>0]|0)+(d[h+11>>0]|0)+(d[h+12>>0]|0)+(d[h+13>>0]|0)+(d[h+14>>0]|0)+(d[h+15>>0]|0)|0)>>>4;break}if(j)k=((d[l>>0]|0)+8+(d[g+2>>0]|0)+(d[g+3>>0]|0)+(d[g+4>>0]|0)+(d[g+5>>0]|0)+(d[g+6>>0]|0)+(d[g+7>>0]|0)+(d[g+8>>0]|0)+(d[g+9>>0]|0)+(d[g+10>>0]|0)+(d[g+11>>0]|0)+(d[g+12>>0]|0)+(d[g+13>>0]|0)+(d[g+14>>0]|0)+(d[g+15>>0]|0)+(d[g+16>>0]|0)|0)>>>4;else k=128}else{j=0;k=0;do{r=j;j=j+1|0;k=(d[g+j>>0]|0)+k+(d[h+r>>0]|0)|0}while((j|0)!=16);k=(k+16|0)>>>5}while(0);nd(e|0,k&255|0,256)|0}else if((j|0)==1)if(!n){r=1;i=z;return r|0}else{k=e;j=0;while(1){r=h+j|0;a[k>>0]=a[r>>0]|0;a[k+1>>0]=a[r>>0]|0;a[k+2>>0]=a[r>>0]|0;a[k+3>>0]=a[r>>0]|0;a[k+4>>0]=a[r>>0]|0;a[k+5>>0]=a[r>>0]|0;a[k+6>>0]=a[r>>0]|0;a[k+7>>0]=a[r>>0]|0;a[k+8>>0]=a[r>>0]|0;a[k+9>>0]=a[r>>0]|0;a[k+10>>0]=a[r>>0]|0;a[k+11>>0]=a[r>>0]|0;a[k+12>>0]=a[r>>0]|0;a[k+13>>0]=a[r>>0]|0;a[k+14>>0]=a[r>>0]|0;a[k+15>>0]=a[r>>0]|0;j=j+1|0;if((j|0)==16)break;else k=k+16|0}}else{if(!((n|0)!=0&(p|0)!=0&(l|0)!=0)){r=1;i=z;return r|0}j=d[g+16>>0]|0;m=d[h+15>>0]|0;o=d[g>>0]|0;p=(((d[g+9>>0]|0)-(d[g+7>>0]|0)+((d[g+10>>0]|0)-(d[g+6>>0]|0)<<1)+(((d[g+11>>0]|0)-(d[g+5>>0]|0)|0)*3|0)+((d[g+12>>0]|0)-(d[g+4>>0]|0)<<2)+(((d[g+13>>0]|0)-(d[g+3>>0]|0)|0)*5|0)+(((d[g+14>>0]|0)-(d[g+2>>0]|0)|0)*6|0)+(((d[g+15>>0]|0)-(d[g+1>>0]|0)|0)*7|0)+(j-o<<3)|0)*5|0)+32>>6;o=(((d[h+8>>0]|0)-(d[h+6>>0]|0)+(m-o<<3)+((d[h+9>>0]|0)-(d[h+5>>0]|0)<<1)+(((d[h+10>>0]|0)-(d[h+4>>0]|0)|0)*3|0)+((d[h+11>>0]|0)-(d[h+3>>0]|0)<<2)+(((d[h+12>>0]|0)-(d[h+2>>0]|0)|0)*5|0)+(((d[h+13>>0]|0)-(d[h+1>>0]|0)|0)*6|0)+(((d[h+14>>0]|0)-(d[h>>0]|0)|0)*7|0)|0)*5|0)+32>>6;j=(m+j<<4)+16|0;m=0;do{k=j+(Z(m+-7|0,o)|0)|0;n=m<<4;b=0;do{l=k+(Z(b+-7|0,p)|0)>>5;if((l|0)<0)l=0;else l=(l|0)>255?-1:l&255;a[e+(b+n)>>0]=l;b=b+1|0}while((b|0)!=16);m=m+1|0}while((m|0)!=16)}Rb(e,f,0);Rb(e,f+64|0,1);Rb(e,f+128|0,2);Rb(e,f+192|0,3);Rb(e,f+256|0,4);Rb(e,f+320|0,5);Rb(e,f+384|0,6);Rb(e,f+448|0,7);Rb(e,f+512|0,8);Rb(e,f+576|0,9);Rb(e,f+640|0,10);Rb(e,f+704|0,11);Rb(e,f+768|0,12);Rb(e,f+832|0,13);Rb(e,f+896|0,14);Rb(e,f+960|0,15);r=0;i=z;return r|0}function Pb(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var 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,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0;N=i;M=(j|0)!=0;L=0;a:while(1){l=vb(L)|0;n=c[l+4>>2]|0;l=ub(b,c[l>>2]|0)|0;j=zb(b,l)|0;if((j|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;j=E?0:j}o=wb(L)|0;m=c[o+4>>2]|0;o=ub(b,c[o>>2]|0)|0;k=zb(b,o)|0;if((k|0)!=0&M){E=(cb(c[o>>2]|0)|0)==2;k=E?0:k}G=(j|0)!=0;H=(k|0)!=0;I=G&H;if(I){if(!(cb(c[l>>2]|0)|0))n=d[l+(n&255)+82>>0]|0;else n=2;if(!(cb(c[o>>2]|0)|0))j=d[o+(m&255)+82>>0]|0;else j=2;j=n>>>0>>0?n:j}else j=2;if(!(c[f+(L<<2)+12>>2]|0)){E=c[f+(L<<2)+76>>2]|0;j=(E>>>0>=j>>>0&1)+E|0}a[b+L+82>>0]=j;l=c[(xb(L)|0)>>2]|0;l=ub(b,l)|0;m=zb(b,l)|0;if((m|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;m=E?0:m}l=c[(yb(L)|0)>>2]|0;l=ub(b,l)|0;n=zb(b,l)|0;if((n|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;n=E?0:n}J=c[3344+(L<<2)>>2]|0;K=c[3408+(L<<2)>>2]|0;r=(1285>>>L&1|0)!=0;if(r){o=h+K|0;l=h+(K+1)|0;p=h+(K+2)|0;q=h+(K+3)|0}else{q=(K<<4)+J|0;o=e+(q+-1)|0;l=e+(q+15)|0;p=e+(q+31)|0;q=e+(q+47)|0}A=a[o>>0]|0;y=a[l>>0]|0;F=a[p>>0]|0;E=a[q>>0]|0;do if(!(51>>>L&1)){x=K+-1|0;w=(x<<4)+J|0;o=a[e+w>>0]|0;q=a[e+(w+1)>>0]|0;s=a[e+(w+2)>>0]|0;u=a[e+(w+3)>>0]|0;t=a[e+(w+4)>>0]|0;l=a[e+(w+5)>>0]|0;v=a[e+(w+6)>>0]|0;p=a[e+(w+7)>>0]|0;if(r){D=v;C=u;u=p;B=q;z=s;v=h+x|0;break}else{D=v;C=u;u=p;B=q;z=s;v=e+(w+-1)|0;break}}else{D=a[g+(J+7)>>0]|0;C=a[g+(J+4)>>0]|0;t=a[g+(J+5)>>0]|0;l=a[g+(J+6)>>0]|0;o=a[g+(J+1)>>0]|0;u=a[g+(J+8)>>0]|0;B=a[g+(J+2)>>0]|0;z=a[g+(J+3)>>0]|0;v=g+J|0}while(0);v=a[v>>0]|0;switch(j|0){case 4:{if(!(I&(n|0)!=0)){k=1;j=51;break a}j=o&255;o=v&255;q=A&255;s=j+2|0;D=(s+q+(o<<1)|0)>>>2;u=D&255;k=B&255;o=o+2|0;v=((j<<1)+k+o|0)>>>2&255;j=z&255;s=((k<<1)+j+s|0)>>>2&255;z=y&255;o=(z+(q<<1)+o|0)>>>2;t=o&255;A=F&255;B=(q+2+(z<<1)+A|0)>>>2;q=u;p=t;n=B&255;m=v;l=s;j=((C&255)+2+k+(j<<1)|0)>>>2&255;k=u;r=v;o=(z+2+(A<<1)+(E&255)|0)>>>2&255|B<<8&65280|D<<24|o<<16&16711680;break}case 6:{if(!(I&(n|0)!=0)){k=1;j=51;break a}l=v&255;s=A&255;u=s+1|0;r=(u+l|0)>>>1&255;C=y&255;v=((s<<1)+2+C+l|0)>>>2&255;u=(u+C|0)>>>1&255;D=F&255;s=s+2|0;y=(s+(C<<1)+D|0)>>>2;A=(C+1+D|0)>>>1;E=E&255;j=o&255;s=(s+j+(l<<1)|0)>>>2&255;k=B&255;q=r;p=u;n=A&255;m=s;l=(k+2+(j<<1)+l|0)>>>2&255;j=((z&255)+2+(k<<1)+j|0)>>>2&255;k=v;t=y&255;o=y<<24|A<<16&16711680|(D+1+E|0)>>>1&255|C+2+(D<<1)+E<<6&65280;break}case 2:{do if(!I){if(G){j=((A&255)+2+(y&255)+(F&255)+(E&255)|0)>>>2;break}if(H)j=((C&255)+2+(z&255)+(B&255)+(o&255)|0)>>>2;else j=128}else j=((A&255)+4+(y&255)+(F&255)+(E&255)+(C&255)+(z&255)+(B&255)+(o&255)|0)>>>3;while(0);o=Z(j&255,16843009)|0;n=o&255;t=o>>>8&255;u=o>>>16&255;v=o>>>24&255;q=n;p=n;m=t;l=u;j=v;k=t;r=u;s=v;break}case 0:{if(!k){k=1;j=51;break a}q=o;p=o;n=o;m=B;l=z;j=C;k=B;r=z;s=C;t=B;u=z;v=C;o=(z&255)<<16|(C&255)<<24|(B&255)<<8|o&255;break}case 1:{if(!G){k=1;j=51;break a}j=Z(A&255,16843009)|0;s=Z(y&255,16843009)|0;v=Z(F&255,16843009)|0;q=j&255;p=s&255;n=v&255;m=j>>>8&255;l=j>>>16&255;j=j>>>24&255;k=s>>>8&255;r=s>>>16&255;s=s>>>24&255;t=v>>>8&255;u=v>>>16&255;v=v>>>24&255;o=Z(E&255,16843009)|0;break}case 7:{if(!k){k=1;j=51;break a}A=(m|0)==0;n=o&255;p=B&255;z=z&255;m=(z+1+p|0)>>>1&255;o=C&255;u=o+1|0;v=(u+z|0)>>>1&255;B=(A?C:t)&255;u=(u+B|0)>>>1&255;j=z+2|0;y=o+2|0;z=(y+p+(z<<1)|0)>>>2;o=(j+(o<<1)+B|0)>>>2;E=(A?C:l)&255;y=(y+E+(B<<1)|0)>>>2;q=(p+1+n|0)>>>1&255;p=(j+n+(p<<1)|0)>>>2&255;n=m;l=v;j=u;k=z&255;r=o&255;s=y&255;t=v;v=(B+1+E|0)>>>1&255;o=y<<16&16711680|z&255|(B+2+((A?C:D)&255)+(E<<1)|0)>>>2<<24|o<<8&65280;break}case 3:{if(!k){k=1;j=51;break a}n=(m|0)==0;q=B&255;m=z&255;p=m+2|0;k=C&255;B=k+2|0;m=(B+q+(m<<1)|0)>>>2&255;v=(n?C:t)&255;k=(p+(k<<1)+v|0)>>>2&255;E=(n?C:l)&255;B=(B+E+(v<<1)|0)>>>2;t=B&255;A=(n?C:D)&255;D=(v+2+A+(E<<1)|0)>>>2;v=D&255;C=(n?C:u)&255;E=(E+2+C+(A<<1)|0)>>>2;q=(p+(o&255)+(q<<1)|0)>>>2&255;p=m;n=k;l=k;j=t;r=t;s=v;u=v;v=E&255;o=(A+2+(C*3|0)|0)>>>2<<24|B&255|D<<8&65280|E<<16&16711680;break}case 5:{if(!(I&(n|0)!=0)){k=1;j=51;break a}n=v&255;u=o&255;t=(u+1+n|0)>>>1&255;x=B&255;E=(x+2+(u<<1)+n|0)>>>2;B=A&255;A=u+2|0;o=(A+B+(n<<1)|0)>>>2;u=(x+1+u|0)>>>1&255;s=z&255;A=((x<<1)+s+A|0)>>>2;v=(s+1+x|0)>>>1&255;C=C&255;D=y&255;q=t;p=o&255;n=(D+2+(B<<1)+n|0)>>>2&255;m=u;l=v;j=(C+1+s|0)>>>1&255;k=E&255;r=A&255;s=(C+2+x+(s<<1)|0)>>>2&255;o=A<<24|(B+2+(F&255)+(D<<1)|0)>>>2&255|E<<16&16711680|o<<8&65280;break}default:{if(!G){k=1;j=51;break a}s=A&255;j=y&255;m=F&255;l=(j+1+m|0)>>>1&255;o=E&255;k=(j+2+(m<<1)+o|0)>>>2&255;r=(m+1+o|0)>>>1&255;t=(m+2+(o*3|0)|0)>>>2&255;q=(s+1+j|0)>>>1&255;p=l;n=r;m=(s+2+(j<<1)+m|0)>>>2&255;j=k;s=t;u=E;v=E;o=o<<8|o|o<<16|o<<24}}E=(K<<4)+J|0;c[e+E>>2]=(l&255)<<16|(j&255)<<24|(m&255)<<8|q&255;c[e+(E+16)>>2]=(r&255)<<16|(s&255)<<24|(k&255)<<8|p&255;c[e+(E+32)>>2]=(u&255)<<16|(v&255)<<24|(t&255)<<8|n&255;c[e+(E+48)>>2]=o;Rb(e,f+(L<<6)+328|0,L);L=L+1|0;if(L>>>0>=16){k=0;j=51;break}}if((j|0)==51){i=N;return k|0}return 0}function Qb(b,e,f,g,h,j,k){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var 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;y=i;m=b+200|0;l=zb(b,c[m>>2]|0)|0;n=(k|0)!=0;if((l|0)!=0&n){o=(cb(c[c[m>>2]>>2]|0)|0)==2;l=o?0:l}m=b+204|0;k=zb(b,c[m>>2]|0)|0;if((k|0)!=0&n){o=(cb(c[c[m>>2]>>2]|0)|0)==2;o=o?0:k}else o=k;m=b+212|0;k=zb(b,c[m>>2]|0)|0;if((k|0)!=0&n){n=(cb(c[c[m>>2]>>2]|0)|0)==2;k=n?0:k}w=(l|0)!=0;x=(o|0)!=0;v=w&x;u=v&(k|0)!=0;t=(l|0)==0;s=(o|0)==0;p=g;q=16;r=0;while(1){if((j|0)==1){if(t){l=1;k=29;break}else{n=e;b=8;m=h}while(1){b=b+-1|0;a[n>>0]=a[m>>0]|0;a[n+1>>0]=a[m>>0]|0;a[n+2>>0]=a[m>>0]|0;a[n+3>>0]=a[m>>0]|0;a[n+4>>0]=a[m>>0]|0;a[n+5>>0]=a[m>>0]|0;a[n+6>>0]=a[m>>0]|0;a[n+7>>0]=a[m>>0]|0;if(!b)break;else{n=n+8|0;m=m+1|0}}}else if((j|0)==2){if(s){l=1;k=29;break}else{n=p;b=e;m=8}while(1){n=n+1|0;m=m+-1|0;a[b>>0]=a[n>>0]|0;a[b+8>>0]=a[n>>0]|0;a[b+16>>0]=a[n>>0]|0;a[b+24>>0]=a[n>>0]|0;a[b+32>>0]=a[n>>0]|0;a[b+40>>0]=a[n>>0]|0;a[b+48>>0]=a[n>>0]|0;a[b+56>>0]=a[n>>0]|0;if(!m)break;else b=b+1|0}}else if(!j){m=p+1|0;do if(!v){if(x){n=((d[m>>0]|0)+2+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)|0)>>>2;b=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2;break}if(w){b=((d[h>>0]|0)+2+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)|0)>>>2;n=b}else{n=128;b=128}}else{n=((d[m>>0]|0)+4+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)+(d[h>>0]|0)+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)|0)>>>3;b=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2}while(0);n=n&255;o=b&255;nd(e|0,n|0,4)|0;nd(e+4|0,o|0,4)|0;nd(e+8|0,n|0,4)|0;nd(e+12|0,o|0,4)|0;nd(e+16|0,n|0,4)|0;nd(e+20|0,o|0,4)|0;g=e+32|0;nd(e+24|0,n|0,4)|0;nd(e+28|0,o|0,4)|0;if(w){o=d[h+4>>0]|0;n=d[h+5>>0]|0;b=d[h+6>>0]|0;m=d[h+7>>0]|0;k=(o+2+n+b+m|0)>>>2;if(x){l=k;n=(o+4+n+b+m+(d[p+5>>0]|0)+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>3}else{l=k;n=k}}else if(x){l=((d[m>>0]|0)+2+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)|0)>>>2;n=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2}else{l=128;n=128}b=l&255;o=n&255;nd(g|0,b|0,4)|0;nd(e+36|0,o|0,4)|0;nd(e+40|0,b|0,4)|0;nd(e+44|0,o|0,4)|0;nd(e+48|0,b|0,4)|0;nd(e+52|0,o|0,4)|0;nd(e+56|0,b|0,4)|0;nd(e+60|0,o|0,4)|0}else{if(!u){l=1;k=29;break}n=d[p+8>>0]|0;b=d[h+7>>0]|0;l=d[p>>0]|0;k=(((d[p+5>>0]|0)-(d[p+3>>0]|0)+((d[p+6>>0]|0)-(d[p+2>>0]|0)<<1)+(((d[p+7>>0]|0)-(d[p+1>>0]|0)|0)*3|0)+(n-l<<2)|0)*17|0)+16>>5;l=(((d[h+4>>0]|0)-(d[h+2>>0]|0)+(b-l<<2)+((d[h+5>>0]|0)-(d[h+1>>0]|0)<<1)+(((d[h+6>>0]|0)-(d[h>>0]|0)|0)*3|0)|0)*17|0)+16>>5;o=Z(k,-3)|0;n=(b+n<<4)+16+(Z(l,-3)|0)|0;b=e;m=8;while(1){m=m+-1|0;g=n+o|0;a[b>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+1>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+2>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+3>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+4>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+5>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+6>>0]=a[(g>>5)+3984>>0]|0;a[b+7>>0]=a[(g+k>>5)+3984>>0]|0;if(!m)break;else{n=n+l|0;b=b+8|0}}}Rb(e,f,q);g=q|1;Rb(e,f+64|0,g);Rb(e,f+128|0,g+1|0);Rb(e,f+192|0,q|3);r=r+1|0;if(r>>>0>=2){l=0;k=29;break}else{p=p+9|0;q=q+4|0;e=e+64|0;h=h+8|0;f=f+256|0}}if((k|0)==29){i=y;return l|0}return 0}function Rb(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;h=i;g=c[e>>2]|0;if((g|0)==16777215){i=h;return}m=f>>>0<16;l=m?16:8;m=m?f:f&3;m=(Z(c[3408+(m<<2)>>2]|0,l)|0)+(c[3344+(m<<2)>>2]|0)|0;n=b+m|0;p=c[e+4>>2]|0;j=b+(m+1)|0;f=d[j>>0]|0;a[n>>0]=a[3472+(g+512+(d[n>>0]|0))>>0]|0;n=c[e+8>>2]|0;k=b+(m+2)|0;o=d[k>>0]|0;a[j>>0]=a[3472+(p+512+f)>>0]|0;g=b+(m+3)|0;j=a[3472+((c[e+12>>2]|0)+512+(d[g>>0]|0))>>0]|0;a[k>>0]=a[3472+(n+512+o)>>0]|0;a[g>>0]=j;g=m+l|0;m=b+g|0;j=c[e+20>>2]|0;k=b+(g+1)|0;o=d[k>>0]|0;a[m>>0]=a[3472+((c[e+16>>2]|0)+512+(d[m>>0]|0))>>0]|0;m=c[e+24>>2]|0;n=b+(g+2)|0;f=d[n>>0]|0;a[k>>0]=a[3472+(j+512+o)>>0]|0;k=b+(g+3)|0;o=a[3472+((c[e+28>>2]|0)+512+(d[k>>0]|0))>>0]|0;a[n>>0]=a[3472+(m+512+f)>>0]|0;a[k>>0]=o;g=g+l|0;k=b+g|0;o=c[e+36>>2]|0;n=b+(g+1)|0;f=d[n>>0]|0;a[k>>0]=a[3472+((c[e+32>>2]|0)+512+(d[k>>0]|0))>>0]|0;k=c[e+40>>2]|0;m=b+(g+2)|0;j=d[m>>0]|0;a[n>>0]=a[3472+(o+512+f)>>0]|0;n=b+(g+3)|0;f=a[3472+((c[e+44>>2]|0)+512+(d[n>>0]|0))>>0]|0;a[m>>0]=a[3472+(k+512+j)>>0]|0;a[n>>0]=f;g=g+l|0;l=b+g|0;n=c[e+52>>2]|0;f=b+(g+1)|0;m=d[f>>0]|0;a[l>>0]=a[3472+((c[e+48>>2]|0)+512+(d[l>>0]|0))>>0]|0;l=c[e+56>>2]|0;j=b+(g+2)|0;k=d[j>>0]|0;a[f>>0]=a[3472+(n+512+m)>>0]|0;g=b+(g+3)|0;f=a[3472+((c[e+60>>2]|0)+512+(d[g>>0]|0))>>0]|0;a[j>>0]=a[3472+(l+512+k)>>0]|0;a[g>>0]=f;i=h;return} +function yc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;q=i;l=b+-1|0;k=a[b+1>>0]|0;m=d[l>>0]|0;n=d[b>>0]|0;r=m-n|0;p=f+4|0;do if((((r|0)>-1?r:0-r|0)>>>0<(c[p>>2]|0)>>>0?(o=d[b+-2>>0]|0,r=o-m|0,j=c[f+8>>2]|0,((r|0)>-1?r:0-r|0)>>>0>>0):0)?(h=k&255,k=h-n|0,((k|0)>-1?k:0-k|0)>>>0>>0):0)if(e>>>0<4){k=d[(c[f>>2]|0)+(e+-1)>>0]|0;k=Oa(~k,k+1|0,4-h+(n-m<<2)+o>>3)|0;o=a[3472+((n|512)-k)>>0]|0;a[l>>0]=a[3472+((m|512)+k)>>0]|0;a[b>>0]=o;break}else{a[l>>0]=(m+2+h+(o<<1)|0)>>>2;a[b>>0]=(n+2+(h<<1)+o|0)>>>2;break}while(0);l=b+g|0;m=b+(g+-1)|0;o=d[m>>0]|0;n=d[l>>0]|0;k=o-n|0;if(((k|0)>-1?k:0-k|0)>>>0>=(c[p>>2]|0)>>>0){i=q;return}k=d[b+(g+-2)>>0]|0;p=k-o|0;j=c[f+8>>2]|0;if(((p|0)>-1?p:0-p|0)>>>0>=j>>>0){i=q;return}h=d[b+(g+1)>>0]|0;g=h-n|0;if(((g|0)>-1?g:0-g|0)>>>0>=j>>>0){i=q;return}if(e>>>0<4){b=d[(c[f>>2]|0)+(e+-1)>>0]|0;b=Oa(~b,b+1|0,4-h+(n-o<<2)+k>>3)|0;g=a[3472+((n|512)-b)>>0]|0;a[m>>0]=a[3472+((o|512)+b)>>0]|0;a[l>>0]=g;i=q;return}else{a[m>>0]=(o+2+h+(k<<1)|0)>>>2;a[l>>0]=(n+2+(h<<1)+k|0)>>>2;i=q;return}}function zc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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;v=i;if(e>>>0<4){n=d[(c[f>>2]|0)+(e+-1)>>0]|0;h=n+1|0;q=0-g|0;e=f+4|0;p=q<<1;o=f+8|0;n=~n;j=8;while(1){m=b+q|0;f=a[b+g>>0]|0;l=d[m>>0]|0;k=d[b>>0]|0;r=l-k|0;if((((r|0)>-1?r:0-r|0)>>>0<(c[e>>2]|0)>>>0?(t=d[b+p>>0]|0,r=t-l|0,s=c[o>>2]|0,((r|0)>-1?r:0-r|0)>>>0>>0):0)?(u=f&255,f=u-k|0,((f|0)>-1?f:0-f|0)>>>0>>0):0){r=Oa(n,h,4-u+(k-l<<2)+t>>3)|0;f=a[3472+((k|512)-r)>>0]|0;a[m>>0]=a[3472+((l|512)+r)>>0]|0;a[b>>0]=f}j=j+-1|0;if(!j)break;else b=b+1|0}i=v;return}else{o=0-g|0;m=f+4|0;n=o<<1;f=f+8|0;l=8;while(1){h=b+o|0;e=a[b+g>>0]|0;j=d[h>>0]|0;k=d[b>>0]|0;s=j-k|0;if((((s|0)>-1?s:0-s|0)>>>0<(c[m>>2]|0)>>>0?(p=d[b+n>>0]|0,s=p-j|0,q=c[f>>2]|0,((s|0)>-1?s:0-s|0)>>>0>>0):0)?(r=e&255,e=r-k|0,((e|0)>-1?e:0-e|0)>>>0>>0):0){a[h>>0]=(j+2+r+(p<<1)|0)>>>2;a[b>>0]=(k+2+(r<<1)+p|0)>>>2}l=l+-1|0;if(!l)break;else b=b+1|0}i=v;return}}function Ac(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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=i;r=d[(c[f>>2]|0)+(e+-1)>>0]|0;s=r+1|0;l=0-g|0;h=f+4|0;q=l<<1;e=f+8|0;r=~r;l=b+l|0;m=a[b+g>>0]|0;k=d[l>>0]|0;j=d[b>>0]|0;u=k-j|0;f=c[h>>2]|0;if((((u|0)>-1?u:0-u|0)>>>0>>0?(o=d[b+q>>0]|0,u=o-k|0,n=c[e>>2]|0,((u|0)>-1?u:0-u|0)>>>0>>0):0)?(p=m&255,m=p-j|0,((m|0)>-1?m:0-m|0)>>>0>>0):0){p=Oa(r,s,4-p+(j-k<<2)+o>>3)|0;f=a[3472+((j|512)-p)>>0]|0;a[l>>0]=a[3472+((k|512)+p)>>0]|0;a[b>>0]=f;f=c[h>>2]|0}m=b+1|0;j=b+(1-g)|0;k=d[j>>0]|0;l=d[m>>0]|0;p=k-l|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}h=d[b+(q|1)>>0]|0;p=h-k|0;f=c[e>>2]|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}e=d[b+(g+1)>>0]|0;p=e-l|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}o=Oa(r,s,4-e+(l-k<<2)+h>>3)|0;p=a[3472+((l|512)-o)>>0]|0;a[j>>0]=a[3472+((k|512)+o)>>0]|0;a[m>>0]=p;i=t;return}function Bc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;p=c[b+4>>2]|0;q=c[b+8>>2]|0;if(!((d|0)==0|(d|0)==5)?(c[a+3384>>2]|0)==0:0)f=0;else{g=a+1220|0;e=0;do{f=ic(g,e)|0;e=e+1|0}while(e>>>0<16&(f|0)==0)}l=a+1176|0;n=c[l>>2]|0;if(n){m=c[a+1212>>2]|0;e=0;j=0;g=0;do{if(c[m+(j*216|0)+196>>2]|0)break;j=j+1|0;e=e+1|0;o=(e|0)==(p|0);g=(o&1)+g|0;e=o?0:e}while(j>>>0>>0);if((j|0)!=(n|0)){o=a+1212|0;n=c[o>>2]|0;j=Z(g,p)|0;if(e){l=a+1204|0;h=e;do{h=h+-1|0;m=h+j|0;Cc(n+(m*216|0)|0,b,g,h,d,f);c[n+(m*216|0)+196>>2]=1;c[l>>2]=(c[l>>2]|0)+1}while((h|0)!=0)}e=e+1|0;if(e>>>0

>>0){m=a+1204|0;do{l=e+j|0;k=n+(l*216|0)+196|0;if(!(c[k>>2]|0)){Cc(n+(l*216|0)|0,b,g,e,d,f);c[k>>2]=1;c[m>>2]=(c[m>>2]|0)+1}e=e+1|0}while((e|0)!=(p|0))}if(g){if(p){n=g+-1|0;h=Z(n,p)|0;e=a+1204|0;l=0-p|0;k=0;do{m=n;j=(c[o>>2]|0)+((k+h|0)*216|0)|0;while(1){Cc(j,b,m,k,d,f);c[j+196>>2]=1;c[e>>2]=(c[e>>2]|0)+1;if(!m)break;else{m=m+-1|0;j=j+(l*216|0)|0}}k=k+1|0}while((k|0)!=(p|0))}}else g=0;g=g+1|0;if(g>>>0>=q>>>0){i=r;return 0}m=a+1204|0;if(!p){i=r;return 0}do{e=c[o>>2]|0;l=Z(g,p)|0;k=0;do{h=k+l|0;j=e+(h*216|0)+196|0;if(!(c[j>>2]|0)){Cc(e+(h*216|0)|0,b,g,k,d,f);c[j>>2]=1;c[m>>2]=(c[m>>2]|0)+1}k=k+1|0}while((k|0)!=(p|0));g=g+1|0}while((g|0)!=(q|0));i=r;return 0}}if((d|0)==2|(d|0)==7)if((c[a+3384>>2]|0)==0|(f|0)==0)g=13;else g=14;else if(!f)g=13;else g=14;if((g|0)==13)id(c[b>>2]|0,128,Z(p*384|0,q)|0);else if((g|0)==14)hd(c[b>>2]|0,f,Z(p*384|0,q)|0);g=c[l>>2]|0;c[a+1204>>2]=g;if(!g){i=r;return 0}e=c[a+1212>>2]|0;f=0;do{c[e+(f*216|0)+8>>2]=1;f=f+1|0}while(f>>>0>>0);i=r;return 0}function Cc(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var 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,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,_=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;sa=i;i=i+480|0;qa=sa+96|0;ra=sa+32|0;m=sa+24|0;n=sa;na=c[e+4>>2]|0;u=c[e+8>>2]|0;Na(e,(Z(na,f)|0)+g|0);p=c[e>>2]|0;k=f<<4;l=g<<4;o=(Z(f<<8,na)|0)+l|0;c[b+20>>2]=40;c[b+8>>2]=0;c[b>>2]=6;c[b+12>>2]=0;c[b+16>>2]=0;c[b+24>>2]=0;do if((h|0)==2|(h|0)==7)id(qa,0,384);else{c[m>>2]=0;c[n+4>>2]=na;c[n+8>>2]=u;c[n>>2]=j;if(!j){id(qa,0,384);break}dc(qa,m,n,l,k,0,0,16,16);sc(e,qa);i=sa;return}while(0);id(ra,0,64);if((f|0)!=0?(c[b+((0-na|0)*216|0)+196>>2]|0)!=0:0){v=o-(na<<4)|0;E=v|1;D=v|3;E=(d[p+E>>0]|0)+(d[p+v>>0]|0)+(d[p+(E+1)>>0]|0)+(d[p+D>>0]|0)|0;$=v|7;D=(d[p+(D+2)>>0]|0)+(d[p+(D+1)>>0]|0)+(d[p+(D+3)>>0]|0)+(d[p+$>>0]|0)|0;F=(d[p+($+2)>>0]|0)+(d[p+($+1)>>0]|0)+(d[p+($+3)>>0]|0)+(d[p+($+4)>>0]|0)|0;v=(d[p+($+6)>>0]|0)+(d[p+($+5)>>0]|0)+(d[p+($+7)>>0]|0)+(d[p+(v|15)>>0]|0)|0;$=D+E|0;c[ra>>2]=F+$+(c[ra>>2]|0)+v;s=ra+4|0;c[s>>2]=$-F-v+(c[s>>2]|0);s=1}else{E=0;D=0;F=0;v=0;s=0}if((u+-1|0)!=(f|0)?(c[b+(na*216|0)+196>>2]|0)!=0:0){z=o+(na<<8)|0;w=z|1;x=z|3;w=(d[p+w>>0]|0)+(d[p+z>>0]|0)+(d[p+(w+1)>>0]|0)+(d[p+x>>0]|0)|0;r=z|7;x=(d[p+(x+2)>>0]|0)+(d[p+(x+1)>>0]|0)+(d[p+(x+3)>>0]|0)+(d[p+r>>0]|0)|0;y=(d[p+(r+2)>>0]|0)+(d[p+(r+1)>>0]|0)+(d[p+(r+3)>>0]|0)+(d[p+(r+4)>>0]|0)|0;z=(d[p+(r+6)>>0]|0)+(d[p+(r+5)>>0]|0)+(d[p+(r+7)>>0]|0)+(d[p+(z|15)>>0]|0)|0;r=x+w|0;c[ra>>2]=y+r+(c[ra>>2]|0)+z;t=ra+4|0;c[t>>2]=r-y-z+(c[t>>2]|0);t=1;r=s+1|0}else{t=0;w=0;x=0;y=0;z=0;r=s}if((g|0)!=0?(c[b+-20>>2]|0)!=0:0){_=o+-1|0;$=na<<4;j=na<<5;ma=na*48|0;C=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;h=na<<6;_=_+h|0;B=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;_=_+h|0;A=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;h=_+h|0;ma=(d[p+(h+$)>>0]|0)+(d[p+h>>0]|0)+(d[p+(h+j)>>0]|0)+(d[p+(h+ma)>>0]|0)|0;h=B+C|0;c[ra>>2]=A+h+(c[ra>>2]|0)+ma;j=ra+16|0;c[j>>2]=h-A-ma+(c[j>>2]|0);j=r+1|0;h=1}else{j=r;C=0;B=0;A=0;ma=0;h=0}do if((na+-1|0)!=(g|0)?(c[b+412>>2]|0)!=0:0){$=o+16|0;n=na<<4;m=na<<5;o=na*48|0;b=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;q=na<<6;$=$+q|0;l=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;$=$+q|0;k=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;q=$+q|0;o=(d[p+(q+n)>>0]|0)+(d[p+q>>0]|0)+(d[p+(q+m)>>0]|0)+(d[p+(q+o)>>0]|0)|0;p=j+1|0;q=h+1|0;j=l+b|0;c[ra>>2]=k+j+(c[ra>>2]|0)+o;m=ra+16|0;j=j-k-o+(c[m>>2]|0)|0;c[m>>2]=j;m=(r|0)==0;n=(h|0)!=0;if(!(m&n)){if(!m){m=1;j=p;h=q;l=21;break}}else c[ra+4>>2]=A+ma+B+C-b-l-k-o>>5;m=1;o=(s|0)!=0;b=(t|0)!=0;h=q;l=27}else l=17;while(0);if((l|0)==17){n=(h|0)!=0;if(!r){m=0;p=j;l=23}else{m=0;l=21}}if((l|0)==21){p=ra+4|0;c[p>>2]=c[p>>2]>>r+3;p=j;l=23}do if((l|0)==23){j=(h|0)==0;o=(s|0)!=0;b=(t|0)!=0;if(j&o&b){c[ra+16>>2]=F+v+D+E-z-y-x-w>>5;pa=m;h=p;oa=n;o=1;b=1;break}if(j){pa=m;h=p;oa=n}else{j=c[ra+16>>2]|0;l=27}}while(0);if((l|0)==27){c[ra+16>>2]=j>>h+3;pa=m;h=p;oa=n}if((h|0)==1)c[ra>>2]=c[ra>>2]>>4;else if((h|0)==2)c[ra>>2]=c[ra>>2]>>5;else if((h|0)==3)c[ra>>2]=(c[ra>>2]|0)*21>>10;else c[ra>>2]=c[ra>>2]>>6;Dc(ra);n=0;j=qa;m=ra;while(1){h=c[m+((n>>>2&3)<<2)>>2]|0;if((h|0)<0)h=0;else h=(h|0)>255?-1:h&255;a[j>>0]=h;h=n+1|0;if((h|0)==256)break;else{n=h;j=j+1|0;m=(h&63|0)==0?m+16|0:m}}ta=Z(u,na)|0;V=na<<3;Y=0-V|0;G=Y|1;_=G+1|0;$=Y|3;aa=$+1|0;ba=$+2|0;ca=$+3|0;da=Y|7;W=ra+4|0;ka=na<<6;H=ka|1;ea=H+1|0;fa=ka|3;ga=fa+1|0;ha=fa+2|0;ia=fa+3|0;ja=ka|7;I=V+-1|0;U=na<<4;J=U+-1|0;K=J+V|0;L=J+U|0;M=L+V|0;N=L+U|0;O=N+V|0;X=ra+16|0;P=V+8|0;Q=U|8;R=Q+V|0;S=Q+U|0;T=S+V|0;U=S+U|0;V=U+V|0;la=ta<<6;q=E;p=D;h=F;t=v;n=w;j=x;l=y;u=z;F=0;m=C;k=B;r=A;s=ma;E=(c[e>>2]|0)+((Z(f<<6,na)|0)+(g<<3)+(ta<<8))|0;while(1){id(ra,0,64);if(o){q=(d[E+G>>0]|0)+(d[E+Y>>0]|0)|0;p=(d[E+$>>0]|0)+(d[E+_>>0]|0)|0;z=(d[E+ba>>0]|0)+(d[E+aa>>0]|0)|0;A=(d[E+da>>0]|0)+(d[E+ca>>0]|0)|0;t=p+q|0;c[ra>>2]=z+t+(c[ra>>2]|0)+A;c[W>>2]=t-z-A+(c[W>>2]|0);t=1}else{z=h;A=t;t=0}if(b){B=(d[E+H>>0]|0)+(d[E+ka>>0]|0)|0;C=(d[E+fa>>0]|0)+(d[E+ea>>0]|0)|0;D=(d[E+ha>>0]|0)+(d[E+ga>>0]|0)|0;u=(d[E+ja>>0]|0)+(d[E+ia>>0]|0)|0;h=C+B|0;c[ra>>2]=D+h+(c[ra>>2]|0)+u;c[W>>2]=h-D-u+(c[W>>2]|0);h=t+1|0}else{B=n;C=j;D=l;h=t}if(oa){v=(d[E+I>>0]|0)+(d[E+-1>>0]|0)|0;w=(d[E+K>>0]|0)+(d[E+J>>0]|0)|0;x=(d[E+M>>0]|0)+(d[E+L>>0]|0)|0;y=(d[E+O>>0]|0)+(d[E+N>>0]|0)|0;t=w+v|0;c[ra>>2]=x+t+(c[ra>>2]|0)+y;c[X>>2]=t-x-y+(c[X>>2]|0);t=h+1|0;s=1}else{t=h;v=m;w=k;x=r;y=s;s=0}do if(pa){l=(d[E+P>>0]|0)+(d[E+8>>0]|0)|0;m=(d[E+R>>0]|0)+(d[E+Q>>0]|0)|0;j=(d[E+T>>0]|0)+(d[E+S>>0]|0)|0;n=(d[E+V>>0]|0)+(d[E+U>>0]|0)|0;t=t+1|0;s=s+1|0;k=m+l|0;c[ra>>2]=j+k+(c[ra>>2]|0)+n;k=k-j-n+(c[X>>2]|0)|0;c[X>>2]=k;r=(h|0)==0;if(!(r&oa))if(r){l=54;break}else{l=49;break}else{c[W>>2]=x+y+w+v-l-m-j-n>>4;l=54;break}}else if(!h){r=s;l=50}else l=49;while(0);if((l|0)==49){c[W>>2]=c[W>>2]>>h+2;r=s;l=50}do if((l|0)==50){l=0;s=(r|0)==0;if(s&o&b){c[X>>2]=z+A+p+q-u-D-C-B>>4;break}if(!s){k=c[X>>2]|0;s=r;l=54}}while(0);if((l|0)==54)c[X>>2]=k>>s+2;if((t|0)==1)c[ra>>2]=c[ra>>2]>>3;else if((t|0)==2)c[ra>>2]=c[ra>>2]>>4;else if((t|0)==3)c[ra>>2]=(c[ra>>2]|0)*21>>9;else c[ra>>2]=c[ra>>2]>>5;Dc(ra);s=0;r=qa+((F<<6)+256)|0;k=ra;while(1){t=c[k+((s>>>1&3)<<2)>>2]|0;if((t|0)<0)t=0;else t=(t|0)>255?-1:t&255;a[r>>0]=t;t=s+1|0;if((t|0)==64)break;else{s=t;r=r+1|0;k=(t&15|0)==0?k+16|0:k}}F=F+1|0;if((F|0)==2)break;else{h=z;t=A;n=B;j=C;l=D;m=v;k=w;r=x;s=y;E=E+la|0}}sc(e,qa);i=sa;return}function Dc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;h=i;f=a+4|0;b=c[f>>2]|0;g=a+16|0;d=c[g>>2]|0;e=c[a>>2]|0;if(!(b|d)){c[a+60>>2]=e;c[a+56>>2]=e;c[a+52>>2]=e;c[a+48>>2]=e;c[a+44>>2]=e;c[a+40>>2]=e;c[a+36>>2]=e;c[a+32>>2]=e;c[a+28>>2]=e;c[a+24>>2]=e;c[a+20>>2]=e;c[g>>2]=e;c[a+12>>2]=e;c[a+8>>2]=e;c[f>>2]=e;i=h;return}else{k=b+e|0;g=b>>1;j=g+e|0;g=e-g|0;b=e-b|0;c[a>>2]=d+k;e=d>>1;c[a+16>>2]=e+k;c[a+32>>2]=k-e;c[a+48>>2]=k-d;c[f>>2]=d+j;c[a+20>>2]=e+j;c[a+36>>2]=j-e;c[a+52>>2]=j-d;c[a+8>>2]=d+g;c[a+24>>2]=e+g;c[a+40>>2]=g-e;c[a+56>>2]=g-d;c[a+12>>2]=d+b;c[a+28>>2]=e+b;c[a+44>>2]=b-e;c[a+60>>2]=b-d;i=h;return}}function Ec(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;id(b,0,952);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b>>2]=d&1;do if(d){d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+4>>2]=d;if((d|0)==255){d=jb(a,16)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+8>>2]=d;d=jb(a,16)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+12>>2]=d;break}}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+16>>2]=d&1;do if(d){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+20>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+24>>2]=d&1;do if(d){d=jb(a,3)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+28>>2]=d;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+32>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+36>>2]=d&1;if(!d){c[b+40>>2]=2;c[b+44>>2]=2;c[b+48>>2]=2;break}d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+40>>2]=d;d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+44>>2]=d;d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+48>>2]=d;break}}else{c[b+28>>2]=5;c[b+40>>2]=2;c[b+44>>2]=2;c[b+48>>2]=2}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+52>>2]=d&1;if(d){d=b+56|0;e=nb(a,d)|0;if(e){d=e;i=h;return d|0}if((c[d>>2]|0)>>>0>5){d=1;i=h;return d|0}d=b+60|0;e=nb(a,d)|0;if(e){d=e;i=h;return d|0}if((c[d>>2]|0)>>>0>5){d=1;i=h;return d|0}}d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+64>>2]=d&1;do if(d){d=kb(a)|0;if((lb(a,32)|0)==-1|(d|0)==0){d=1;i=h;return d|0}c[b+68>>2]=d;d=kb(a)|0;if((lb(a,32)|0)==-1|(d|0)==0){d=1;i=h;return d|0}c[b+72>>2]=d;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+76>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;f=b+80|0;c[f>>2]=d&1;if(d){e=Fc(a,b+84|0)|0;if(e){d=e;i=h;return d|0}}else{c[b+84>>2]=1;c[b+96>>2]=288000001;c[b+224>>2]=288000001;c[b+480>>2]=24;c[b+484>>2]=24;c[b+488>>2]=24;c[b+492>>2]=24}e=jb(a,1)|0;if((e|0)==-1){d=1;i=h;return d|0}e=(e|0)==1;d=b+496|0;c[d>>2]=e&1;if(e){e=Fc(a,b+500|0)|0;if(e){d=e;i=h;return d|0}}else{c[b+500>>2]=1;c[b+512>>2]=240000001;c[b+640>>2]=240000001;c[b+896>>2]=24;c[b+900>>2]=24;c[b+904>>2]=24;c[b+908>>2]=24}if(!((c[f>>2]|0)==0?(c[d>>2]|0)==0:0))g=46;do if((g|0)==46){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+912>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+916>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+920>>2]=d&1;do if(d){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+924>>2]=(d|0)==1&1;e=b+928|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+932|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+936|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+940|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}d=nb(a,b+944|0)|0;if(d){i=h;return d|0}d=nb(a,b+948|0)|0;if(!d)break;i=h;return d|0}else{c[b+924>>2]=1;c[b+928>>2]=2;c[b+932>>2]=1;c[b+936>>2]=16;c[b+940>>2]=16;c[b+944>>2]=16;c[b+948>>2]=16}while(0);d=0;i=h;return d|0}function Fc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;d=nb(a,b)|0;if(d){i=k;return d|0}d=(c[b>>2]|0)+1|0;c[b>>2]=d;if(d>>>0>32){d=1;i=k;return d|0}d=jb(a,4)|0;if((d|0)==-1){d=1;i=k;return d|0}j=b+4|0;c[j>>2]=d;e=jb(a,4)|0;if((e|0)==-1){d=1;i=k;return d|0}h=b+8|0;c[h>>2]=e;a:do if(c[b>>2]|0){g=0;while(1){f=b+(g<<2)+12|0;d=nb(a,f)|0;if(d){e=17;break}e=c[f>>2]|0;if((e|0)==-1){d=1;e=17;break}d=e+1|0;c[f>>2]=d;c[f>>2]=d<<(c[j>>2]|0)+6;f=b+(g<<2)+140|0;d=nb(a,f)|0;if(d){e=17;break}e=c[f>>2]|0;if((e|0)==-1){d=1;e=17;break}e=e+1|0;c[f>>2]=e;c[f>>2]=e<<(c[h>>2]|0)+4;e=jb(a,1)|0;if((e|0)==-1){d=1;e=17;break}c[b+(g<<2)+268>>2]=(e|0)==1&1;g=g+1|0;if(g>>>0>=(c[b>>2]|0)>>>0)break a}if((e|0)==17){i=k;return d|0}}while(0);d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+396>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+400>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+404>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+408>>2]=d;d=0;i=k;return d|0}function Gc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;a:do if(!(c[d+284>>2]|0))o=0;else{h=0;while(1){j=c[d+(h*20|0)+288>>2]|0;if((j|0)==5){o=1;break a}else if(!j)break;h=h+1|0}o=0}while(0);j=c[b+16>>2]|0;if((j|0)==1){if((c[e>>2]|0)!=5){f=c[a+12>>2]|0;if((c[a+8>>2]|0)>>>0>(c[d+12>>2]|0)>>>0)f=(c[b+12>>2]|0)+f|0}else f=0;m=c[b+36>>2]|0;h=(m|0)==0;if(h)j=0;else j=(c[d+12>>2]|0)+f|0;e=(c[e+4>>2]|0)==0;k=((e&(j|0)!=0)<<31>>31)+j|0;l=(k|0)!=0;if(l){g=k+-1|0;n=(g>>>0)%(m>>>0)|0;g=(g>>>0)/(m>>>0)|0}else{n=0;g=0}if(h)j=0;else{k=c[b+40>>2]|0;j=0;h=0;do{j=(c[k+(h<<2)>>2]|0)+j|0;h=h+1|0}while(h>>>0>>0)}if(l){g=Z(j,g)|0;k=c[b+40>>2]|0;j=0;do{g=(c[k+(j<<2)>>2]|0)+g|0;j=j+1|0}while(j>>>0<=n>>>0)}else g=0;if(e)j=(c[b+28>>2]|0)+g|0;else j=g;g=(c[d+32>>2]|0)+(c[b+32>>2]|0)|0;h=a+12|0;if(!o){b=((g|0)<0?g:0)+j+(c[d+28>>2]|0)|0;c[h>>2]=f;c[a+8>>2]=c[d+12>>2];i=p;return b|0}else{c[h>>2]=0;c[a+8>>2]=0;b=0;i=p;return b|0}}else if(!j){if((c[e>>2]|0)!=5){h=c[a>>2]|0;j=c[d+20>>2]|0;if(h>>>0>j>>>0?(k=c[b+20>>2]|0,(h-j|0)>>>0>=k>>>1>>>0):0){h=(c[a+4>>2]|0)+k|0;k=a}else{k=a;m=11}}else{c[a+4>>2]=0;c[a>>2]=0;j=c[d+20>>2]|0;h=0;k=a;m=11}do if((m|0)==11){if(j>>>0>h>>>0?(g=c[b+20>>2]|0,(j-h|0)>>>0>g>>>1>>>0):0){h=(c[a+4>>2]|0)-g|0;break}h=c[a+4>>2]|0}while(0);if(!(c[e+4>>2]|0)){b=c[d+24>>2]|0;b=j+h+((b|0)<0?b:0)|0;i=p;return b|0}c[a+4>>2]=h;f=c[d+24>>2]|0;g=(f|0)<0;if(!o){c[k>>2]=j;b=j+h+(g?f:0)|0;i=p;return b|0}else{c[a+4>>2]=0;c[k>>2]=g?0-f|0:0;b=0;i=p;return b|0}}else{if((c[e>>2]|0)==5){k=0;g=0;f=a+12|0}else{j=c[d+12>>2]|0;f=a+12|0;h=c[f>>2]|0;if((c[a+8>>2]|0)>>>0>j>>>0)h=(c[b+12>>2]|0)+h|0;k=h;g=(j+h<<1)+(((c[e+4>>2]|0)==0)<<31>>31)|0}if(!o){c[f>>2]=k;c[a+8>>2]=c[d+12>>2];b=g;i=p;return b|0}else{c[f>>2]=0;c[a+8>>2]=0;b=0;i=p;return b|0}}return 0}function Hc(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;Ab(a);e=fd(2112)|0;c[a+3376>>2]=e;if(e)if(!b)b=0;else{c[a+1216>>2]=1;b=0}else b=1;i=d;return b|0}function Ic(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,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;i=i+208|0;l=r+204|0;p=r;g=r+112|0;h=r+40|0;q=r+16|0;j=r+12|0;n=r+8|0;c[j>>2]=0;o=a+3344|0;if((c[o>>2]|0)!=0?(c[a+3348>>2]|0)==(b|0):0){b=a+3356|0;c[q+0>>2]=c[b+0>>2];c[q+4>>2]=c[b+4>>2];c[q+8>>2]=c[b+8>>2];c[q+12>>2]=c[b+12>>2];c[q+4>>2]=c[q>>2];c[q+8>>2]=0;c[q+16>>2]=0;c[f>>2]=c[a+3352>>2]}else k=4;do if((k|0)==4)if(!(Pa(b,d,q,f)|0)){d=a+3356|0;c[d+0>>2]=c[q+0>>2];c[d+4>>2]=c[q+4>>2];c[d+8>>2]=c[q+8>>2];c[d+12>>2]=c[q+12>>2];c[d+16>>2]=c[q+16>>2];c[a+3352>>2]=c[f>>2];c[a+3348>>2]=b;break}else{n=3;i=r;return n|0}while(0);c[o>>2]=0;if(sb(q,p)|0){n=3;i=r;return n|0}if(((c[p>>2]|0)+-1|0)>>>0>11){n=0;i=r;return n|0}b=Ib(q,p,a,j)|0;if(!b){do if(!(c[j>>2]|0))k=19;else{if((c[a+1184>>2]|0)!=0?(c[a+16>>2]|0)!=0:0){if(c[a+3380>>2]|0){n=3;i=r;return n|0}if(!(c[a+1188>>2]|0)){m=a+1220|0;n=a+1336|0;c[n>>2]=jc(m)|0;nc(m);Bc(a,n,0)|0}else Bc(a,a+1336|0,c[a+1372>>2]|0)|0;c[f>>2]=0;c[o>>2]=1;c[a+1180>>2]=0;g=a+1336|0;b=a+1360|0;break}c[a+1188>>2]=0;c[a+1180>>2]=0;k=19}while(0);do if((k|0)==19){b=c[p>>2]|0;if((b|0)==7)if(!(Qa(q,g)|0)){Bb(a,g)|0;n=0;i=r;return n|0}else{n=g+40|0;gd(c[n>>2]|0);c[n>>2]=0;n=g+84|0;gd(c[n>>2]|0);c[n>>2]=0;n=3;i=r;return n|0}else if((b|0)==1|(b|0)==5){k=a+1180|0;if(c[a+1180>>2]|0){n=0;i=r;return n|0}c[a+1184>>2]=1;if(Fb(a)|0){c[a+1204>>2]=0;c[a+1208>>2]=e;Ua(q,l)|0;j=a+8|0;d=c[j>>2]|0;b=Db(a,c[l>>2]|0,(c[p>>2]|0)==5&1)|0;if(b){c[a+4>>2]=256;c[a+12>>2]=0;c[j>>2]=32;c[a+16>>2]=0;c[a+3380>>2]=0;n=(b|0)==65535?5:4;i=r;return n|0}if((d|0)!=(c[j>>2]|0)){d=c[a+16>>2]|0;c[n>>2]=1;b=c[a>>2]|0;if(b>>>0<32)b=c[a+(b<<2)+20>>2]|0;else b=0;c[f>>2]=0;c[o>>2]=1;if((((((c[p>>2]|0)==5?(l=_a(n,q,d,c[a+12>>2]|0,5)|0,(c[n>>2]|l|0)==0):0)?(m=a+1220|0,!((c[a+1276>>2]|0)!=0|(b|0)==0)):0)?(c[b+52>>2]|0)==(c[d+52>>2]|0):0)?(c[b+56>>2]|0)==(c[d+56>>2]|0):0)?(c[b+88>>2]|0)==(c[d+88>>2]|0):0)qc(m);else c[a+1280>>2]=0;c[a>>2]=c[j>>2];n=2;i=r;return n|0}}if(c[a+3380>>2]|0){n=3;i=r;return n|0}h=a+1368|0;j=a+2356|0;b=a+16|0;if(Ta(q,j,c[b>>2]|0,c[a+12>>2]|0,p)|0){n=3;i=r;return n|0}if(!(Fb(a)|0))d=a+1220|0;else{d=a+1220|0;if((c[p>>2]|0)!=5?(oc(d,c[a+2368>>2]|0,(c[p+4>>2]|0)!=0&1,c[(c[b>>2]|0)+48>>2]|0)|0)!=0:0){n=3;i=r;return n|0}c[a+1336>>2]=jc(d)|0}od(h|0,j|0,988)|0;c[a+1188>>2]=1;b=a+1360|0;l=p;m=c[l+4>>2]|0;n=b;c[n>>2]=c[l>>2];c[n+4>>2]=m;Hb(a,c[a+1432>>2]|0);nc(d);if(gc(d,a+1436|0,c[a+1380>>2]|0,c[a+1412>>2]|0)|0){n=3;i=r;return n|0}g=a+1336|0;if($a(q,a,g,h)|0){ab(a,c[h>>2]|0);n=3;i=r;return n|0}if(!(Gb(a)|0)){n=0;i=r;return n|0}else{c[k>>2]=1;break}}else if((b|0)==8)if(!(Sa(q,h)|0)){Cb(a,h)|0;n=0;i=r;return n|0}else{n=h+20|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+24|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+28|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+44|0;gd(c[n>>2]|0);c[n>>2]=0;n=3;i=r;return n|0}else{n=0;i=r;return n|0}}while(0);uc(g,c[a+1212>>2]|0);Eb(a);j=Gc(a+1284|0,c[a+16>>2]|0,a+1368|0,b)|0;d=a+1188|0;do if(c[d>>2]|0){h=a+1220|0;if(!(c[a+1364>>2]|0)){hc(h,0,g,c[a+1380>>2]|0,j,(c[b>>2]|0)==5&1,c[a+1208>>2]|0,c[a+1204>>2]|0)|0;break}else{hc(h,a+1644|0,g,c[a+1380>>2]|0,j,(c[b>>2]|0)==5&1,c[a+1208>>2]|0,c[a+1204>>2]|0)|0;break}}while(0);c[a+1184>>2]=0;c[d>>2]=0;n=1;i=r;return n|0}else if((b|0)==65520){n=4;i=r;return n|0}else{n=3;i=r;return n|0}return 0}function Jc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;e=0;do{d=a+(e<<2)+20|0;b=c[d>>2]|0;if(b){gd(c[b+40>>2]|0);c[(c[d>>2]|0)+40>>2]=0;gd(c[(c[d>>2]|0)+84>>2]|0);c[(c[d>>2]|0)+84>>2]=0;gd(c[d>>2]|0);c[d>>2]=0}e=e+1|0}while((e|0)!=32);e=0;do{d=a+(e<<2)+148|0;b=c[d>>2]|0;if(b){gd(c[b+20>>2]|0);c[(c[d>>2]|0)+20>>2]=0;gd(c[(c[d>>2]|0)+24>>2]|0);c[(c[d>>2]|0)+24>>2]=0;gd(c[(c[d>>2]|0)+28>>2]|0);c[(c[d>>2]|0)+28>>2]=0;gd(c[(c[d>>2]|0)+44>>2]|0);c[(c[d>>2]|0)+44>>2]=0;gd(c[d>>2]|0);c[d>>2]=0}e=e+1|0}while((e|0)!=256);b=a+3376|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+1212|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+1172|0;gd(c[b>>2]|0);c[b>>2]=0;mc(a+1220|0);i=f;return}function Kc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=i;a=pc(a+1220|0)|0;if(!a){a=0;i=f;return a|0}c[b>>2]=c[a+4>>2];c[d>>2]=c[a+12>>2];c[e>>2]=c[a+8>>2];a=c[a>>2]|0;i=f;return a|0}function Lc(a){a=a|0;var b=0;b=i;a=c[a+16>>2]|0;if(!a){a=0;i=b;return a|0}a=c[a+52>>2]|0;i=b;return a|0}function Mc(a){a=a|0;var b=0;b=i;a=c[a+16>>2]|0;if(!a){a=0;i=b;return a|0}a=c[a+56>>2]|0;i=b;return a|0}function Nc(a){a=a|0;var b=0;b=i;qc(a+1220|0);i=b;return}function Oc(a){a=a|0;var b=0;b=i;a=(Jb(a)|0)==0&1;i=b;return a|0}function Pc(a){a=a|0;var b=0,d=0;d=i;a=c[a+16>>2]|0;if(((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(b=c[a+84>>2]|0,(b|0)!=0):0)?(c[b+24>>2]|0)!=0:0)?(c[b+32>>2]|0)!=0:0){a=1;i=d;return a|0}a=0;i=d;return a|0}function Qc(a){a=a|0;var b=0,d=0;d=i;a=c[a+16>>2]|0;if(((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(b=c[a+84>>2]|0,(b|0)!=0):0)?(c[b+24>>2]|0)!=0:0)?(c[b+36>>2]|0)!=0:0)a=c[b+48>>2]|0;else a=2;i=d;return a|0}function Rc(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;h=i;a=c[a+16>>2]|0;if((a|0)!=0?(c[a+60>>2]|0)!=0:0){c[b>>2]=1;b=a+64|0;c[d>>2]=c[b>>2]<<1;c[e>>2]=(c[a+52>>2]<<4)-((c[a+68>>2]|0)+(c[b>>2]|0)<<1);b=a+72|0;c[f>>2]=c[b>>2]<<1;a=(c[a+56>>2]<<4)-((c[a+76>>2]|0)+(c[b>>2]|0)<<1)|0;c[g>>2]=a;i=h;return}c[b>>2]=0;c[d>>2]=0;c[e>>2]=0;c[f>>2]=0;a=0;c[g>>2]=a;i=h;return}function Sc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;f=i;a=c[a+16>>2]|0;a:do if((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(e=c[a+84>>2]|0,(e|0)!=0):0)?(c[e>>2]|0)!=0:0){a=c[e+4>>2]|0;do switch(a|0){case 8:{e=11;a=32;break a}case 13:{e=99;a=160;break a}case 12:{e=33;a=64;break a}case 6:{e=11;a=24;break a}case 7:{e=11;a=20;break a}case 255:{a=c[e+8>>2]|0;e=c[e+12>>2]|0;g=(a|0)==0|(e|0)==0;e=g?0:e;a=g?0:a;break a}case 5:{e=33;a=40;break a}case 4:{e=11;a=16;break a}case 3:{e=11;a=10;break a}case 1:case 0:{e=a;break a}case 2:{e=11;a=12;break a}case 10:{e=11;a=18;break a}case 9:{e=33;a=80;break a}case 11:{e=11;a=15;break a}default:{e=0;a=0;break a}}while(0)}else{e=1;a=1}while(0);c[b>>2]=a;c[d>>2]=e;i=f;return}function Tc(a){a=a|0;a=c[a+16>>2]|0;if(!a)a=0;else a=c[a>>2]|0;return a|0}function Uc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;do if(a){d=fd(3396)|0;if(d){e=d+8|0;if(!(Hc(e,b)|0)){c[d>>2]=1;c[d+4>>2]=0;c[a>>2]=d;d=0;break}else{Jc(e);gd(d);d=-4;break}}else d=-4}else d=-1;while(0);i=f;return d|0}function Vc(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;if((a|0)==0|(b|0)==0){a=-1;i=e;return a|0}d=a+8|0;if(!(c[a+24>>2]|0)){a=-6;i=e;return a|0}if(!(c[a+20>>2]|0)){a=-6;i=e;return a|0}c[b+4>>2]=(Lc(d)|0)<<4;c[b+8>>2]=(Mc(d)|0)<<4;c[b+12>>2]=Pc(d)|0;c[b+16>>2]=Qc(d)|0;Rc(d,b+28|0,b+32|0,b+36|0,b+40|0,b+44|0);Sc(d,b+20|0,b+24|0);c[b>>2]=Tc(d)|0;a=0;i=e;return a|0}function Wc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;m=i;i=i+16|0;j=m;a:do if((!((b|0)==0|(d|0)==0)?(f=c[b>>2]|0,(f|0)!=0):0)?(g=c[b+4>>2]|0,(g|0)!=0):0)if((a|0)!=0?(e=c[a>>2]|0,(e|0)!=0):0){c[d>>2]=0;c[j>>2]=0;k=a+8|0;c[a+3392>>2]=c[b+12>>2];h=b+8|0;b=1;while(1){if((e|0)==2){l=8;break}e=Ic(k,f,g,c[h>>2]|0,j)|0;n=c[j>>2]|0;f=f+n|0;g=g-n|0;g=(g|0)<0?0:g;c[d>>2]=f;if((e|0)==5){b=-4;break a}else if((e|0)==4){e=(Oc(k)|0|g|0)==0;b=e?-2:b}else if((e|0)==2)break;else if((e|0)==1){l=13;break}if(!g)break a;e=c[a>>2]|0}if((l|0)==8){c[a>>2]=1;c[d>>2]=f+(c[j>>2]|0)}else if((l|0)==13){b=a+4|0;c[b>>2]=(c[b>>2]|0)+1;b=(g|0)==0?2:3;break}b=a+1288|0;if((c[b>>2]|0)!=0?(c[a+1244>>2]|0)!=(c[a+1248>>2]|0):0){c[b>>2]=0;c[a>>2]=2;b=3}else b=4}else b=-3;else b=-1;while(0);i=m;return b|0}function Xc(a){a=a|0;c[a>>2]=2;c[a+4>>2]=3;return}function Yc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;h=i;i=i+16|0;f=h+8|0;e=h+4|0;g=h;if((a|0)==0|(b|0)==0){a=-1;i=h;return a|0}a=a+8|0;if(d)Nc(a);a=Kc(a,g,e,f)|0;if(!a){a=0;i=h;return a|0}c[b>>2]=a;c[b+4>>2]=c[g>>2];c[b+8>>2]=c[e>>2];c[b+12>>2]=c[f>>2];a=2;i=h;return a|0}function Zc(a){a=a|0;var b=0,d=0;d=i;b=jd(a)|0;c[1792]=b;c[1791]=b;c[1790]=a;c[1793]=b+a;i=d;return b|0}function _c(a){a=a|0;c[1790]=a;return}function $c(){var a=0;a=i;c[1786]=c[1791];c[1787]=c[1790];do bd()|0;while((c[1787]|0)!=0);i=a;return}function ad(){var a=0,b=0;b=i;if(Uc(7176,0)|0){da(7280)|0;a=c[1784]|0;if(a)kd(a)}else{c[1796]=1;c[1798]=1}i=b;return -1}function bd(){var a=0,b=0,d=0;b=i;c[1788]=c[1798];a=Wc(c[1794]|0,7144,7200)|0;switch(a|0){case 1:case -2:{c[1787]=0;i=b;return a|0}case 4:{if(Vc(c[1794]|0,7208)|0){a=-1;i=b;return a|0}c[1814]=(Z((c[1803]|0)*3|0,c[1804]|0)|0)>>>1;ra();a=c[1800]|0;c[1787]=(c[1786]|0)-a+(c[1787]|0);c[1786]=a;a=0;i=b;return a|0}case 2:{c[1787]=0;break}case 3:{d=c[1800]|0;c[1787]=(c[1786]|0)-d+(c[1787]|0);c[1786]=d;break}default:{i=b;return a|0}}c[1798]=(c[1798]|0)+1;if((Yc(c[1794]|0,7264,0)|0)!=2){i=b;return a|0}do{c[1796]=(c[1796]|0)+1;ca(c[1816]|0,c[1803]|0,c[1804]|0)}while((Yc(c[1794]|0,7264,0)|0)==2);i=b;return a|0}function cd(){var a=0,b=0;b=i;a=c[1784]|0;if(a)kd(a);i=b;return}function dd(){var a=0,b=0;b=i;i=i+16|0;a=b;Xc(a);i=b;return c[a>>2]|0}function ed(){var a=0,b=0;b=i;i=i+16|0;a=b;Xc(a);i=b;return c[a+4>>2]|0}function fd(a){a=a|0;var b=0;b=i;a=jd(a)|0;i=b;return a|0}function gd(a){a=a|0;var b=0;b=i;kd(a);i=b;return}function hd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=i;od(a|0,b|0,c|0)|0;i=d;return}function id(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=i;nd(a|0,b&255|0,c|0)|0;i=d;return}function jd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=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,G=0,H=0,I=0,J=0,K=0,L=0;L=i;do if(a>>>0<245){if(a>>>0<11)p=16;else p=a+11&-8;a=p>>>3;l=c[1828]|0;k=l>>>a;if(k&3){g=(k&1^1)+a|0;b=g<<1;h=7352+(b<<2)|0;b=7352+(b+2<<2)|0;e=c[b>>2]|0;j=e+8|0;f=c[j>>2]|0;do if((h|0)!=(f|0)){if(f>>>0<(c[1832]|0)>>>0)ka();d=f+12|0;if((c[d>>2]|0)==(e|0)){c[d>>2]=h;c[b>>2]=f;break}else ka()}else c[1828]=l&~(1<>2]=x|3;x=e+(x|4)|0;c[x>>2]=c[x>>2]|1;x=j;i=L;return x|0}j=c[1830]|0;if(p>>>0>j>>>0){if(k){g=2<>>12&16;g=g>>>a;h=g>>>5&8;g=g>>>h;d=g>>>2&4;g=g>>>d;e=g>>>1&2;g=g>>>e;f=g>>>1&1;f=(h|a|d|e|f)+(g>>>f)|0;g=f<<1;e=7352+(g<<2)|0;g=7352+(g+2<<2)|0;d=c[g>>2]|0;a=d+8|0;h=c[a>>2]|0;do if((e|0)!=(h|0)){if(h>>>0<(c[1832]|0)>>>0)ka();j=h+12|0;if((c[j>>2]|0)==(d|0)){c[j>>2]=e;c[g>>2]=h;m=c[1830]|0;break}else ka()}else{c[1828]=l&~(1<>2]=p|3;b=d+p|0;c[d+(p|4)>>2]=k|1;c[d+x>>2]=k;if(m){e=c[1833]|0;g=m>>>3;h=g<<1;f=7352+(h<<2)|0;j=c[1828]|0;g=1<>2]|0;if(h>>>0<(c[1832]|0)>>>0)ka();else{n=j;o=h}}else{c[1828]=j|g;n=7352+(h+2<<2)|0;o=f}c[n>>2]=e;c[o+12>>2]=e;c[e+8>>2]=o;c[e+12>>2]=f}c[1830]=k;c[1833]=b;x=a;i=L;return x|0}k=c[1829]|0;if(k){l=(k&0-k)+-1|0;w=l>>>12&16;l=l>>>w;v=l>>>5&8;l=l>>>v;x=l>>>2&4;l=l>>>x;j=l>>>1&2;l=l>>>j;m=l>>>1&1;m=c[7616+((v|w|x|j|m)+(l>>>m)<<2)>>2]|0;l=(c[m+4>>2]&-8)-p|0;j=m;while(1){d=c[j+16>>2]|0;if(!d){d=c[j+20>>2]|0;if(!d)break}j=(c[d+4>>2]&-8)-p|0;x=j>>>0>>0;l=x?j:l;j=d;m=x?d:m}k=c[1832]|0;if(m>>>0>>0)ka();b=m+p|0;if(m>>>0>=b>>>0)ka();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){e=0;break}}while(1){f=j+20|0;g=c[f>>2]|0;if(g){j=g;h=f;continue}f=j+16|0;g=c[f>>2]|0;if(!g)break;else{j=g;h=f}}if(h>>>0>>0)ka();else{c[h>>2]=0;e=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ka();j=f+12|0;if((c[j>>2]|0)!=(m|0))ka();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;e=g;break}else ka()}while(0);do if(a){j=c[m+28>>2]|0;h=7616+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=e;if(!e){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=e;else c[a+20>>2]=e;if(!e)break}h=c[1832]|0;if(e>>>0>>0)ka();c[e+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ka();else{c[e+16>>2]=j;c[j+24>>2]=e;break}while(0);f=c[m+20>>2]|0;if(f)if(f>>>0<(c[1832]|0)>>>0)ka();else{c[e+20>>2]=f;c[f+24>>2]=e;break}}while(0);if(l>>>0<16){x=l+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}else{c[m+4>>2]=p|3;c[m+(p|4)>>2]=l|1;c[m+(l+p)>>2]=l;d=c[1830]|0;if(d){e=c[1833]|0;g=d>>>3;h=g<<1;f=7352+(h<<2)|0;j=c[1828]|0;g=1<>2]|0;if(h>>>0<(c[1832]|0)>>>0)ka();else{r=j;q=h}}else{c[1828]=j|g;r=7352+(h+2<<2)|0;q=f}c[r>>2]=e;c[q+12>>2]=e;c[e+8>>2]=q;c[e+12>>2]=f}c[1830]=l;c[1833]=b}x=m+8|0;i=L;return x|0}}}else if(a>>>0<=4294967231){a=a+11|0;p=a&-8;m=c[1829]|0;if(m){h=0-p|0;a=a>>>8;if(a)if(p>>>0>16777215)l=31;else{q=(a+1048320|0)>>>16&8;r=a<>>16&4;r=r<>>16&2;l=14-(o|q|l)+(r<>>15)|0;l=p>>>(l+7|0)&1|l<<1}else l=0;j=c[7616+(l<<2)>>2]|0;a:do if(!j){a=0;k=0}else{if((l|0)==31)k=0;else k=25-(l>>>1)|0;f=h;a=0;e=p<>2]&-8;h=g-p|0;if(h>>>0>>0)if((g|0)==(p|0)){a=j;k=j;break a}else k=j;else h=f;r=c[j+20>>2]|0;j=c[j+(e>>>31<<2)+16>>2]|0;a=(r|0)==0|(r|0)==(j|0)?a:r;if(!j)break;else{f=h;e=e<<1}}}while(0);if((a|0)==0&(k|0)==0){a=2<>>12&16;r=r>>>n;m=r>>>5&8;r=r>>>m;o=r>>>2&4;r=r>>>o;q=r>>>1&2;r=r>>>q;a=r>>>1&1;a=c[7616+((m|n|o|q|a)+(r>>>a)<<2)>>2]|0}if(!a){n=h;m=k}else while(1){r=(c[a+4>>2]&-8)-p|0;j=r>>>0>>0;h=j?r:h;k=j?a:k;j=c[a+16>>2]|0;if(j){a=j;continue}a=c[a+20>>2]|0;if(!a){n=h;m=k;break}}if((m|0)!=0?n>>>0<((c[1830]|0)-p|0)>>>0:0){k=c[1832]|0;if(m>>>0>>0)ka();o=m+p|0;if(m>>>0>=o>>>0)ka();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){b=0;break}}while(1){f=j+20|0;g=c[f>>2]|0;if(g){j=g;h=f;continue}f=j+16|0;g=c[f>>2]|0;if(!g)break;else{j=g;h=f}}if(h>>>0>>0)ka();else{c[h>>2]=0;b=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ka();j=f+12|0;if((c[j>>2]|0)!=(m|0))ka();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;b=g;break}else ka()}while(0);do if(a){j=c[m+28>>2]|0;h=7616+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=b;if(!b){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=b;else c[a+20>>2]=b;if(!b)break}h=c[1832]|0;if(b>>>0>>0)ka();c[b+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ka();else{c[b+16>>2]=j;c[j+24>>2]=b;break}while(0);j=c[m+20>>2]|0;if(j)if(j>>>0<(c[1832]|0)>>>0)ka();else{c[b+20>>2]=j;c[j+24>>2]=b;break}}while(0);b:do if(n>>>0>=16){c[m+4>>2]=p|3;c[m+(p|4)>>2]=n|1;c[m+(n+p)>>2]=n;j=n>>>3;if(n>>>0<256){g=j<<1;d=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(e>>>0>=(c[1832]|0)>>>0){t=f;u=e;break}ka()}while(0);c[t>>2]=o;c[u+12>>2]=o;c[m+(p+8)>>2]=u;c[m+(p+12)>>2]=d;break}d=n>>>8;if(d)if(n>>>0>16777215)f=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|w|f)+(x<>>15)|0;f=n>>>(f+7|0)&1|f<<1}else f=0;h=7616+(f<<2)|0;c[m+(p+28)>>2]=f;c[m+(p+20)>>2]=0;c[m+(p+16)>>2]=0;j=c[1829]|0;g=1<>2]=o;c[m+(p+24)>>2]=h;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break}j=c[h>>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;c:do if((c[j+4>>2]&-8|0)!=(n|0)){f=n<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(n|0)){v=h;break c}else{f=f<<1;j=h}}if(g>>>0<(c[1832]|0)>>>0)ka();else{c[g>>2]=o;c[m+(p+24)>>2]=j;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break b}}else v=j;while(0);b=v+8|0;d=c[b>>2]|0;x=c[1832]|0;if(v>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=o;c[b>>2]=o;c[m+(p+8)>>2]=d;c[m+(p+12)>>2]=v;c[m+(p+24)>>2]=0;break}else ka()}else{x=n+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}while(0);x=m+8|0;i=L;return x|0}}}else p=-1;while(0);k=c[1830]|0;if(k>>>0>=p>>>0){d=k-p|0;b=c[1833]|0;if(d>>>0>15){c[1833]=b+p;c[1830]=d;c[b+(p+4)>>2]=d|1;c[b+k>>2]=d;c[b+4>>2]=p|3}else{c[1830]=0;c[1833]=0;c[b+4>>2]=k|3;x=b+(k+4)|0;c[x>>2]=c[x>>2]|1}x=b+8|0;i=L;return x|0}k=c[1831]|0;if(k>>>0>p>>>0){w=k-p|0;c[1831]=w;x=c[1834]|0;c[1834]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}do if(!(c[1946]|0)){k=ua(30)|0;if(!(k+-1&k)){c[1948]=k;c[1947]=k;c[1949]=-1;c[1950]=-1;c[1951]=0;c[1939]=0;c[1946]=(ta(0)|0)&-16^1431655768;break}else ka()}while(0);l=p+48|0;g=c[1948]|0;f=p+47|0;h=g+f|0;g=0-g|0;m=h&g;if(m>>>0<=p>>>0){x=0;i=L;return x|0}a=c[1938]|0;if((a|0)!=0?(u=c[1936]|0,v=u+m|0,v>>>0<=u>>>0|v>>>0>a>>>0):0){x=0;i=L;return x|0}d:do if(!(c[1939]&4)){j=c[1834]|0;e:do if(j){a=7760|0;while(1){k=c[a>>2]|0;if(k>>>0<=j>>>0?(s=a+4|0,(k+(c[s>>2]|0)|0)>>>0>j>>>0):0)break;a=c[a+8>>2]|0;if(!a){A=181;break e}}if(a){k=h-(c[1831]|0)&g;if(k>>>0<2147483647){j=ma(k|0)|0;if((j|0)==((c[a>>2]|0)+(c[s>>2]|0)|0))A=190;else A=191}else k=0}else A=181}else A=181;while(0);do if((A|0)==181){j=ma(0)|0;if((j|0)!=(-1|0)){a=j;k=c[1947]|0;h=k+-1|0;if(!(h&a))k=m;else k=m-a+(h+a&0-k)|0;a=c[1936]|0;h=a+k|0;if(k>>>0>p>>>0&k>>>0<2147483647){v=c[1938]|0;if((v|0)!=0?h>>>0<=a>>>0|h>>>0>v>>>0:0){k=0;break}h=ma(k|0)|0;if((h|0)==(j|0))A=190;else{j=h;A=191}}else k=0}else k=0}while(0);f:do if((A|0)==190){if((j|0)!=(-1|0)){w=j;s=k;A=201;break d}}else if((A|0)==191){a=0-k|0;do if((j|0)!=(-1|0)&k>>>0<2147483647&l>>>0>k>>>0?(d=c[1948]|0,d=f-k+d&0-d,d>>>0<2147483647):0)if((ma(d|0)|0)==(-1|0)){ma(a|0)|0;k=0;break f}else{k=d+k|0;break}while(0);if((j|0)==(-1|0))k=0;else{w=j;s=k;A=201;break d}}while(0);c[1939]=c[1939]|4;A=198}else{k=0;A=198}while(0);if((((A|0)==198?m>>>0<2147483647:0)?(w=ma(m|0)|0,x=ma(0)|0,(w|0)!=(-1|0)&(x|0)!=(-1|0)&w>>>0>>0):0)?(z=x-w|0,y=z>>>0>(p+40|0)>>>0,y):0){s=y?z:k;A=201}if((A|0)==201){j=(c[1936]|0)+s|0;c[1936]=j;if(j>>>0>(c[1937]|0)>>>0)c[1937]=j;o=c[1834]|0;g:do if(o){f=7760|0;while(1){k=c[f>>2]|0;g=f+4|0;j=c[g>>2]|0;if((w|0)==(k+j|0)){A=213;break}h=c[f+8>>2]|0;if(!h)break;else f=h}if(((A|0)==213?(c[f+12>>2]&8|0)==0:0)?o>>>0>=k>>>0&o>>>0>>0:0){c[g>>2]=j+s;d=(c[1831]|0)+s|0;b=o+8|0;if(!(b&7))b=0;else b=0-b&7;x=d-b|0;c[1834]=o+b;c[1831]=x;c[o+(b+4)>>2]=x|1;c[o+(d+4)>>2]=40;c[1835]=c[1950];break}k=c[1832]|0;if(w>>>0>>0){c[1832]=w;k=w}h=w+s|0;g=7760|0;while(1){if((c[g>>2]|0)==(h|0)){A=223;break}j=c[g+8>>2]|0;if(!j)break;else g=j}if((A|0)==223?(c[g+12>>2]&8|0)==0:0){c[g>>2]=w;j=g+4|0;c[j>>2]=(c[j>>2]|0)+s;j=w+8|0;if(!(j&7))r=0;else r=0-j&7;j=w+(s+8)|0;if(!(j&7))b=0;else b=0-j&7;j=w+(b+s)|0;q=r+p|0;n=w+q|0;d=j-(w+r)-p|0;c[w+(r+4)>>2]=p|3;h:do if((j|0)!=(o|0)){if((j|0)==(c[1833]|0)){x=(c[1830]|0)+d|0;c[1830]=x;c[1833]=n;c[w+(q+4)>>2]=x|1;c[w+(x+q)>>2]=x;break}l=s+4|0;h=c[w+(l+b)>>2]|0;if((h&3|0)==1){m=h&-8;e=h>>>3;i:do if(h>>>0>=256){a=c[w+((b|24)+s)>>2]|0;g=c[w+(s+12+b)>>2]|0;do if((g|0)==(j|0)){g=b|16;f=w+(l+g)|0;h=c[f>>2]|0;if(!h){g=w+(g+s)|0;h=c[g>>2]|0;if(!h){H=0;break}}else g=f;while(1){e=h+20|0;f=c[e>>2]|0;if(f){h=f;g=e;continue}e=h+16|0;f=c[e>>2]|0;if(!f)break;else{h=f;g=e}}if(g>>>0>>0)ka();else{c[g>>2]=0;H=h;break}}else{f=c[w+((b|8)+s)>>2]|0;if(f>>>0>>0)ka();k=f+12|0;if((c[k>>2]|0)!=(j|0))ka();h=g+8|0;if((c[h>>2]|0)==(j|0)){c[k>>2]=g;c[h>>2]=f;H=g;break}else ka()}while(0);if(!a)break;k=c[w+(s+28+b)>>2]|0;h=7616+(k<<2)|0;do if((j|0)!=(c[h>>2]|0)){if(a>>>0<(c[1832]|0)>>>0)ka();k=a+16|0;if((c[k>>2]|0)==(j|0))c[k>>2]=H;else c[a+20>>2]=H;if(!H)break i}else{c[h>>2]=H;if(H)break;c[1829]=c[1829]&~(1<>>0>>0)ka();c[H+24>>2]=a;j=b|16;k=c[w+(j+s)>>2]|0;do if(k)if(k>>>0>>0)ka();else{c[H+16>>2]=k;c[k+24>>2]=H;break}while(0);j=c[w+(l+j)>>2]|0;if(!j)break;if(j>>>0<(c[1832]|0)>>>0)ka();else{c[H+20>>2]=j;c[j+24>>2]=H;break}}else{g=c[w+((b|8)+s)>>2]|0;f=c[w+(s+12+b)>>2]|0;h=7352+(e<<1<<2)|0;do if((g|0)!=(h|0)){if(g>>>0>>0)ka();if((c[g+12>>2]|0)==(j|0))break;ka()}while(0);if((f|0)==(g|0)){c[1828]=c[1828]&~(1<>>0>>0)ka();k=f+8|0;if((c[k>>2]|0)==(j|0)){D=k;break}ka()}while(0);c[g+12>>2]=f;c[D>>2]=g}while(0);j=w+((m|b)+s)|0;k=m+d|0}else k=d;j=j+4|0;c[j>>2]=c[j>>2]&-2;c[w+(q+4)>>2]=k|1;c[w+(k+q)>>2]=k;j=k>>>3;if(k>>>0<256){g=j<<1;f=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(h>>>0>=(c[1832]|0)>>>0){I=j;J=h;break}ka()}while(0);c[I>>2]=n;c[J+12>>2]=n;c[w+(q+8)>>2]=J;c[w+(q+12)>>2]=f;break}d=k>>>8;do if(!d)f=0;else{if(k>>>0>16777215){f=31;break}v=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|v|f)+(x<>>15)|0;f=k>>>(f+7|0)&1|f<<1}while(0);h=7616+(f<<2)|0;c[w+(q+28)>>2]=f;c[w+(q+20)>>2]=0;c[w+(q+16)>>2]=0;j=c[1829]|0;g=1<>2]=n;c[w+(q+24)>>2]=h;c[w+(q+12)>>2]=n;c[w+(q+8)>>2]=n;break}j=c[h>>2]|0;if((f|0)==31)h=0;else h=25-(f>>>1)|0;j:do if((c[j+4>>2]&-8|0)!=(k|0)){f=k<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(k|0)){K=h;break j}else{f=f<<1;j=h}}if(g>>>0<(c[1832]|0)>>>0)ka();else{c[g>>2]=n;c[w+(q+24)>>2]=j;c[w+(q+12)>>2]=n;c[w+(q+8)>>2]=n;break h}}else K=j;while(0);b=K+8|0;d=c[b>>2]|0;x=c[1832]|0;if(K>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=n;c[b>>2]=n;c[w+(q+8)>>2]=d;c[w+(q+12)>>2]=K;c[w+(q+24)>>2]=0;break}else ka()}else{x=(c[1831]|0)+d|0;c[1831]=x;c[1834]=n;c[w+(q+4)>>2]=x|1}while(0);x=w+(r|8)|0;i=L;return x|0}j=7760|0;while(1){h=c[j>>2]|0;if(h>>>0<=o>>>0?(B=c[j+4>>2]|0,C=h+B|0,C>>>0>o>>>0):0)break;j=c[j+8>>2]|0}j=h+(B+-39)|0;if(!(j&7))j=0;else j=0-j&7;g=h+(B+-47+j)|0;g=g>>>0<(o+16|0)>>>0?o:g;h=g+8|0;j=w+8|0;if(!(j&7))j=0;else j=0-j&7;f=s+-40-j|0;c[1834]=w+j;c[1831]=f;c[w+(j+4)>>2]=f|1;c[w+(s+-36)>>2]=40;c[1835]=c[1950];c[g+4>>2]=27;c[h+0>>2]=c[1940];c[h+4>>2]=c[1941];c[h+8>>2]=c[1942];c[h+12>>2]=c[1943];c[1940]=w;c[1941]=s;c[1943]=0;c[1942]=h;f=g+28|0;c[f>>2]=7;if((g+32|0)>>>0>>0)do{x=f;f=f+4|0;c[f>>2]=7}while((x+8|0)>>>0>>0);if((g|0)!=(o|0)){k=g-o|0;j=o+(k+4)|0;c[j>>2]=c[j>>2]&-2;c[o+4>>2]=k|1;c[o+k>>2]=k;j=k>>>3;if(k>>>0<256){g=j<<1;f=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(b>>>0>=(c[1832]|0)>>>0){E=d;F=b;break}ka()}while(0);c[E>>2]=o;c[F+12>>2]=o;c[o+8>>2]=F;c[o+12>>2]=f;break}d=k>>>8;if(d)if(k>>>0>16777215)g=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;g=14-(v|w|g)+(x<>>15)|0;g=k>>>(g+7|0)&1|g<<1}else g=0;h=7616+(g<<2)|0;c[o+28>>2]=g;c[o+20>>2]=0;c[o+16>>2]=0;e=c[1829]|0;j=1<>2]=o;c[o+24>>2]=h;c[o+12>>2]=o;c[o+8>>2]=o;break}e=c[h>>2]|0;if((g|0)==31)d=0;else d=25-(g>>>1)|0;k:do if((c[e+4>>2]&-8|0)!=(k|0)){j=k<>>31<<2)+16|0;d=c[h>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(k|0)){G=d;break k}else{j=j<<1;e=d}}if(h>>>0<(c[1832]|0)>>>0)ka();else{c[h>>2]=o;c[o+24>>2]=e;c[o+12>>2]=o;c[o+8>>2]=o;break g}}else G=e;while(0);b=G+8|0;d=c[b>>2]|0;x=c[1832]|0;if(G>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=o;c[b>>2]=o;c[o+8>>2]=d;c[o+12>>2]=G;c[o+24>>2]=0;break}else ka()}}else{x=c[1832]|0;if((x|0)==0|w>>>0>>0)c[1832]=w;c[1940]=w;c[1941]=s;c[1943]=0;c[1837]=c[1946];c[1836]=-1;b=0;do{x=b<<1;v=7352+(x<<2)|0;c[7352+(x+3<<2)>>2]=v;c[7352+(x+2<<2)>>2]=v;b=b+1|0}while((b|0)!=32);b=w+8|0;if(!(b&7))b=0;else b=0-b&7;x=s+-40-b|0;c[1834]=w+b;c[1831]=x;c[w+(b+4)>>2]=x|1;c[w+(s+-36)>>2]=40;c[1835]=c[1950]}while(0);b=c[1831]|0;if(b>>>0>p>>>0){w=b-p|0;c[1831]=w;x=c[1834]|0;c[1834]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}}c[(va()|0)>>2]=12;x=0;i=L;return x|0}function kd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=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;w=i;if(!a){i=w;return}f=a+-8|0;h=c[1832]|0;if(f>>>0>>0)ka();g=c[a+-4>>2]|0;e=g&3;if((e|0)==1)ka();q=g&-8;r=a+(q+-8)|0;do if(!(g&1)){g=c[f>>2]|0;if(!e){i=w;return}j=-8-g|0;m=a+j|0;n=g+q|0;if(m>>>0>>0)ka();if((m|0)==(c[1833]|0)){f=a+(q+-4)|0;g=c[f>>2]|0;if((g&3|0)!=3){v=m;l=n;break}c[1830]=n;c[f>>2]=g&-2;c[a+(j+4)>>2]=n|1;c[r>>2]=n;i=w;return}d=g>>>3;if(g>>>0<256){e=c[a+(j+8)>>2]|0;f=c[a+(j+12)>>2]|0;g=7352+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0>>0)ka();if((c[e+12>>2]|0)!=(m|0))ka()}if((f|0)==(e|0)){c[1828]=c[1828]&~(1<>>0>>0)ka();g=f+8|0;if((c[g>>2]|0)==(m|0))b=g;else ka()}else b=f+8|0;c[e+12>>2]=f;c[b>>2]=e;v=m;l=n;break}b=c[a+(j+24)>>2]|0;e=c[a+(j+12)>>2]|0;do if((e|0)==(m|0)){f=a+(j+20)|0;g=c[f>>2]|0;if(!g){f=a+(j+16)|0;g=c[f>>2]|0;if(!g){k=0;break}}while(1){d=g+20|0;e=c[d>>2]|0;if(e){g=e;f=d;continue}d=g+16|0;e=c[d>>2]|0;if(!e)break;else{g=e;f=d}}if(f>>>0>>0)ka();else{c[f>>2]=0;k=g;break}}else{d=c[a+(j+8)>>2]|0;if(d>>>0>>0)ka();g=d+12|0;if((c[g>>2]|0)!=(m|0))ka();f=e+8|0;if((c[f>>2]|0)==(m|0)){c[g>>2]=e;c[f>>2]=d;k=e;break}else ka()}while(0);if(b){g=c[a+(j+28)>>2]|0;f=7616+(g<<2)|0;if((m|0)==(c[f>>2]|0)){c[f>>2]=k;if(!k){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();g=b+16|0;if((c[g>>2]|0)==(m|0))c[g>>2]=k;else c[b+20>>2]=k;if(!k){v=m;l=n;break}}f=c[1832]|0;if(k>>>0>>0)ka();c[k+24>>2]=b;g=c[a+(j+16)>>2]|0;do if(g)if(g>>>0>>0)ka();else{c[k+16>>2]=g;c[g+24>>2]=k;break}while(0);g=c[a+(j+20)>>2]|0;if(g)if(g>>>0<(c[1832]|0)>>>0)ka();else{c[k+20>>2]=g;c[g+24>>2]=k;v=m;l=n;break}else{v=m;l=n}}else{v=m;l=n}}else{v=f;l=q}while(0);if(v>>>0>=r>>>0)ka();g=a+(q+-4)|0;f=c[g>>2]|0;if(!(f&1))ka();if(!(f&2)){if((r|0)==(c[1834]|0)){m=(c[1831]|0)+l|0;c[1831]=m;c[1834]=v;c[v+4>>2]=m|1;if((v|0)!=(c[1833]|0)){i=w;return}c[1833]=0;c[1830]=0;i=w;return}if((r|0)==(c[1833]|0)){m=(c[1830]|0)+l|0;c[1830]=m;c[1833]=v;c[v+4>>2]=m|1;c[v+m>>2]=m;i=w;return}h=(f&-8)+l|0;d=f>>>3;do if(f>>>0>=256){b=c[a+(q+16)>>2]|0;g=c[a+(q|4)>>2]|0;do if((g|0)==(r|0)){f=a+(q+12)|0;g=c[f>>2]|0;if(!g){f=a+(q+8)|0;g=c[f>>2]|0;if(!g){p=0;break}}while(1){d=g+20|0;e=c[d>>2]|0;if(e){g=e;f=d;continue}d=g+16|0;e=c[d>>2]|0;if(!e)break;else{g=e;f=d}}if(f>>>0<(c[1832]|0)>>>0)ka();else{c[f>>2]=0;p=g;break}}else{f=c[a+q>>2]|0;if(f>>>0<(c[1832]|0)>>>0)ka();e=f+12|0;if((c[e>>2]|0)!=(r|0))ka();d=g+8|0;if((c[d>>2]|0)==(r|0)){c[e>>2]=g;c[d>>2]=f;p=g;break}else ka()}while(0);if(b){g=c[a+(q+20)>>2]|0;f=7616+(g<<2)|0;if((r|0)==(c[f>>2]|0)){c[f>>2]=p;if(!p){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();g=b+16|0;if((c[g>>2]|0)==(r|0))c[g>>2]=p;else c[b+20>>2]=p;if(!p)break}g=c[1832]|0;if(p>>>0>>0)ka();c[p+24>>2]=b;f=c[a+(q+8)>>2]|0;do if(f)if(f>>>0>>0)ka();else{c[p+16>>2]=f;c[f+24>>2]=p;break}while(0);d=c[a+(q+12)>>2]|0;if(d)if(d>>>0<(c[1832]|0)>>>0)ka();else{c[p+20>>2]=d;c[d+24>>2]=p;break}}}else{e=c[a+q>>2]|0;f=c[a+(q|4)>>2]|0;g=7352+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0<(c[1832]|0)>>>0)ka();if((c[e+12>>2]|0)!=(r|0))ka()}if((f|0)==(e|0)){c[1828]=c[1828]&~(1<>>0<(c[1832]|0)>>>0)ka();g=f+8|0;if((c[g>>2]|0)==(r|0))o=g;else ka()}else o=f+8|0;c[e+12>>2]=f;c[o>>2]=e}while(0);c[v+4>>2]=h|1;c[v+h>>2]=h;if((v|0)==(c[1833]|0)){c[1830]=h;i=w;return}else g=h}else{c[g>>2]=f&-2;c[v+4>>2]=l|1;c[v+l>>2]=l;g=l}e=g>>>3;if(g>>>0<256){f=e<<1;g=7352+(f<<2)|0;d=c[1828]|0;e=1<>2]|0;if(b>>>0<(c[1832]|0)>>>0)ka();else{s=d;t=b}}else{c[1828]=d|e;s=7352+(f+2<<2)|0;t=g}c[s>>2]=v;c[t+12>>2]=v;c[v+8>>2]=t;c[v+12>>2]=g;i=w;return}d=g>>>8;if(d)if(g>>>0>16777215)f=31;else{l=(d+1048320|0)>>>16&8;m=d<>>16&4;m=m<>>16&2;f=14-(k|l|f)+(m<>>15)|0;f=g>>>(f+7|0)&1|f<<1}else f=0;b=7616+(f<<2)|0;c[v+28>>2]=f;c[v+20>>2]=0;c[v+16>>2]=0;d=c[1829]|0;e=1<>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;b:do if((c[b+4>>2]&-8|0)!=(g|0)){f=g<>>31<<2)+16|0;d=c[e>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(g|0)){u=d;break b}else{f=f<<1;b=d}}if(e>>>0<(c[1832]|0)>>>0)ka();else{c[e>>2]=v;c[v+24>>2]=b;c[v+12>>2]=v;c[v+8>>2]=v;break a}}else u=b;while(0);d=u+8|0;b=c[d>>2]|0;m=c[1832]|0;if(u>>>0>=m>>>0&b>>>0>=m>>>0){c[b+12>>2]=v;c[d>>2]=v;c[v+8>>2]=b;c[v+12>>2]=u;c[v+24>>2]=0;break}else ka()}else{c[1829]=d|e;c[b>>2]=v;c[v+24>>2]=b;c[v+12>>2]=v;c[v+8>>2]=v}while(0);m=(c[1836]|0)+-1|0;c[1836]=m;if(!m)b=7768|0;else{i=w;return}while(1){b=c[b>>2]|0;if(!b)break;else b=b+8|0}c[1836]=-1;i=w;return}function ld(){}function md(b){b=b|0;var c=0;c=b;while(a[c>>0]|0)c=c+1|0;return c-b|0}function nd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;h=b&3;i=d|d<<8|d<<16|d<<24;g=f&~3;if(h){h=b+4-h|0;while((b|0)<(h|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(g|0)){c[b>>2]=i;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function od(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return pa(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function pd(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;xa[a&3](b|0,c|0,d|0,e|0,f|0)}function qd(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;_(0)} + +// EMSCRIPTEN_END_FUNCS +var xa=[qd,fc,ec,qd];return{_strlen:md,_free:kd,_broadwayGetMajorVersion:dd,_get_h264bsdClip:Lb,_broadwayExit:cd,_memset:nd,_broadwayCreateStream:Zc,_malloc:jd,_memcpy:od,_broadwayGetMinorVersion:ed,_broadwayPlayStream:$c,_broadwaySetStreamLength:_c,_broadwayInit:ad,runPostSets:ld,stackAlloc:ya,stackSave:za,stackRestore:Aa,setThrew:Ba,setTempRet0:Ea,getTempRet0:Fa,dynCall_viiiii:pd}}) + + +// EMSCRIPTEN_END_ASM +(p.Xc,p.Yc,Q),Bb=p._strlen=$._strlen,Ea=p._free=$._free;p._broadwayGetMajorVersion=$._broadwayGetMajorVersion;p._get_h264bsdClip=$._get_h264bsdClip;p._broadwayExit=$._broadwayExit;var Gb=p._memset=$._memset;p._broadwayCreateStream=$._broadwayCreateStream;var Ca=p._malloc=$._malloc,gc=p._memcpy=$._memcpy; +p._broadwayGetMinorVersion=$._broadwayGetMinorVersion;p._broadwayPlayStream=$._broadwayPlayStream;p._broadwaySetStreamLength=$._broadwaySetStreamLength;p._broadwayInit=$._broadwayInit;p.runPostSets=$.runPostSets;p.dynCall_viiiii=$.dynCall_viiiii;z.pb=$.stackAlloc;z.Tb=$.stackSave;z.Sb=$.stackRestore;z.Yd=$.setTempRet0;z.xd=$.getTempRet0; +if(T)if("function"===typeof p.locateFile?T=p.locateFile(T):p.memoryInitializerPrefixURL&&(T=p.memoryInitializerPrefixURL+T),t||da){var hc=p.readBinary(T);N.set(hc,Ia)}else Ya(),yb(T,function(a){N.set(a,Ia);Za()},function(){d("could not load memory initializer "+T)});function ia(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}ia.prototype=Error();var ic,jc=k,Xa=function kc(){!p.calledRun&&lc&&mc();p.calledRun||(Xa=kc)}; +p.callMain=p.ag=function(a){function b(){for(var a=0;3>a;a++)e.push(0)}w(0==S,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");w(0==Oa.length,"cannot call main when preRun functions remain to be called");a=a||[];Sa||(Sa=i,Na(R));var c=a.length+1,e=[M(Va(p.thisProgram),"i8",0)];b();for(var f=0;f y ? y : z); + } + + function OptimizedGetBoundaryStrengthsA($mb, $bS) { + var $totalCoeff = $mb + 28; + + var tc0 = HEAP16[$totalCoeff + 0 >> 1]; + var tc1 = HEAP16[$totalCoeff + 2 >> 1]; + var tc2 = HEAP16[$totalCoeff + 4 >> 1]; + var tc3 = HEAP16[$totalCoeff + 6 >> 1]; + var tc4 = HEAP16[$totalCoeff + 8 >> 1]; + var tc5 = HEAP16[$totalCoeff + 10 >> 1]; + var tc6 = HEAP16[$totalCoeff + 12 >> 1]; + var tc7 = HEAP16[$totalCoeff + 14 >> 1]; + var tc8 = HEAP16[$totalCoeff + 16 >> 1]; + var tc9 = HEAP16[$totalCoeff + 18 >> 1]; + var tc10 = HEAP16[$totalCoeff + 20 >> 1]; + var tc11 = HEAP16[$totalCoeff + 22 >> 1]; + var tc12 = HEAP16[$totalCoeff + 24 >> 1]; + var tc13 = HEAP16[$totalCoeff + 26 >> 1]; + var tc14 = HEAP16[$totalCoeff + 28 >> 1]; + var tc15 = HEAP16[$totalCoeff + 30 >> 1]; + + HEAP32[$bS + 32 >> 2] = tc2 || tc0 ? 2 : 0; + HEAP32[$bS + 40 >> 2] = tc3 || tc1 ? 2 : 0; + HEAP32[$bS + 48 >> 2] = tc6 || tc4 ? 2 : 0; + HEAP32[$bS + 56 >> 2] = tc7 || tc5 ? 2 : 0; + HEAP32[$bS + 64 >> 2] = tc8 || tc2 ? 2 : 0; + HEAP32[$bS + 72 >> 2] = tc9 || tc3 ? 2 : 0; + HEAP32[$bS + 80 >> 2] = tc12 || tc6 ? 2 : 0; + HEAP32[$bS + 88 >> 2] = tc13 || tc7 ? 2 : 0; + HEAP32[$bS + 96 >> 2] = tc10 || tc8 ? 2 : 0; + HEAP32[$bS + 104 >> 2] = tc11 || tc9 ? 2 : 0; + HEAP32[$bS + 112 >> 2] = tc14 || tc12 ? 2 : 0; + HEAP32[$bS + 120 >> 2] = tc15 || tc13 ? 2 : 0; + + HEAP32[$bS + 12 >> 2] = tc1 || tc0 ? 2 : 0; + HEAP32[$bS + 20 >> 2] = tc4 || tc1 ? 2 : 0; + HEAP32[$bS + 28 >> 2] = tc5 || tc4 ? 2 : 0; + HEAP32[$bS + 44 >> 2] = tc3 || tc2 ? 2 : 0; + HEAP32[$bS + 52 >> 2] = tc6 || tc3 ? 2 : 0; + HEAP32[$bS + 60 >> 2] = tc7 || tc6 ? 2 : 0; + HEAP32[$bS + 76 >> 2] = tc9 || tc8 ? 2 : 0; + HEAP32[$bS + 84 >> 2] = tc12 || tc9 ? 2 : 0; + HEAP32[$bS + 92 >> 2] = tc13 || tc12 ? 2 : 0; + HEAP32[$bS + 108 >> 2] = tc11 || tc10 ? 2 : 0; + HEAP32[$bS + 116 >> 2] = tc14 || tc11 ? 2 : 0; + HEAP32[$bS + 124 >> 2] = tc15 || tc14 ? 2 : 0; + } + + function OptimizedFilterVerLumaEdge ($data, bS, $thresholds, imageWidth) { + var delta, tc, tmp; + var p0, q0, p1, q1, p2, q2; + var tmpFlag; + var $clp = _h264bsdClip + 512; + var alpha = HEAP32[$thresholds + 4 >> 2]; + var beta = HEAP32[$thresholds + 8 >> 2]; + var val; + + if (bS < 4) { + tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255; + for (var i = 4; i > 0; i--) { + p1 = HEAPU8[$data + -2] & 255; + p0 = HEAPU8[$data + -1] & 255; + q0 = HEAPU8[$data] & 255; + q1 = HEAPU8[$data + 1] & 255; + if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) { + p2 = HEAPU8[$data - 3] & 255; + if (Math.abs(p2 - p0) < beta) { + val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; + HEAP8[$data - 2] = p1 + clip(-tc, tc, val); + tmp++; + } + + q2 = HEAPU8[$data + 2] & 255; + if (Math.abs(q2 - q0) < beta) { + val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; + HEAP8[$data + 1] = (q1 + clip(-tc, tc, val)); + tmp++; + } + + val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); + delta = clip(-tmp, tmp, val); + + p0 = HEAPU8[$clp + (p0 + delta)] & 255; + q0 = HEAPU8[$clp + (q0 - delta)] & 255; + tmp = tc; + HEAP8[$data - 1] = p0; + HEAP8[$data] = q0; + + $data += imageWidth; + } + } + } else { + OriginalFilterVerLumaEdge($data, bS, $thresholds, imageWidth); + } + } + + /** + * Filter all four successive horizontal 4-pixel luma edges. This can be done when bS is equal to all four edges. + */ + function OptimizedFilterHorLuma ($data, bS, $thresholds, imageWidth) { + var delta, tc, tmp; + var p0, q0, p1, q1, p2, q2; + var tmpFlag; + var $clp = _h264bsdClip + 512; + var alpha = HEAP32[$thresholds + 4 >> 2]; + var beta = HEAP32[$thresholds + 8 >> 2]; + var val; + + if (bS < 4) { + tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255; + for (var i = 16; i > 0; i--) { + p1 = HEAPU8[$data + (-imageWidth << 1)] & 255; + p0 = HEAPU8[$data + -imageWidth] & 255; + q0 = HEAPU8[$data] & 255; + q1 = HEAPU8[$data + imageWidth] & 255; + + if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) { + p2 = HEAPU8[$data + (-imageWidth * 3)] & 255; + if (Math.abs(p2 - p0) < beta) { + val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; + HEAP8[$data + (-imageWidth << 1)] = p1 + clip(-tc, tc, val); + tmp++; + } + + q2 = HEAPU8[$data + (imageWidth << 2)] & 255; + if (Math.abs(q2 - q0) < beta) { + val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; + HEAP8[$data + imageWidth] = (q1 + clip(-tc, tc, val)); + tmp++; + } + + val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); + delta = clip(-tmp, tmp, val); + + p0 = HEAPU8[$clp + (p0 + delta)] & 255; + q0 = HEAPU8[$clp + (q0 - delta)] & 255; + tmp = tc; + HEAP8[$data - imageWidth] = p0; + HEAP8[$data] = q0; + + $data ++; + } + } + } else { + OriginalFilterHorLuma($data, bS, $thresholds, imageWidth); + } + } + }; + + + Broadway.prototype = { + configure: function (config) { + // patchOptimizations(config, patches); + console.info("Broadway Configured: " + JSON.stringify(config)); + } + + }; + + + + + /* + + asm.js implementation of a yuv to rgb convertor + provided by @soliton4 + + based on + http://www.wordsaretoys.com/2013/10/18/making-yuv-conversion-a-little-faster/ + + */ + + + // factory to create asm.js yuv -> rgb convertor for a given resolution + var asmInstances = {}; + var getAsm = function(parWidth, parHeight){ + var idStr = "" + parWidth + "x" + parHeight; + if (asmInstances[idStr]){ + return asmInstances[idStr]; + }; + + var lumaSize = parWidth * parHeight; + var chromaSize = (lumaSize|0) >> 2; + + var inpSize = lumaSize + chromaSize + chromaSize; + var outSize = parWidth * parHeight * 4; + var cacheSize = Math.pow(2, 24) * 4; + var size = inpSize + outSize + cacheSize; + + var chunkSize = Math.pow(2, 24); + var heapSize = chunkSize; + while (heapSize < size){ + heapSize += chunkSize; + }; + var heap = new ArrayBuffer(heapSize); + + var res = asmFactory(global, {}, heap); + res.init(parWidth, parHeight); + asmInstances[idStr] = res; + + res.heap = heap; + res.out = new Uint8Array(heap, 0, outSize); + res.inp = new Uint8Array(heap, outSize, inpSize); + res.outSize = outSize; + + return res; + }; + + + function asmFactory(stdlib, foreign, heap) { + "use asm"; + + var imul = stdlib.Math.imul; + var min = stdlib.Math.min; + var max = stdlib.Math.max; + var pow = stdlib.Math.pow; + var out = new stdlib.Uint8Array(heap); + var out32 = new stdlib.Uint32Array(heap); + var inp = new stdlib.Uint8Array(heap); + var mem = new stdlib.Uint8Array(heap); + var mem32 = new stdlib.Uint32Array(heap); + + // for double algo + /*var vt = 1.370705; + var gt = 0.698001; + var gt2 = 0.337633; + var bt = 1.732446;*/ + + var width = 0; + var height = 0; + var lumaSize = 0; + var chromaSize = 0; + var inpSize = 0; + var outSize = 0; + + var inpStart = 0; + var outStart = 0; + + var widthFour = 0; + + var cacheStart = 0; + + + function init(parWidth, parHeight){ + parWidth = parWidth|0; + parHeight = parHeight|0; + + var i = 0; + var s = 0; + + width = parWidth; + widthFour = imul(parWidth, 4)|0; + height = parHeight; + lumaSize = imul(width|0, height|0)|0; + chromaSize = (lumaSize|0) >> 2; + outSize = imul(imul(width, height)|0, 4)|0; + inpSize = ((lumaSize + chromaSize)|0 + chromaSize)|0; + + outStart = 0; + inpStart = (outStart + outSize)|0; + cacheStart = (inpStart + inpSize)|0; + + // initializing memory (to be on the safe side) + s = ~~(+pow(+2, +24)); + s = imul(s, 4)|0; + + for (i = 0|0; ((i|0) < (s|0))|0; i = (i + 4)|0){ + mem32[((cacheStart + i)|0) >> 2] = 0; + }; + }; + + function doit(){ + var ystart = 0; + var ustart = 0; + var vstart = 0; + + var y = 0; + var yn = 0; + var u = 0; + var v = 0; + + var o = 0; + + var line = 0; + var col = 0; + + var usave = 0; + var vsave = 0; + + var ostart = 0; + var cacheAdr = 0; + + ostart = outStart|0; + + ystart = inpStart|0; + ustart = (ystart + lumaSize|0)|0; + vstart = (ustart + chromaSize)|0; + + for (line = 0; (line|0) < (height|0); line = (line + 2)|0){ + usave = ustart; + vsave = vstart; + for (col = 0; (col|0) < (width|0); col = (col + 2)|0){ + y = inp[ystart >> 0]|0; + yn = inp[((ystart + width)|0) >> 0]|0; + + u = inp[ustart >> 0]|0; + v = inp[vstart >> 0]|0; + + cacheAdr = (((((y << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(y,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[ostart >> 2] = o; + + cacheAdr = (((((yn << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(yn,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[((ostart + widthFour)|0) >> 2] = o; + + //yuv2rgb5(y, u, v, ostart); + //yuv2rgb5(yn, u, v, (ostart + widthFour)|0); + ostart = (ostart + 4)|0; + + // next step only for y. u and v stay the same + ystart = (ystart + 1)|0; + y = inp[ystart >> 0]|0; + yn = inp[((ystart + width)|0) >> 0]|0; + + //yuv2rgb5(y, u, v, ostart); + cacheAdr = (((((y << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(y,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[ostart >> 2] = o; + + //yuv2rgb5(yn, u, v, (ostart + widthFour)|0); + cacheAdr = (((((yn << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(yn,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[((ostart + widthFour)|0) >> 2] = o; + ostart = (ostart + 4)|0; + + //all positions inc 1 + + ystart = (ystart + 1)|0; + ustart = (ustart + 1)|0; + vstart = (vstart + 1)|0; + }; + ostart = (ostart + widthFour)|0; + ystart = (ystart + width)|0; + + }; + + }; + + function yuv2rgbcalc(y, u, v){ + y = y|0; + u = u|0; + v = v|0; + + var r = 0; + var g = 0; + var b = 0; + + var o = 0; + + var a0 = 0; + var a1 = 0; + var a2 = 0; + var a3 = 0; + var a4 = 0; + + a0 = imul(1192, (y - 16)|0)|0; + a1 = imul(1634, (v - 128)|0)|0; + a2 = imul(832, (v - 128)|0)|0; + a3 = imul(400, (u - 128)|0)|0; + a4 = imul(2066, (u - 128)|0)|0; + + r = (((a0 + a1)|0) >> 10)|0; + g = (((((a0 - a2)|0) - a3)|0) >> 10)|0; + b = (((a0 + a4)|0) >> 10)|0; + + if ((((r & 255)|0) != (r|0))|0){ + r = min(255, max(0, r|0)|0)|0; + }; + if ((((g & 255)|0) != (g|0))|0){ + g = min(255, max(0, g|0)|0)|0; + }; + if ((((b & 255)|0) != (b|0))|0){ + b = min(255, max(0, b|0)|0)|0; + }; + + o = 255; + o = (o << 8)|0; + o = (o + b)|0; + o = (o << 8)|0; + o = (o + g)|0; + o = (o << 8)|0; + o = (o + r)|0; + + return o|0; + + }; + + + + return { + init: init, + doit: doit + }; + }; + + + /* + potential worker initialization + + */ + + + if (typeof self != "undefined"){ + var isWorker = false; + var decoder; + var reuseMemory = false; + + var memAr = []; + var getMem = function(length){ + if (memAr.length){ + var u = memAr.shift(); + while (u && u.byteLength !== length){ + u = memAr.shift(); + }; + if (u){ + return u; + }; + }; + return new ArrayBuffer(length); + }; + + self.addEventListener('message', function(e) { + + if (isWorker){ + if (reuseMemory){ + if (e.data.reuse){ + memAr.push(e.data.reuse); + }; + }; + if (e.data.buf){ + decoder.decode(new Uint8Array(e.data.buf, e.data.offset || 0, e.data.length), e.data.info); + }; + + }else{ + if (e.data && e.data.type === "Broadway.js - Worker init"){ + isWorker = true; + decoder = new Broadway(e.data.options); + + if (e.data.options.reuseMemory){ + reuseMemory = true; + decoder.onPictureDecoded = function (buffer, width, height, infos) { + + //var buf = getMem(); + + // buffer needs to be copied because we give up ownership + var copyU8 = new Uint8Array(getMem(buffer.length)); + copyU8.set( buffer, 0, buffer.length ); + + postMessage({ + buf: copyU8.buffer, + length: buffer.length, + width: width, + height: height, + infos: infos + }, [copyU8.buffer]); // 2nd parameter is used to indicate transfer of ownership + + }; + + }else{ + decoder.onPictureDecoded = function (buffer, width, height, infos) { + if (buffer) { + buffer = new Uint8Array(buffer); + }; + + // buffer needs to be copied because we give up ownership + var copyU8 = new Uint8Array(buffer.length); + copyU8.set( buffer, 0, buffer.length ); + + postMessage({ + buf: copyU8.buffer, + length: buffer.length, + width: width, + height: height, + infos: infos + }, [copyU8.buffer]); // 2nd parameter is used to indicate transfer of ownership + + }; + }; + postMessage({ consoleLog: "broadway worker initialized" }); + }; + }; + + + }, false); + }; + + Broadway.nowValue = nowValue; + + return Broadway; + + })(); + + +})); + + +}).call(this,"/dvp\\node_modules\\h264-live-player\\vendor\\broadway") +},{}],5:[function(require,module,exports){ +"use strict"; +var assert = require('../utils/assert'); + + +function Program(gl) { + this.gl = gl; + this.program = this.gl.createProgram(); +} + +Program.prototype = { + attach: function (shader) { + this.gl.attachShader(this.program, shader.shader); + }, + link: function () { + this.gl.linkProgram(this.program); + // If creating the shader program failed, alert. + assert(this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS), + "Unable to initialize the shader program."); + }, + use: function () { + this.gl.useProgram(this.program); + }, + getAttributeLocation: function(name) { + return this.gl.getAttribLocation(this.program, name); + }, + setMatrixUniform: function(name, array) { + var uniform = this.gl.getUniformLocation(this.program, name); + this.gl.uniformMatrix4fv(uniform, false, array); + } +}; +module.exports = Program; + + +},{"../utils/assert":20}],6:[function(require,module,exports){ +"use strict"; + +var assert = require('../utils/assert'); + +/** + * Represents a WebGL shader script. + */ + +function Script() {} + +Script.createFromElementId = function(id) { + var script = document.getElementById(id); + + // Didn't find an element with the specified ID, abort. + assert(script , "Could not find shader with ID: " + id); + + // Walk through the source element's children, building the shader source string. + var source = ""; + var currentChild = script .firstChild; + while(currentChild) { + if (currentChild.nodeType == 3) { + source += currentChild.textContent; + } + currentChild = currentChild.nextSibling; + } + + var res = new Scriptor(); + res.type = script.type; + res.source = source; + return res; +}; + +Script.createFromSource = function(type, source) { + var res = new Script(); + res.type = type; + res.source = source; + return res; +} + + +module.exports = Script; +},{"../utils/assert":20}],7:[function(require,module,exports){ +"use strict"; + +var error = require('../utils/error'); + +/** + * Represents a WebGL shader object and provides a mechanism to load shaders from HTML + * script tags. + */ + + +function Shader(gl, script) { + + // Now figure out what type of shader script we have, based on its MIME type. + if (script.type == "x-shader/x-fragment") { + this.shader = gl.createShader(gl.FRAGMENT_SHADER); + } else if (script.type == "x-shader/x-vertex") { + this.shader = gl.createShader(gl.VERTEX_SHADER); + } else { + error("Unknown shader type: " + script.type); + return; + } + + // Send the source to the shader object. + gl.shaderSource(this.shader, script.source); + + // Compile the shader program. + gl.compileShader(this.shader); + + // See if it compiled successfully. + if (!gl.getShaderParameter(this.shader, gl.COMPILE_STATUS)) { + error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(this.shader)); + return; + } +} +module.exports = Shader; + + + + +},{"../utils/error":21}],8:[function(require,module,exports){ +"use strict"; + +var assert = require('../utils/assert'); + +/** + * Represents a WebGL texture object. + */ + +function Texture(gl, size, format) { + this.gl = gl; + this.size = size; + this.texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + this.format = format ? format : gl.LUMINANCE; + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, size.w, size.h, 0, this.format, gl.UNSIGNED_BYTE, null); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); +} + +var textureIDs = null; +Texture.prototype = { + fill: function(textureData, useTexSubImage2D) { + var gl = this.gl; + assert(textureData.length >= this.size.w * this.size.h, + "Texture size mismatch, data:" + textureData.length + ", texture: " + this.size.w * this.size.h); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + if (useTexSubImage2D) { + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.size.w , this.size.h, this.format, gl.UNSIGNED_BYTE, textureData); + } else { + // texImage2D seems to be faster, thus keeping it as the default + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.size.w, this.size.h, 0, this.format, gl.UNSIGNED_BYTE, textureData); + } + }, + bind: function(n, program, name) { + var gl = this.gl; + if (!textureIDs) { + textureIDs = [gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2]; + } + gl.activeTexture(textureIDs[n]); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.uniform1i(gl.getUniformLocation(program.program, name), n); + } +}; +module.exports = Texture; + + +},{"../utils/assert":20}],9:[function(require,module,exports){ +"use strict"; + +/** + * Generic WebGL backed canvas that sets up: a quad to paint a texture on, appropriate vertex/fragment shaders, + * scene parameters and other things. Specialized versions of this class can be created by overriding several + * initialization methods. + + */ + +var Script = require('./Script'); +var error = require('../utils/error'); +var makePerspective = require('../utils/glUtils').makePerspective; +var Matrix = require('sylvester.js').Matrix; +var Class = require('uclass'); + + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", ` + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D texture; + void main(void) { + gl_FragColor = texture2D(texture, vTextureCoord); + } +`); + +var WebGLCanvas = new Class({ + + initialize : function(canvas, size, useFrameBuffer) { + + this.canvas = canvas; + this.size = size; + this.canvas.width = size.w; + this.canvas.height = size.h; + + this.onInitWebGL(); + this.onInitShaders(); + this.initBuffers(); + + if (useFrameBuffer) + this.initFramebuffer(); + + this.onInitTextures(); + this.initScene(); + }, + + +/** + * Initialize a frame buffer so that we can render off-screen. + */ + initFramebuffer : function() { + + var gl = this.gl; + + // Create framebuffer object and texture. + this.framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + this.framebufferTexture = new Texture(this.gl, this.size, gl.RGBA); + + // Create and allocate renderbuffer for depth data. + var renderbuffer = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.size.w, this.size.h); + + // Attach texture and renderbuffer to the framebuffer. + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.framebufferTexture.texture, 0); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer); + }, + + + +/** + * Initialize vertex and texture coordinate buffers for a plane. + */ + initBuffers : function () { + var tmp; + var gl = this.gl; + + // Create vertex position buffer. + this.quadVPBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer); + tmp = [ + 1.0, 1.0, 0.0, + -1.0, 1.0, 0.0, + 1.0, -1.0, 0.0, + -1.0, -1.0, 0.0]; + + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW); + this.quadVPBuffer.itemSize = 3; + this.quadVPBuffer.numItems = 4; + + /* + +--------------------+ + | -1,1 (1) | 1,1 (0) + | | + | | + | | + | | + | | + | -1,-1 (3) | 1,-1 (2) + +--------------------+ + */ + + var scaleX = 1.0; + var scaleY = 1.0; + + // Create vertex texture coordinate buffer. + this.quadVTCBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer); + tmp = [ + scaleX, 0.0, + 0.0, 0.0, + scaleX, scaleY, + 0.0, scaleY, + ]; + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW); + }, + + + mvIdentity : function () { + this.mvMatrix = Matrix.I(4); + }, + + mvMultiply : function(m) { + this.mvMatrix = this.mvMatrix.x(m); + }, + + mvTranslate : function (m) { + this.mvMultiply(Matrix.Translation($V([m[0], m[1], m[2]])).ensure4x4()); + }, + + setMatrixUniforms : function () { + this.program.setMatrixUniform("uPMatrix", new Float32Array(this.perspectiveMatrix.flatten())); + this.program.setMatrixUniform("uMVMatrix", new Float32Array(this.mvMatrix.flatten())); + }, + + initScene : function() { + var gl = this.gl; + + // Establish the perspective with which we want to view the + // scene. Our field of view is 45 degrees, with a width/height + // ratio of 640:480, and we only want to see objects between 0.1 units + // and 100 units away from the camera. + + this.perspectiveMatrix = makePerspective(45, 1, 0.1, 100.0); + + // Set the drawing position to the "identity" point, which is + // the center of the scene. + this.mvIdentity(); + + // Now move the drawing position a bit to where we want to start + // drawing the square. + this.mvTranslate([0.0, 0.0, -2.4]); + + // Draw the cube by binding the array buffer to the cube's vertices + // array, setting attributes, and pushing it to GL. + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer); + gl.vertexAttribPointer(this.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); + + // Set the texture coordinates attribute for the vertices. + + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer); + gl.vertexAttribPointer(this.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + + this.onInitSceneTextures(); + + this.setMatrixUniforms(); + + if (this.framebuffer) { + console.log("Bound Frame Buffer"); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + } + }, + + + + toString: function() { + return "WebGLCanvas Size: " + this.size; + }, + + checkLastError: function (operation) { + var err = this.gl.getError(); + if (err != this.gl.NO_ERROR) { + var name = this.glNames[err]; + name = (name !== undefined) ? name + "(" + err + ")": + ("Unknown WebGL ENUM (0x" + value.toString(16) + ")"); + if (operation) { + console.log("WebGL Error: %s, %s", operation, name); + } else { + console.log("WebGL Error: %s", name); + } + console.trace(); + } + }, + + onInitWebGL: function () { + try { + this.gl = this.canvas.getContext("experimental-webgl"); + } catch(e) {} + + if (!this.gl) { + error("Unable to initialize WebGL. Your browser may not support it."); + } + if (this.glNames) { + return; + } + this.glNames = {}; + for (var propertyName in this.gl) { + if (typeof this.gl[propertyName] == 'number') { + this.glNames[this.gl[propertyName]] = propertyName; + } + } + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");; + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + var gl = this.gl; + this.texture = new Texture(gl, this.size, gl.RGBA); + }, + + onInitSceneTextures: function () { + this.texture.bind(0, this.program, "texture"); + }, + + drawScene: function() { + this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); + }, + + readPixels: function(buffer) { + var gl = this.gl; + gl.readPixels(0, 0, this.size.w, this.size.h, gl.RGBA, gl.UNSIGNED_BYTE, buffer); + }, + + +}); + + + +module.exports = WebGLCanvas; + +},{"../utils/error":21,"../utils/glUtils":22,"./Script":6,"sylvester.js":12,"uclass":47}],10:[function(require,module,exports){ +"use strict"; +var Class = require('uclass'); + +var YUVCanvas = new Class({ + + Binds : ['decode'], + + initialize : function(canvas, size) { + this.canvas = canvas; + this.canvasCtx = this.canvas.getContext("2d"); + this.canvasBuffer = this.canvasCtx.createImageData(size.w, size.h); + }, + + decode : function (buffer, width, height) { + if (!buffer) + return; + + var lumaSize = width * height; + var chromaSize = lumaSize >> 2; + + var ybuf = buffer.subarray(0, lumaSize); + var ubuf = buffer.subarray(lumaSize, lumaSize + chromaSize); + var vbuf = buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize); + + for (var y = 0; y < height; y++) { + for (var x = 0; x < width; x++) { + var yIndex = x + y * width; + var uIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2); + var vIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2); + var R = 1.164 * (ybuf[yIndex] - 16) + 1.596 * (vbuf[vIndex] - 128); + var G = 1.164 * (ybuf[yIndex] - 16) - 0.813 * (vbuf[vIndex] - 128) - 0.391 * (ubuf[uIndex] - 128); + var B = 1.164 * (ybuf[yIndex] - 16) + 2.018 * (ubuf[uIndex] - 128); + + var rgbIndex = yIndex * 4; + this.canvasBuffer.data[rgbIndex+0] = R; + this.canvasBuffer.data[rgbIndex+1] = G; + this.canvasBuffer.data[rgbIndex+2] = B; + this.canvasBuffer.data[rgbIndex+3] = 0xff; + } + } + + this.canvasCtx.putImageData(this.canvasBuffer, 0, 0); + + var date = new Date(); + //console.log("WSAvcPlayer: Decode time: " + (date.getTime() - this.rcvtime) + " ms"); + }, + +}); + + +module.exports = YUVCanvas; +},{"uclass":47}],11:[function(require,module,exports){ +"use strict"; + +var Program = require('./Program'); +var Shader = require('./Shader'); +var Texture = require('./Texture'); +var Script = require('./Script'); +var WebGLCanvas = require('./WebGLCanvas'); + +var Class = require('uclass'); + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", ` + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D YTexture; + uniform sampler2D UTexture; + uniform sampler2D VTexture; + const mat4 YUV2RGB = mat4 + ( + 1.1643828125, 0, 1.59602734375, -.87078515625, + 1.1643828125, -.39176171875, -.81296875, .52959375, + 1.1643828125, 2.017234375, 0, -1.081390625, + 0, 0, 0, 1 + ); + + void main(void) { + gl_FragColor = vec4( texture2D(YTexture, vTextureCoord).x, texture2D(UTexture, vTextureCoord).x, texture2D(VTexture, vTextureCoord).x, 1) * YUV2RGB; + } +`); + + + + +var YUVWebGLCanvas = new Class({ + Extends : WebGLCanvas, + Binds : ['decode'], + + initialize : function(canvas, size) { + YUVWebGLCanvas.parent.initialize.call(this, canvas, size); + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");; + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + console.log("creatingTextures: size: " + this.size); + this.YTexture = new Texture(this.gl, this.size); + this.UTexture = new Texture(this.gl, this.size.getHalfSize()); + this.VTexture = new Texture(this.gl, this.size.getHalfSize()); + }, + + onInitSceneTextures: function () { + this.YTexture.bind(0, this.program, "YTexture"); + this.UTexture.bind(1, this.program, "UTexture"); + this.VTexture.bind(2, this.program, "VTexture"); + }, + + fillYUVTextures: function(y, u, v) { + this.YTexture.fill(y); + this.UTexture.fill(u); + this.VTexture.fill(v); + }, + + decode: function(buffer, width, height) { + + if (!buffer) + return; + + var lumaSize = width * height; + var chromaSize = lumaSize >> 2; + + this.YTexture.fill(buffer.subarray(0, lumaSize)); + this.UTexture.fill(buffer.subarray(lumaSize, lumaSize + chromaSize)); + this.VTexture.fill(buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize)); + this.drawScene(); + }, + + toString: function() { + return "YUVCanvas Size: " + this.size; + } +}); + + + + + +module.exports = YUVWebGLCanvas; + +},{"./Program":5,"./Script":6,"./Shader":7,"./Texture":8,"./WebGLCanvas":9,"uclass":47}],12:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel + +var global = (Function('return this'))(); + +exports.Vector = require('./vector'); +global.$V = exports.Vector.create; +exports.Matrix = require('./matrix'); +global.$M = exports.Matrix.create; +exports.Line = require('./line'); +global.$L = exports.Line.create; +exports.Plane = require('./plane'); +global.$P = exports.Plane.create; +exports.Line.Segment = require('./line.segment'); +exports.Sylvester = require('./sylvester'); + +},{"./line":13,"./line.segment":14,"./matrix":15,"./plane":16,"./sylvester":17,"./vector":18}],13:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +var Vector = require('./vector'); +var Matrix = require('./matrix'); +var Plane = require('./plane'); +var Sylvester = require('./sylvester'); + +// Line class - depends on Vector, and some methods require Matrix and Plane. + +function Line() {} +Line.prototype = { + + // Returns true if the argument occupies the same space as the line + eql: function(line) { + return (this.isParallelTo(line) && this.contains(line.anchor)); + }, + + // Returns a copy of the line + dup: function() { + return Line.create(this.anchor, this.direction); + }, + + // Returns the result of translating the line by the given vector/array + translate: function(vector) { + var V = vector.elements || vector; + return Line.create([ + this.anchor.elements[0] + V[0], + this.anchor.elements[1] + V[1], + this.anchor.elements[2] + (V[2] || 0) + ], this.direction); + }, + + // Returns true if the line is parallel to the argument. Here, 'parallel to' + // means that the argument's direction is either parallel or antiparallel to + // the line's own direction. A line is parallel to a plane if the two do not + // have a unique intersection. + isParallelTo: function(obj) { + if (obj.normal || (obj.start && obj.end)) { return obj.isParallelTo(this); } + var theta = this.direction.angleFrom(obj.direction); + return (Math.abs(theta) <= Sylvester.precision || Math.abs(theta - Math.PI) <= Sylvester.precision); + }, + + // Returns the line's perpendicular distance from the argument, + // which can be a point, a line or a plane + distanceFrom: function(obj) { + if (obj.normal || (obj.start && obj.end)) { return obj.distanceFrom(this); } + if (obj.direction) { + // obj is a line + if (this.isParallelTo(obj)) { return this.distanceFrom(obj.anchor); } + var N = this.direction.cross(obj.direction).toUnitVector().elements; + var A = this.anchor.elements, B = obj.anchor.elements; + return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]); + } else { + // obj is a point + var P = obj.elements || obj; + var A = this.anchor.elements, D = this.direction.elements; + var PA1 = P[0] - A[0], PA2 = P[1] - A[1], PA3 = (P[2] || 0) - A[2]; + var modPA = Math.sqrt(PA1*PA1 + PA2*PA2 + PA3*PA3); + if (modPA === 0) return 0; + // Assumes direction vector is normalized + var cosTheta = (PA1 * D[0] + PA2 * D[1] + PA3 * D[2]) / modPA; + var sin2 = 1 - cosTheta*cosTheta; + return Math.abs(modPA * Math.sqrt(sin2 < 0 ? 0 : sin2)); + } + }, + + // Returns true iff the argument is a point on the line, or if the argument + // is a line segment lying within the receiver + contains: function(obj) { + if (obj.start && obj.end) { return this.contains(obj.start) && this.contains(obj.end); } + var dist = this.distanceFrom(obj); + return (dist !== null && dist <= Sylvester.precision); + }, + + // Returns the distance from the anchor of the given point. Negative values are + // returned for points that are in the opposite direction to the line's direction from + // the line's anchor point. + positionOf: function(point) { + if (!this.contains(point)) { return null; } + var P = point.elements || point; + var A = this.anchor.elements, D = this.direction.elements; + return (P[0] - A[0]) * D[0] + (P[1] - A[1]) * D[1] + ((P[2] || 0) - A[2]) * D[2]; + }, + + // Returns true iff the line lies in the given plane + liesIn: function(plane) { + return plane.contains(this); + }, + + // Returns true iff the line has a unique point of intersection with the argument + intersects: function(obj) { + if (obj.normal) { return obj.intersects(this); } + return (!this.isParallelTo(obj) && this.distanceFrom(obj) <= Sylvester.precision); + }, + + // Returns the unique intersection point with the argument, if one exists + intersectionWith: function(obj) { + if (obj.normal || (obj.start && obj.end)) { return obj.intersectionWith(this); } + if (!this.intersects(obj)) { return null; } + var P = this.anchor.elements, X = this.direction.elements, + Q = obj.anchor.elements, Y = obj.direction.elements; + var X1 = X[0], X2 = X[1], X3 = X[2], Y1 = Y[0], Y2 = Y[1], Y3 = Y[2]; + var PsubQ1 = P[0] - Q[0], PsubQ2 = P[1] - Q[1], PsubQ3 = P[2] - Q[2]; + var XdotQsubP = - X1*PsubQ1 - X2*PsubQ2 - X3*PsubQ3; + var YdotPsubQ = Y1*PsubQ1 + Y2*PsubQ2 + Y3*PsubQ3; + var XdotX = X1*X1 + X2*X2 + X3*X3; + var YdotY = Y1*Y1 + Y2*Y2 + Y3*Y3; + var XdotY = X1*Y1 + X2*Y2 + X3*Y3; + var k = (XdotQsubP * YdotY / XdotX + XdotY * YdotPsubQ) / (YdotY - XdotY * XdotY); + return Vector.create([P[0] + k*X1, P[1] + k*X2, P[2] + k*X3]); + }, + + // Returns the point on the line that is closest to the given point or line/line segment + pointClosestTo: function(obj) { + if (obj.start && obj.end) { + // obj is a line segment + var P = obj.pointClosestTo(this); + return (P === null) ? null : this.pointClosestTo(P); + } else if (obj.direction) { + // obj is a line + if (this.intersects(obj)) { return this.intersectionWith(obj); } + if (this.isParallelTo(obj)) { return null; } + var D = this.direction.elements, E = obj.direction.elements; + var D1 = D[0], D2 = D[1], D3 = D[2], E1 = E[0], E2 = E[1], E3 = E[2]; + // Create plane containing obj and the shared normal and intersect this with it + // Thank you: http://www.cgafaq.info/wiki/Line-line_distance + var x = (D3 * E1 - D1 * E3), y = (D1 * E2 - D2 * E1), z = (D2 * E3 - D3 * E2); + var N = [x * E3 - y * E2, y * E1 - z * E3, z * E2 - x * E1]; + var P = Plane.create(obj.anchor, N); + return P.intersectionWith(this); + } else { + // obj is a point + var P = obj.elements || obj; + if (this.contains(P)) { return Vector.create(P); } + var A = this.anchor.elements, D = this.direction.elements; + var D1 = D[0], D2 = D[1], D3 = D[2], A1 = A[0], A2 = A[1], A3 = A[2]; + var x = D1 * (P[1]-A2) - D2 * (P[0]-A1), y = D2 * ((P[2] || 0) - A3) - D3 * (P[1]-A2), + z = D3 * (P[0]-A1) - D1 * ((P[2] || 0) - A3); + var V = Vector.create([D2 * x - D3 * z, D3 * y - D1 * x, D1 * z - D2 * y]); + var k = this.distanceFrom(P) / V.modulus(); + return Vector.create([ + P[0] + V.elements[0] * k, + P[1] + V.elements[1] * k, + (P[2] || 0) + V.elements[2] * k + ]); + } + }, + + // Returns a copy of the line rotated by t radians about the given line. Works by + // finding the argument's closest point to this line's anchor point (call this C) and + // rotating the anchor about C. Also rotates the line's direction about the argument's. + // Be careful with this - the rotation axis' direction affects the outcome! + rotate: function(t, line) { + // If we're working in 2D + if (typeof(line.direction) == 'undefined') { line = Line.create(line.to3D(), Vector.k); } + var R = Matrix.Rotation(t, line.direction).elements; + var C = line.pointClosestTo(this.anchor).elements; + var A = this.anchor.elements, D = this.direction.elements; + var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2]; + var x = A1 - C1, y = A2 - C2, z = A3 - C3; + return Line.create([ + C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z, + C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z, + C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z + ], [ + R[0][0] * D[0] + R[0][1] * D[1] + R[0][2] * D[2], + R[1][0] * D[0] + R[1][1] * D[1] + R[1][2] * D[2], + R[2][0] * D[0] + R[2][1] * D[1] + R[2][2] * D[2] + ]); + }, + + // Returns a copy of the line with its direction vector reversed. + // Useful when using lines for rotations. + reverse: function() { + return Line.create(this.anchor, this.direction.x(-1)); + }, + + // Returns the line's reflection in the given point or line + reflectionIn: function(obj) { + if (obj.normal) { + // obj is a plane + var A = this.anchor.elements, D = this.direction.elements; + var A1 = A[0], A2 = A[1], A3 = A[2], D1 = D[0], D2 = D[1], D3 = D[2]; + var newA = this.anchor.reflectionIn(obj).elements; + // Add the line's direction vector to its anchor, then mirror that in the plane + var AD1 = A1 + D1, AD2 = A2 + D2, AD3 = A3 + D3; + var Q = obj.pointClosestTo([AD1, AD2, AD3]).elements; + var newD = [Q[0] + (Q[0] - AD1) - newA[0], Q[1] + (Q[1] - AD2) - newA[1], Q[2] + (Q[2] - AD3) - newA[2]]; + return Line.create(newA, newD); + } else if (obj.direction) { + // obj is a line - reflection obtained by rotating PI radians about obj + return this.rotate(Math.PI, obj); + } else { + // obj is a point - just reflect the line's anchor in it + var P = obj.elements || obj; + return Line.create(this.anchor.reflectionIn([P[0], P[1], (P[2] || 0)]), this.direction); + } + }, + + // Set the line's anchor point and direction. + setVectors: function(anchor, direction) { + // Need to do this so that line's properties are not + // references to the arguments passed in + anchor = Vector.create(anchor); + direction = Vector.create(direction); + if (anchor.elements.length == 2) {anchor.elements.push(0); } + if (direction.elements.length == 2) { direction.elements.push(0); } + if (anchor.elements.length > 3 || direction.elements.length > 3) { return null; } + var mod = direction.modulus(); + if (mod === 0) { return null; } + this.anchor = anchor; + this.direction = Vector.create([ + direction.elements[0] / mod, + direction.elements[1] / mod, + direction.elements[2] / mod + ]); + return this; + } +}; + +// Constructor function +Line.create = function(anchor, direction) { + var L = new Line(); + return L.setVectors(anchor, direction); +}; + +// Axes +Line.X = Line.create(Vector.Zero(3), Vector.i); +Line.Y = Line.create(Vector.Zero(3), Vector.j); +Line.Z = Line.create(Vector.Zero(3), Vector.k); + +module.exports = Line; + +},{"./matrix":15,"./plane":16,"./sylvester":17,"./vector":18}],14:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// Line.Segment class - depends on Line and its dependencies. + +var Line = require('./line'); +var Vector = require('./vector'); + +Line.Segment = function() {}; +Line.Segment.prototype = { + + // Returns true iff the line segment is equal to the argument + eql: function(segment) { + return (this.start.eql(segment.start) && this.end.eql(segment.end)) || + (this.start.eql(segment.end) && this.end.eql(segment.start)); + }, + + // Returns a copy of the line segment + dup: function() { + return Line.Segment.create(this.start, this.end); + }, + + // Returns the length of the line segment + length: function() { + var A = this.start.elements, B = this.end.elements; + var C1 = B[0] - A[0], C2 = B[1] - A[1], C3 = B[2] - A[2]; + return Math.sqrt(C1*C1 + C2*C2 + C3*C3); + }, + + // Returns the line segment as a vector equal to its + // end point relative to its endpoint + toVector: function() { + var A = this.start.elements, B = this.end.elements; + return Vector.create([B[0] - A[0], B[1] - A[1], B[2] - A[2]]); + }, + + // Returns the segment's midpoint as a vector + midpoint: function() { + var A = this.start.elements, B = this.end.elements; + return Vector.create([(B[0] + A[0])/2, (B[1] + A[1])/2, (B[2] + A[2])/2]); + }, + + // Returns the plane that bisects the segment + bisectingPlane: function() { + return Plane.create(this.midpoint(), this.toVector()); + }, + + // Returns the result of translating the line by the given vector/array + translate: function(vector) { + var V = vector.elements || vector; + var S = this.start.elements, E = this.end.elements; + return Line.Segment.create( + [S[0] + V[0], S[1] + V[1], S[2] + (V[2] || 0)], + [E[0] + V[0], E[1] + V[1], E[2] + (V[2] || 0)] + ); + }, + + // Returns true iff the line segment is parallel to the argument. It simply forwards + // the method call onto its line property. + isParallelTo: function(obj) { + return this.line.isParallelTo(obj); + }, + + // Returns the distance between the argument and the line segment's closest point to the argument + distanceFrom: function(obj) { + var P = this.pointClosestTo(obj); + return (P === null) ? null : P.distanceFrom(obj); + }, + + // Returns true iff the given point lies on the segment + contains: function(obj) { + if (obj.start && obj.end) { return this.contains(obj.start) && this.contains(obj.end); } + var P = (obj.elements || obj).slice(); + if (P.length == 2) { P.push(0); } + if (this.start.eql(P)) { return true; } + var S = this.start.elements; + var V = Vector.create([S[0] - P[0], S[1] - P[1], S[2] - (P[2] || 0)]); + var vect = this.toVector(); + return V.isAntiparallelTo(vect) && V.modulus() <= vect.modulus(); + }, + + // Returns true iff the line segment intersects the argument + intersects: function(obj) { + return (this.intersectionWith(obj) !== null); + }, + + // Returns the unique point of intersection with the argument + intersectionWith: function(obj) { + if (!this.line.intersects(obj)) { return null; } + var P = this.line.intersectionWith(obj); + return (this.contains(P) ? P : null); + }, + + // Returns the point on the line segment closest to the given object + pointClosestTo: function(obj) { + if (obj.normal) { + // obj is a plane + var V = this.line.intersectionWith(obj); + if (V === null) { return null; } + return this.pointClosestTo(V); + } else { + // obj is a line (segment) or point + var P = this.line.pointClosestTo(obj); + if (P === null) { return null; } + if (this.contains(P)) { return P; } + return (this.line.positionOf(P) < 0 ? this.start : this.end).dup(); + } + }, + + // Set the start and end-points of the segment + setPoints: function(startPoint, endPoint) { + startPoint = Vector.create(startPoint).to3D(); + endPoint = Vector.create(endPoint).to3D(); + if (startPoint === null || endPoint === null) { return null; } + this.line = Line.create(startPoint, endPoint.subtract(startPoint)); + this.start = startPoint; + this.end = endPoint; + return this; + } +}; + +// Constructor function +Line.Segment.create = function(v1, v2) { + var S = new Line.Segment(); + return S.setPoints(v1, v2); +}; + +module.exports = Line.Segment; + +},{"./line":13,"./vector":18}],15:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// Matrix class - depends on Vector. + +var Sylvester = require('./sylvester'); +var Vector = require('./vector'); + +// augment a matrix M with identity rows/cols +function identSize(M, m, n, k) { + var e = M.elements; + var i = k - 1; + + while(i--) { + var row = []; + + for(var j = 0; j < n; j++) + row.push(j == i ? 1 : 0); + + e.unshift(row); + } + + for(var i = k - 1; i < m; i++) { + while(e[i].length < n) + e[i].unshift(0); + } + + return $M(e); +} + +function pca(X) { + var Sigma = X.transpose().x(X).x(1 / X.rows()); + var svd = Sigma.svd(); + return {U: svd.U, S: svd.S}; +} + +// singular value decomposition in pure javascript +function svdJs() { + var A = this; + var V = Matrix.I(A.rows()); + var S = A.transpose(); + var U = Matrix.I(A.cols()); + var err = Number.MAX_VALUE; + var i = 0; + var maxLoop = 100; + + while(err > 2.2737e-13 && i < maxLoop) { + var qr = S.transpose().qrJs(); + S = qr.R; + V = V.x(qr.Q); + qr = S.transpose().qrJs(); + U = U.x(qr.Q); + S = qr.R; + + var e = S.triu(1).unroll().norm(); + var f = S.diagonal().norm(); + + if(f == 0) + f = 1; + + err = e / f; + + i++; + } + + var ss = S.diagonal(); + var s = []; + + for(var i = 1; i <= ss.cols(); i++) { + var ssn = ss.e(i); + s.push(Math.abs(ssn)); + + if(ssn < 0) { + for(var j = 0; j < U.rows(); j++) { + V.elements[j][i - 1] = -(V.elements[j][i - 1]); + } + } + } + + return {U: U, S: $V(s).toDiagonalMatrix(), V: V}; +} + + + +// QR decomposition in pure javascript +function qrJs() { + var m = this.rows(); + var n = this.cols(); + var Q = Matrix.I(m); + var A = this; + + for(var k = 1; k < Math.min(m, n); k++) { + var ak = A.slice(k, 0, k, k).col(1); + var oneZero = [1]; + + while(oneZero.length <= m - k) + oneZero.push(0); + + oneZero = $V(oneZero); + var vk = ak.add(oneZero.x(ak.norm() * Math.sign(ak.e(1)))); + var Vk = $M(vk); + var Hk = Matrix.I(m - k + 1).subtract(Vk.x(2).x(Vk.transpose()).div(Vk.transpose().x(Vk).e(1, 1))); + var Qk = identSize(Hk, m, n, k); + A = Qk.x(A); + // slow way to compute Q + Q = Q.x(Qk); + } + + return {Q: Q, R: A}; +} + + + + +function Matrix() {} +Matrix.prototype = { + // solve a system of linear equations (work in progress) + solve: function(b) { + var lu = this.lu(); + b = lu.P.x(b); + var y = lu.L.forwardSubstitute(b); + var x = lu.U.backSubstitute(y); + return lu.P.x(x); + //return this.inv().x(b); + }, + + // project a matrix onto a lower dim + pcaProject: function(k, U) { + var U = U || pca(this).U; + var Ureduce= U.slice(1, U.rows(), 1, k); + return {Z: this.x(Ureduce), U: U}; + }, + + // recover a matrix to a higher dimension + pcaRecover: function(U) { + var k = this.cols(); + var Ureduce = U.slice(1, U.rows(), 1, k); + return this.x(Ureduce.transpose()); + }, + + // grab the upper triangular part of the matrix + triu: function(k) { + if(!k) + k = 0; + + return this.map(function(x, i, j) { + return j - i >= k ? x : 0; + }); + }, + + // unroll a matrix into a vector + unroll: function() { + var v = []; + + for(var i = 1; i <= this.cols(); i++) { + for(var j = 1; j <= this.rows(); j++) { + v.push(this.e(j, i)); + } + } + + return $V(v); + }, + + // return a sub-block of the matrix + slice: function(startRow, endRow, startCol, endCol) { + var x = []; + + if(endRow == 0) + endRow = this.rows(); + + if(endCol == 0) + endCol = this.cols(); + + for(i = startRow; i <= endRow; i++) { + var row = []; + + for(j = startCol; j <= endCol; j++) { + row.push(this.e(i, j)); + } + + x.push(row); + } + + return $M(x); + }, + + // Returns element (i,j) of the matrix + e: function(i,j) { + if (i < 1 || i > this.elements.length || j < 1 || j > this.elements[0].length) { return null; } + return this.elements[i - 1][j - 1]; + }, + + // Returns row k of the matrix as a vector + row: function(i) { + if (i > this.elements.length) { return null; } + return $V(this.elements[i - 1]); + }, + + // Returns column k of the matrix as a vector + col: function(j) { + if (j > this.elements[0].length) { return null; } + var col = [], n = this.elements.length; + for (var i = 0; i < n; i++) { col.push(this.elements[i][j - 1]); } + return $V(col); + }, + + // Returns the number of rows/columns the matrix has + dimensions: function() { + return {rows: this.elements.length, cols: this.elements[0].length}; + }, + + // Returns the number of rows in the matrix + rows: function() { + return this.elements.length; + }, + + // Returns the number of columns in the matrix + cols: function() { + return this.elements[0].length; + }, + + approxEql: function(matrix) { + return this.eql(matrix, Sylvester.approxPrecision); + }, + + // Returns true iff the matrix is equal to the argument. You can supply + // a vector as the argument, in which case the receiver must be a + // one-column matrix equal to the vector. + eql: function(matrix, precision) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + if (this.elements.length != M.length || + this.elements[0].length != M[0].length) { return false; } + var i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { j = nj; + while (j--) { + if (Math.abs(this.elements[i][j] - M[i][j]) > (precision || Sylvester.precision)) { return false; } + } + } + return true; + }, + + // Returns a copy of the matrix + dup: function() { + return Matrix.create(this.elements); + }, + + // Maps the matrix to another matrix (of the same dimensions) according to the given function + map: function(fn) { + var els = [], i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { j = nj; + els[i] = []; + while (j--) { + els[i][j] = fn(this.elements[i][j], i + 1, j + 1); + } + } + return Matrix.create(els); + }, + + // Returns true iff the argument has the same dimensions as the matrix + isSameSizeAs: function(matrix) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + return (this.elements.length == M.length && + this.elements[0].length == M[0].length); + }, + + // Returns the result of adding the argument to the matrix + add: function(matrix) { + if(typeof(matrix) == 'number') { + return this.map(function(x, i, j) { return x + matrix}); + } else { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + if (!this.isSameSizeAs(M)) { return null; } + return this.map(function(x, i, j) { return x + M[i - 1][j - 1]; }); + } + }, + + // Returns the result of subtracting the argument from the matrix + subtract: function(matrix) { + if(typeof(matrix) == 'number') { + return this.map(function(x, i, j) { return x - matrix}); + } else { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + if (!this.isSameSizeAs(M)) { return null; } + return this.map(function(x, i, j) { return x - M[i - 1][j - 1]; }); + } + }, + + // Returns true iff the matrix can multiply the argument from the left + canMultiplyFromLeft: function(matrix) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + // this.columns should equal matrix.rows + return (this.elements[0].length == M.length); + }, + + // Returns the result of a multiplication-style operation the matrix from the right by the argument. + // If the argument is a scalar then just operate on all the elements. If the argument is + // a vector, a vector is returned, which saves you having to remember calling + // col(1) on the result. + mulOp: function(matrix, op) { + if (!matrix.elements) { + return this.map(function(x) { return op(x, matrix); }); + } + + var returnVector = matrix.modulus ? true : false; + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') + M = Matrix.create(M).elements; + if (!this.canMultiplyFromLeft(M)) + return null; + var e = this.elements, rowThis, rowElem, elements = [], + sum, m = e.length, n = M[0].length, o = e[0].length, i = m, j, k; + + while (i--) { + rowElem = []; + rowThis = e[i]; + j = n; + + while (j--) { + sum = 0; + k = o; + + while (k--) { + sum += op(rowThis[k], M[k][j]); + } + + rowElem[j] = sum; + } + + elements[i] = rowElem; + } + + var M = Matrix.create(elements); + return returnVector ? M.col(1) : M; + }, + + // Returns the result of dividing the matrix from the right by the argument. + // If the argument is a scalar then just divide all the elements. If the argument is + // a vector, a vector is returned, which saves you having to remember calling + // col(1) on the result. + div: function(matrix) { + return this.mulOp(matrix, function(x, y) { return x / y}); + }, + + // Returns the result of multiplying the matrix from the right by the argument. + // If the argument is a scalar then just multiply all the elements. If the argument is + // a vector, a vector is returned, which saves you having to remember calling + // col(1) on the result. + multiply: function(matrix) { + return this.mulOp(matrix, function(x, y) { return x * y}); + }, + + x: function(matrix) { return this.multiply(matrix); }, + + elementMultiply: function(v) { + return this.map(function(k, i, j) { + return v.e(i, j) * k; + }); + }, + + // sum all elements in the matrix + sum: function() { + var sum = 0; + + this.map(function(x) { sum += x;}); + + return sum; + }, + + // Returns a Vector of each colum averaged. + mean: function() { + var dim = this.dimensions(); + var r = []; + for (var i = 1; i <= dim.cols; i++) { + r.push(this.col(i).sum() / dim.rows); + } + return $V(r); + }, + + column: function(n) { + return this.col(n); + }, + + // element-wise log + log: function() { + return this.map(function(x) { return Math.log(x); }); + }, + + // Returns a submatrix taken from the matrix + // Argument order is: start row, start col, nrows, ncols + // Element selection wraps if the required index is outside the matrix's bounds, so you could + // use this to perform row/column cycling or copy-augmenting. + minor: function(a, b, c, d) { + var elements = [], ni = c, i, nj, j; + var rows = this.elements.length, cols = this.elements[0].length; + while (ni--) { + i = c - ni - 1; + elements[i] = []; + nj = d; + while (nj--) { + j = d - nj - 1; + elements[i][j] = this.elements[(a + i - 1) % rows][(b + j - 1) % cols]; + } + } + return Matrix.create(elements); + }, + + // Returns the transpose of the matrix + transpose: function() { + var rows = this.elements.length, i, cols = this.elements[0].length, j; + var elements = [], i = cols; + while (i--) { + j = rows; + elements[i] = []; + while (j--) { + elements[i][j] = this.elements[j][i]; + } + } + return Matrix.create(elements); + }, + + // Returns true iff the matrix is square + isSquare: function() { + return (this.elements.length == this.elements[0].length); + }, + + // Returns the (absolute) largest element of the matrix + max: function() { + var m = 0, i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { + j = nj; + while (j--) { + if (Math.abs(this.elements[i][j]) > Math.abs(m)) { m = this.elements[i][j]; } + } + } + return m; + }, + + // Returns the indeces of the first match found by reading row-by-row from left to right + indexOf: function(x) { + var index = null, ni = this.elements.length, i, nj = this.elements[0].length, j; + for (i = 0; i < ni; i++) { + for (j = 0; j < nj; j++) { + if (this.elements[i][j] == x) { return {i: i + 1, j: j + 1}; } + } + } + return null; + }, + + // If the matrix is square, returns the diagonal elements as a vector. + // Otherwise, returns null. + diagonal: function() { + if (!this.isSquare) { return null; } + var els = [], n = this.elements.length; + for (var i = 0; i < n; i++) { + els.push(this.elements[i][i]); + } + return $V(els); + }, + + // Make the matrix upper (right) triangular by Gaussian elimination. + // This method only adds multiples of rows to other rows. No rows are + // scaled up or switched, and the determinant is preserved. + toRightTriangular: function() { + var M = this.dup(), els; + var n = this.elements.length, i, j, np = this.elements[0].length, p; + for (i = 0; i < n; i++) { + if (M.elements[i][i] == 0) { + for (j = i + 1; j < n; j++) { + if (M.elements[j][i] != 0) { + els = []; + for (p = 0; p < np; p++) { els.push(M.elements[i][p] + M.elements[j][p]); } + M.elements[i] = els; + break; + } + } + } + if (M.elements[i][i] != 0) { + for (j = i + 1; j < n; j++) { + var multiplier = M.elements[j][i] / M.elements[i][i]; + els = []; + for (p = 0; p < np; p++) { + // Elements with column numbers up to an including the number + // of the row that we're subtracting can safely be set straight to + // zero, since that's the point of this routine and it avoids having + // to loop over and correct rounding errors later + els.push(p <= i ? 0 : M.elements[j][p] - M.elements[i][p] * multiplier); + } + M.elements[j] = els; + } + } + } + return M; + }, + + toUpperTriangular: function() { return this.toRightTriangular(); }, + + // Returns the determinant for square matrices + determinant: function() { + if (!this.isSquare()) { return null; } + if (this.cols == 1 && this.rows == 1) { return this.row(1); } + if (this.cols == 0 && this.rows == 0) { return 1; } + var M = this.toRightTriangular(); + var det = M.elements[0][0], n = M.elements.length; + for (var i = 1; i < n; i++) { + det = det * M.elements[i][i]; + } + return det; + }, + det: function() { return this.determinant(); }, + + // Returns true iff the matrix is singular + isSingular: function() { + return (this.isSquare() && this.determinant() === 0); + }, + + // Returns the trace for square matrices + trace: function() { + if (!this.isSquare()) { return null; } + var tr = this.elements[0][0], n = this.elements.length; + for (var i = 1; i < n; i++) { + tr += this.elements[i][i]; + } + return tr; + }, + + tr: function() { return this.trace(); }, + + // Returns the rank of the matrix + rank: function() { + var M = this.toRightTriangular(), rank = 0; + var i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { + j = nj; + while (j--) { + if (Math.abs(M.elements[i][j]) > Sylvester.precision) { rank++; break; } + } + } + return rank; + }, + + rk: function() { return this.rank(); }, + + // Returns the result of attaching the given argument to the right-hand side of the matrix + augment: function(matrix) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + var T = this.dup(), cols = T.elements[0].length; + var i = T.elements.length, nj = M[0].length, j; + if (i != M.length) { return null; } + while (i--) { + j = nj; + while (j--) { + T.elements[i][cols + j] = M[i][j]; + } + } + return T; + }, + + // Returns the inverse (if one exists) using Gauss-Jordan + inverse: function() { + if (!this.isSquare() || this.isSingular()) { return null; } + var n = this.elements.length, i = n, j; + var M = this.augment(Matrix.I(n)).toRightTriangular(); + var np = M.elements[0].length, p, els, divisor; + var inverse_elements = [], new_element; + // Matrix is non-singular so there will be no zeros on the diagonal + // Cycle through rows from last to first + while (i--) { + // First, normalise diagonal elements to 1 + els = []; + inverse_elements[i] = []; + divisor = M.elements[i][i]; + for (p = 0; p < np; p++) { + new_element = M.elements[i][p] / divisor; + els.push(new_element); + // Shuffle off the current row of the right hand side into the results + // array as it will not be modified by later runs through this loop + if (p >= n) { inverse_elements[i].push(new_element); } + } + M.elements[i] = els; + // Then, subtract this row from those above it to + // give the identity matrix on the left hand side + j = i; + while (j--) { + els = []; + for (p = 0; p < np; p++) { + els.push(M.elements[j][p] - M.elements[i][p] * M.elements[j][i]); + } + M.elements[j] = els; + } + } + return Matrix.create(inverse_elements); + }, + + inv: function() { return this.inverse(); }, + + // Returns the result of rounding all the elements + round: function() { + return this.map(function(x) { return Math.round(x); }); + }, + + // Returns a copy of the matrix with elements set to the given value if they + // differ from it by less than Sylvester.precision + snapTo: function(x) { + return this.map(function(p) { + return (Math.abs(p - x) <= Sylvester.precision) ? x : p; + }); + }, + + // Returns a string representation of the matrix + inspect: function() { + var matrix_rows = []; + var n = this.elements.length; + for (var i = 0; i < n; i++) { + matrix_rows.push($V(this.elements[i]).inspect()); + } + return matrix_rows.join('\n'); + }, + + // Returns a array representation of the matrix + toArray: function() { + var matrix_rows = []; + var n = this.elements.length; + for (var i = 0; i < n; i++) { + matrix_rows.push(this.elements[i]); + } + return matrix_rows; + }, + + + // Set the matrix's elements from an array. If the argument passed + // is a vector, the resulting matrix will be a single column. + setElements: function(els) { + var i, j, elements = els.elements || els; + if (typeof(elements[0][0]) != 'undefined') { + i = elements.length; + this.elements = []; + while (i--) { + j = elements[i].length; + this.elements[i] = []; + while (j--) { + this.elements[i][j] = elements[i][j]; + } + } + return this; + } + var n = elements.length; + this.elements = []; + for (i = 0; i < n; i++) { + this.elements.push([elements[i]]); + } + return this; + }, + + // return the indexes of the columns with the largest value + // for each row + maxColumnIndexes: function() { + var maxes = []; + + for(var i = 1; i <= this.rows(); i++) { + var max = null; + var maxIndex = -1; + + for(var j = 1; j <= this.cols(); j++) { + if(max === null || this.e(i, j) > max) { + max = this.e(i, j); + maxIndex = j; + } + } + + maxes.push(maxIndex); + } + + return $V(maxes); + }, + + // return the largest values in each row + maxColumns: function() { + var maxes = []; + + for(var i = 1; i <= this.rows(); i++) { + var max = null; + + for(var j = 1; j <= this.cols(); j++) { + if(max === null || this.e(i, j) > max) { + max = this.e(i, j); + } + } + + maxes.push(max); + } + + return $V(maxes); + }, + + // return the indexes of the columns with the smallest values + // for each row + minColumnIndexes: function() { + var mins = []; + + for(var i = 1; i <= this.rows(); i++) { + var min = null; + var minIndex = -1; + + for(var j = 1; j <= this.cols(); j++) { + if(min === null || this.e(i, j) < min) { + min = this.e(i, j); + minIndex = j; + } + } + + mins.push(minIndex); + } + + return $V(mins); + }, + + // return the smallest values in each row + minColumns: function() { + var mins = []; + + for(var i = 1; i <= this.rows(); i++) { + var min = null; + + for(var j = 1; j <= this.cols(); j++) { + if(min === null || this.e(i, j) < min) { + min = this.e(i, j); + } + } + + mins.push(min); + } + + return $V(mins); + }, + + // perorm a partial pivot on the matrix. essentially move the largest + // row below-or-including the pivot and replace the pivot's row with it. + // a pivot matrix is returned so multiplication can perform the transform. + partialPivot: function(k, j, P, A, L) { + var maxIndex = 0; + var maxValue = 0; + + for(var i = k; i <= A.rows(); i++) { + if(Math.abs(A.e(i, j)) > maxValue) { + maxValue = Math.abs(A.e(k, j)); + maxIndex = i; + } + } + + if(maxIndex != k) { + var tmp = A.elements[k - 1]; + A.elements[k - 1] = A.elements[maxIndex - 1]; + A.elements[maxIndex - 1] = tmp; + + P.elements[k - 1][k - 1] = 0; + P.elements[k - 1][maxIndex - 1] = 1; + P.elements[maxIndex - 1][maxIndex - 1] = 0; + P.elements[maxIndex - 1][k - 1] = 1; + } + + return P; + }, + + // solve lower-triangular matrix * x = b via forward substitution + forwardSubstitute: function(b) { + var xa = []; + + for(var i = 1; i <= this.rows(); i++) { + var w = 0; + + for(var j = 1; j < i; j++) { + w += this.e(i, j) * xa[j - 1]; + } + + xa.push((b.e(i) - w) / this.e(i, i)); + } + + return $V(xa); + }, + + // solve an upper-triangular matrix * x = b via back substitution + backSubstitute: function(b) { + var xa = []; + + for(var i = this.rows(); i > 0; i--) { + var w = 0; + + for(var j = this.cols(); j > i; j--) { + w += this.e(i, j) * xa[this.rows() - j]; + } + + xa.push((b.e(i) - w) / this.e(i, i)); + } + + return $V(xa.reverse()); + }, + + luJs: luJs, + svdJs: svdJs, + qrJs: qrJs, +}; + + +var tolerance = 1.4901e-08; + +// pure Javascript LU factorization +function luJs() { + var A = this.dup(); + var L = Matrix.I(A.rows()); + var P = Matrix.I(A.rows()); + var U = Matrix.Zeros(A.rows(), A.cols()); + var p = 1; + + for(var k = 1; k <= Math.min(A.cols(), A.rows()); k++) { + P = A.partialPivot(k, p, P, A, L); + + for(var i = k + 1; i <= A.rows(); i++) { + var l = A.e(i, p) / A.e(k, p); + L.elements[i - 1][k - 1] = l; + + for(var j = k + 1 ; j <= A.cols(); j++) { + A.elements[i - 1][j - 1] -= A.e(k, j) * l; + } + } + + for(var j = k; j <= A.cols(); j++) { + U.elements[k - 1][j - 1] = A.e(k, j); + } + + if(p < A.cols()) + p++; + } + + return {L: L, U: U, P: P}; +} + + + +Matrix.prototype.svd = svdJs; +Matrix.prototype.qr = qrJs; +Matrix.prototype.lu = luJs; + +// Constructor function +Matrix.create = function(aElements) { + var M = new Matrix().setElements(aElements); + return M; +}; + +// Identity matrix of size n +Matrix.I = function(n) { + var els = [], i = n, j; + while (i--) { + j = n; + els[i] = []; + while (j--) { + els[i][j] = (i == j) ? 1 : 0; + } + } + return Matrix.create(els); +}; + +Matrix.loadFile = function(file) { + var fs = require('fs'); + var contents = fs.readFileSync(file, 'utf-8'); + var matrix = []; + + var rowArray = contents.split('\n'); + for (var i = 0; i < rowArray.length; i++) { + var d = rowArray[i].split(','); + if (d.length > 1) { + matrix.push(d); + } + } + + var M = new Matrix(); + return M.setElements(matrix); +}; + +// Diagonal matrix - all off-diagonal elements are zero +Matrix.Diagonal = function(elements) { + var i = elements.length; + var M = Matrix.I(i); + while (i--) { + M.elements[i][i] = elements[i]; + } + return M; +}; + +// Rotation matrix about some axis. If no axis is +// supplied, assume we're after a 2D transform +Matrix.Rotation = function(theta, a) { + if (!a) { + return Matrix.create([ + [Math.cos(theta), -Math.sin(theta)], + [Math.sin(theta), Math.cos(theta)] + ]); + } + var axis = a.dup(); + if (axis.elements.length != 3) { return null; } + var mod = axis.modulus(); + var x = axis.elements[0] / mod, y = axis.elements[1] / mod, z = axis.elements[2] / mod; + var s = Math.sin(theta), c = Math.cos(theta), t = 1 - c; + // Formula derived here: http://www.gamedev.net/reference/articles/article1199.asp + // That proof rotates the co-ordinate system so theta + // becomes -theta and sin becomes -sin here. + return Matrix.create([ + [t * x * x + c, t * x * y - s * z, t * x * z + s * y], + [t * x * y + s * z, t * y * y + c, t * y * z - s * x], + [t * x * z - s * y, t * y * z + s * x, t * z * z + c] + ]); +}; + +// Special case rotations +Matrix.RotationX = function(t) { + var c = Math.cos(t), s = Math.sin(t); + return Matrix.create([ + [1, 0, 0], + [0, c, -s], + [0, s, c] + ]); +}; + +Matrix.RotationY = function(t) { + var c = Math.cos(t), s = Math.sin(t); + return Matrix.create([ + [c, 0, s], + [0, 1, 0], + [-s, 0, c] + ]); +}; + +Matrix.RotationZ = function(t) { + var c = Math.cos(t), s = Math.sin(t); + return Matrix.create([ + [c, -s, 0], + [s, c, 0], + [0, 0, 1] + ]); +}; + +// Random matrix of n rows, m columns +Matrix.Random = function(n, m) { + if (arguments.length === 1) m = n; + return Matrix.Zero(n, m).map( + function() { return Math.random(); } + ); +}; + +Matrix.Fill = function(n, m, v) { + if (arguments.length === 2) { + v = m; + m = n; + } + + var els = [], i = n, j; + + while (i--) { + j = m; + els[i] = []; + + while (j--) { + els[i][j] = v; + } + } + + return Matrix.create(els); +}; + +// Matrix filled with zeros +Matrix.Zero = function(n, m) { + return Matrix.Fill(n, m, 0); +}; + +// Matrix filled with zeros +Matrix.Zeros = function(n, m) { + return Matrix.Zero(n, m); +}; + +// Matrix filled with ones +Matrix.One = function(n, m) { + return Matrix.Fill(n, m, 1); +}; + +// Matrix filled with ones +Matrix.Ones = function(n, m) { + return Matrix.One(n, m); +}; + +module.exports = Matrix; + +},{"./sylvester":17,"./vector":18,"fs":undefined}],16:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// Plane class - depends on Vector. Some methods require Matrix and Line. +var Vector = require('./vector'); +var Matrix = require('./matrix'); +var Line = require('./line'); + +var Sylvester = require('./sylvester'); + +function Plane() {} +Plane.prototype = { + + // Returns true iff the plane occupies the same space as the argument + eql: function(plane) { + return (this.contains(plane.anchor) && this.isParallelTo(plane)); + }, + + // Returns a copy of the plane + dup: function() { + return Plane.create(this.anchor, this.normal); + }, + + // Returns the result of translating the plane by the given vector + translate: function(vector) { + var V = vector.elements || vector; + return Plane.create([ + this.anchor.elements[0] + V[0], + this.anchor.elements[1] + V[1], + this.anchor.elements[2] + (V[2] || 0) + ], this.normal); + }, + + // Returns true iff the plane is parallel to the argument. Will return true + // if the planes are equal, or if you give a line and it lies in the plane. + isParallelTo: function(obj) { + var theta; + if (obj.normal) { + // obj is a plane + theta = this.normal.angleFrom(obj.normal); + return (Math.abs(theta) <= Sylvester.precision || Math.abs(Math.PI - theta) <= Sylvester.precision); + } else if (obj.direction) { + // obj is a line + return this.normal.isPerpendicularTo(obj.direction); + } + return null; + }, + + // Returns true iff the receiver is perpendicular to the argument + isPerpendicularTo: function(plane) { + var theta = this.normal.angleFrom(plane.normal); + return (Math.abs(Math.PI/2 - theta) <= Sylvester.precision); + }, + + // Returns the plane's distance from the given object (point, line or plane) + distanceFrom: function(obj) { + if (this.intersects(obj) || this.contains(obj)) { return 0; } + if (obj.anchor) { + // obj is a plane or line + var A = this.anchor.elements, B = obj.anchor.elements, N = this.normal.elements; + return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]); + } else { + // obj is a point + var P = obj.elements || obj; + var A = this.anchor.elements, N = this.normal.elements; + return Math.abs((A[0] - P[0]) * N[0] + (A[1] - P[1]) * N[1] + (A[2] - (P[2] || 0)) * N[2]); + } + }, + + // Returns true iff the plane contains the given point or line + contains: function(obj) { + if (obj.normal) { return null; } + if (obj.direction) { + return (this.contains(obj.anchor) && this.contains(obj.anchor.add(obj.direction))); + } else { + var P = obj.elements || obj; + var A = this.anchor.elements, N = this.normal.elements; + var diff = Math.abs(N[0]*(A[0] - P[0]) + N[1]*(A[1] - P[1]) + N[2]*(A[2] - (P[2] || 0))); + return (diff <= Sylvester.precision); + } + }, + + // Returns true iff the plane has a unique point/line of intersection with the argument + intersects: function(obj) { + if (typeof(obj.direction) == 'undefined' && typeof(obj.normal) == 'undefined') { return null; } + return !this.isParallelTo(obj); + }, + + // Returns the unique intersection with the argument, if one exists. The result + // will be a vector if a line is supplied, and a line if a plane is supplied. + intersectionWith: function(obj) { + if (!this.intersects(obj)) { return null; } + if (obj.direction) { + // obj is a line + var A = obj.anchor.elements, D = obj.direction.elements, + P = this.anchor.elements, N = this.normal.elements; + var multiplier = (N[0]*(P[0]-A[0]) + N[1]*(P[1]-A[1]) + N[2]*(P[2]-A[2])) / (N[0]*D[0] + N[1]*D[1] + N[2]*D[2]); + return Vector.create([A[0] + D[0]*multiplier, A[1] + D[1]*multiplier, A[2] + D[2]*multiplier]); + } else if (obj.normal) { + // obj is a plane + var direction = this.normal.cross(obj.normal).toUnitVector(); + // To find an anchor point, we find one co-ordinate that has a value + // of zero somewhere on the intersection, and remember which one we picked + var N = this.normal.elements, A = this.anchor.elements, + O = obj.normal.elements, B = obj.anchor.elements; + var solver = Matrix.Zero(2,2), i = 0; + while (solver.isSingular()) { + i++; + solver = Matrix.create([ + [ N[i%3], N[(i+1)%3] ], + [ O[i%3], O[(i+1)%3] ] + ]); + } + // Then we solve the simultaneous equations in the remaining dimensions + var inverse = solver.inverse().elements; + var x = N[0]*A[0] + N[1]*A[1] + N[2]*A[2]; + var y = O[0]*B[0] + O[1]*B[1] + O[2]*B[2]; + var intersection = [ + inverse[0][0] * x + inverse[0][1] * y, + inverse[1][0] * x + inverse[1][1] * y + ]; + var anchor = []; + for (var j = 1; j <= 3; j++) { + // This formula picks the right element from intersection by + // cycling depending on which element we set to zero above + anchor.push((i == j) ? 0 : intersection[(j + (5 - i)%3)%3]); + } + return Line.create(anchor, direction); + } + }, + + // Returns the point in the plane closest to the given point + pointClosestTo: function(point) { + var P = point.elements || point; + var A = this.anchor.elements, N = this.normal.elements; + var dot = (A[0] - P[0]) * N[0] + (A[1] - P[1]) * N[1] + (A[2] - (P[2] || 0)) * N[2]; + return Vector.create([P[0] + N[0] * dot, P[1] + N[1] * dot, (P[2] || 0) + N[2] * dot]); + }, + + // Returns a copy of the plane, rotated by t radians about the given line + // See notes on Line#rotate. + rotate: function(t, line) { + var R = t.determinant ? t.elements : Matrix.Rotation(t, line.direction).elements; + var C = line.pointClosestTo(this.anchor).elements; + var A = this.anchor.elements, N = this.normal.elements; + var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2]; + var x = A1 - C1, y = A2 - C2, z = A3 - C3; + return Plane.create([ + C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z, + C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z, + C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z + ], [ + R[0][0] * N[0] + R[0][1] * N[1] + R[0][2] * N[2], + R[1][0] * N[0] + R[1][1] * N[1] + R[1][2] * N[2], + R[2][0] * N[0] + R[2][1] * N[1] + R[2][2] * N[2] + ]); + }, + + // Returns the reflection of the plane in the given point, line or plane. + reflectionIn: function(obj) { + if (obj.normal) { + // obj is a plane + var A = this.anchor.elements, N = this.normal.elements; + var A1 = A[0], A2 = A[1], A3 = A[2], N1 = N[0], N2 = N[1], N3 = N[2]; + var newA = this.anchor.reflectionIn(obj).elements; + // Add the plane's normal to its anchor, then mirror that in the other plane + var AN1 = A1 + N1, AN2 = A2 + N2, AN3 = A3 + N3; + var Q = obj.pointClosestTo([AN1, AN2, AN3]).elements; + var newN = [Q[0] + (Q[0] - AN1) - newA[0], Q[1] + (Q[1] - AN2) - newA[1], Q[2] + (Q[2] - AN3) - newA[2]]; + return Plane.create(newA, newN); + } else if (obj.direction) { + // obj is a line + return this.rotate(Math.PI, obj); + } else { + // obj is a point + var P = obj.elements || obj; + return Plane.create(this.anchor.reflectionIn([P[0], P[1], (P[2] || 0)]), this.normal); + } + }, + + // Sets the anchor point and normal to the plane. If three arguments are specified, + // the normal is calculated by assuming the three points should lie in the same plane. + // If only two are sepcified, the second is taken to be the normal. Normal vector is + // normalised before storage. + setVectors: function(anchor, v1, v2) { + anchor = Vector.create(anchor); + anchor = anchor.to3D(); if (anchor === null) { return null; } + v1 = Vector.create(v1); + v1 = v1.to3D(); if (v1 === null) { return null; } + if (typeof(v2) == 'undefined') { + v2 = null; + } else { + v2 = Vector.create(v2); + v2 = v2.to3D(); if (v2 === null) { return null; } + } + var A1 = anchor.elements[0], A2 = anchor.elements[1], A3 = anchor.elements[2]; + var v11 = v1.elements[0], v12 = v1.elements[1], v13 = v1.elements[2]; + var normal, mod; + if (v2 !== null) { + var v21 = v2.elements[0], v22 = v2.elements[1], v23 = v2.elements[2]; + normal = Vector.create([ + (v12 - A2) * (v23 - A3) - (v13 - A3) * (v22 - A2), + (v13 - A3) * (v21 - A1) - (v11 - A1) * (v23 - A3), + (v11 - A1) * (v22 - A2) - (v12 - A2) * (v21 - A1) + ]); + mod = normal.modulus(); + if (mod === 0) { return null; } + normal = Vector.create([normal.elements[0] / mod, normal.elements[1] / mod, normal.elements[2] / mod]); + } else { + mod = Math.sqrt(v11*v11 + v12*v12 + v13*v13); + if (mod === 0) { return null; } + normal = Vector.create([v1.elements[0] / mod, v1.elements[1] / mod, v1.elements[2] / mod]); + } + this.anchor = anchor; + this.normal = normal; + return this; + } +}; + +// Constructor function +Plane.create = function(anchor, v1, v2) { + var P = new Plane(); + return P.setVectors(anchor, v1, v2); +}; + +// X-Y-Z planes +Plane.XY = Plane.create(Vector.Zero(3), Vector.k); +Plane.YZ = Plane.create(Vector.Zero(3), Vector.i); +Plane.ZX = Plane.create(Vector.Zero(3), Vector.j); +Plane.YX = Plane.XY; Plane.ZY = Plane.YZ; Plane.XZ = Plane.ZX; + +// Returns the plane containing the given points (can be arrays as +// well as vectors). If the points are not coplanar, returns null. +Plane.fromPoints = function(points) { + var np = points.length, list = [], i, P, n, N, A, B, C, D, theta, prevN, totalN = Vector.Zero(3); + for (i = 0; i < np; i++) { + P = Vector.create(points[i]).to3D(); + if (P === null) { return null; } + list.push(P); + n = list.length; + if (n > 2) { + // Compute plane normal for the latest three points + A = list[n-1].elements; B = list[n-2].elements; C = list[n-3].elements; + N = Vector.create([ + (A[1] - B[1]) * (C[2] - B[2]) - (A[2] - B[2]) * (C[1] - B[1]), + (A[2] - B[2]) * (C[0] - B[0]) - (A[0] - B[0]) * (C[2] - B[2]), + (A[0] - B[0]) * (C[1] - B[1]) - (A[1] - B[1]) * (C[0] - B[0]) + ]).toUnitVector(); + if (n > 3) { + // If the latest normal is not (anti)parallel to the previous one, we've strayed off the plane. + // This might be a slightly long-winded way of doing things, but we need the sum of all the normals + // to find which way the plane normal should point so that the points form an anticlockwise list. + theta = N.angleFrom(prevN); + if (theta !== null) { + if (!(Math.abs(theta) <= Sylvester.precision || Math.abs(theta - Math.PI) <= Sylvester.precision)) { return null; } + } + } + totalN = totalN.add(N); + prevN = N; + } + } + // We need to add in the normals at the start and end points, which the above misses out + A = list[1].elements; B = list[0].elements; C = list[n-1].elements; D = list[n-2].elements; + totalN = totalN.add(Vector.create([ + (A[1] - B[1]) * (C[2] - B[2]) - (A[2] - B[2]) * (C[1] - B[1]), + (A[2] - B[2]) * (C[0] - B[0]) - (A[0] - B[0]) * (C[2] - B[2]), + (A[0] - B[0]) * (C[1] - B[1]) - (A[1] - B[1]) * (C[0] - B[0]) + ]).toUnitVector()).add(Vector.create([ + (B[1] - C[1]) * (D[2] - C[2]) - (B[2] - C[2]) * (D[1] - C[1]), + (B[2] - C[2]) * (D[0] - C[0]) - (B[0] - C[0]) * (D[2] - C[2]), + (B[0] - C[0]) * (D[1] - C[1]) - (B[1] - C[1]) * (D[0] - C[0]) + ]).toUnitVector()); + return Plane.create(list[0], totalN); +}; + +module.exports = Plane; + +},{"./line":13,"./matrix":15,"./sylvester":17,"./vector":18}],17:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// This file is required in order for any other classes to work. Some Vector methods work with the +// other Sylvester classes and are useless unless they are included. Other classes such as Line and +// Plane will not function at all without Vector being loaded first. + +Math.sign = function(x) { + return x < 0 ? -1: 1; +} + +var Sylvester = { + precision: 1e-6, + approxPrecision: 1e-5 +}; + +module.exports = Sylvester; + +},{}],18:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// This file is required in order for any other classes to work. Some Vector methods work with the +// other Sylvester classes and are useless unless they are included. Other classes such as Line and +// Plane will not function at all without Vector being loaded first. + +var Sylvester = require('./sylvester'), +Matrix = require('./matrix'); + +function Vector() {} +Vector.prototype = { + + norm: function() { + var n = this.elements.length; + var sum = 0; + + while (n--) { + sum += Math.pow(this.elements[n], 2); + } + + return Math.sqrt(sum); + }, + + // Returns element i of the vector + e: function(i) { + return (i < 1 || i > this.elements.length) ? null : this.elements[i - 1]; + }, + + // Returns the number of rows/columns the vector has + dimensions: function() { + return {rows: 1, cols: this.elements.length}; + }, + + // Returns the number of rows in the vector + rows: function() { + return 1; + }, + + // Returns the number of columns in the vector + cols: function() { + return this.elements.length; + }, + + // Returns the modulus ('length') of the vector + modulus: function() { + return Math.sqrt(this.dot(this)); + }, + + // Returns true iff the vector is equal to the argument + eql: function(vector) { + var n = this.elements.length; + var V = vector.elements || vector; + if (n != V.length) { return false; } + while (n--) { + if (Math.abs(this.elements[n] - V[n]) > Sylvester.precision) { return false; } + } + return true; + }, + + // Returns a copy of the vector + dup: function() { + return Vector.create(this.elements); + }, + + // Maps the vector to another vector according to the given function + map: function(fn) { + var elements = []; + this.each(function(x, i) { + elements.push(fn(x, i)); + }); + return Vector.create(elements); + }, + + // Calls the iterator for each element of the vector in turn + each: function(fn) { + var n = this.elements.length; + for (var i = 0; i < n; i++) { + fn(this.elements[i], i + 1); + } + }, + + // Returns a new vector created by normalizing the receiver + toUnitVector: function() { + var r = this.modulus(); + if (r === 0) { return this.dup(); } + return this.map(function(x) { return x / r; }); + }, + + // Returns the angle between the vector and the argument (also a vector) + angleFrom: function(vector) { + var V = vector.elements || vector; + var n = this.elements.length, k = n, i; + if (n != V.length) { return null; } + var dot = 0, mod1 = 0, mod2 = 0; + // Work things out in parallel to save time + this.each(function(x, i) { + dot += x * V[i - 1]; + mod1 += x * x; + mod2 += V[i - 1] * V[i - 1]; + }); + mod1 = Math.sqrt(mod1); mod2 = Math.sqrt(mod2); + if (mod1 * mod2 === 0) { return null; } + var theta = dot / (mod1 * mod2); + if (theta < -1) { theta = -1; } + if (theta > 1) { theta = 1; } + return Math.acos(theta); + }, + + // Returns true iff the vector is parallel to the argument + isParallelTo: function(vector) { + var angle = this.angleFrom(vector); + return (angle === null) ? null : (angle <= Sylvester.precision); + }, + + // Returns true iff the vector is antiparallel to the argument + isAntiparallelTo: function(vector) { + var angle = this.angleFrom(vector); + return (angle === null) ? null : (Math.abs(angle - Math.PI) <= Sylvester.precision); + }, + + // Returns true iff the vector is perpendicular to the argument + isPerpendicularTo: function(vector) { + var dot = this.dot(vector); + return (dot === null) ? null : (Math.abs(dot) <= Sylvester.precision); + }, + + // Returns the result of adding the argument to the vector + add: function(value) { + var V = value.elements || value; + + if (this.elements.length != V.length) + return this.map(function(v) { return v + value }); + else + return this.map(function(x, i) { return x + V[i - 1]; }); + }, + + // Returns the result of subtracting the argument from the vector + subtract: function(v) { + if (typeof(v) == 'number') + return this.map(function(k) { return k - v; }); + + var V = v.elements || v; + if (this.elements.length != V.length) { return null; } + return this.map(function(x, i) { return x - V[i - 1]; }); + }, + + // Returns the result of multiplying the elements of the vector by the argument + multiply: function(k) { + return this.map(function(x) { return x * k; }); + }, + + elementMultiply: function(v) { + return this.map(function(k, i) { + return v.e(i) * k; + }); + }, + + sum: function() { + var sum = 0; + this.map(function(x) { sum += x;}); + return sum; + }, + + chomp: function(n) { + var elements = []; + + for (var i = n; i < this.elements.length; i++) { + elements.push(this.elements[i]); + } + + return Vector.create(elements); + }, + + top: function(n) { + var elements = []; + + for (var i = 0; i < n; i++) { + elements.push(this.elements[i]); + } + + return Vector.create(elements); + }, + + augment: function(elements) { + var newElements = this.elements; + + for (var i = 0; i < elements.length; i++) { + newElements.push(elements[i]); + } + + return Vector.create(newElements); + }, + + x: function(k) { return this.multiply(k); }, + + log: function() { + return Vector.log(this); + }, + + elementDivide: function(vector) { + return this.map(function(v, i) { + return v / vector.e(i); + }); + }, + + product: function() { + var p = 1; + + this.map(function(v) { + p *= v; + }); + + return p; + }, + + // Returns the scalar product of the vector with the argument + // Both vectors must have equal dimensionality + dot: function(vector) { + var V = vector.elements || vector; + var i, product = 0, n = this.elements.length; + if (n != V.length) { return null; } + while (n--) { product += this.elements[n] * V[n]; } + return product; + }, + + // Returns the vector product of the vector with the argument + // Both vectors must have dimensionality 3 + cross: function(vector) { + var B = vector.elements || vector; + if (this.elements.length != 3 || B.length != 3) { return null; } + var A = this.elements; + return Vector.create([ + (A[1] * B[2]) - (A[2] * B[1]), + (A[2] * B[0]) - (A[0] * B[2]), + (A[0] * B[1]) - (A[1] * B[0]) + ]); + }, + + // Returns the (absolute) largest element of the vector + max: function() { + var m = 0, i = this.elements.length; + while (i--) { + if (Math.abs(this.elements[i]) > Math.abs(m)) { m = this.elements[i]; } + } + return m; + }, + + + maxIndex: function() { + var m = 0, i = this.elements.length; + var maxIndex = -1; + + while (i--) { + if (Math.abs(this.elements[i]) > Math.abs(m)) { + m = this.elements[i]; + maxIndex = i + 1; + } + } + + return maxIndex; + }, + + + // Returns the index of the first match found + indexOf: function(x) { + var index = null, n = this.elements.length; + for (var i = 0; i < n; i++) { + if (index === null && this.elements[i] == x) { + index = i + 1; + } + } + return index; + }, + + // Returns a diagonal matrix with the vector's elements as its diagonal elements + toDiagonalMatrix: function() { + return Matrix.Diagonal(this.elements); + }, + + // Returns the result of rounding the elements of the vector + round: function() { + return this.map(function(x) { return Math.round(x); }); + }, + + // Transpose a Vector, return a 1xn Matrix + transpose: function() { + var rows = this.elements.length; + var elements = []; + + for (var i = 0; i < rows; i++) { + elements.push([this.elements[i]]); + } + return Matrix.create(elements); + }, + + // Returns a copy of the vector with elements set to the given value if they + // differ from it by less than Sylvester.precision + snapTo: function(x) { + return this.map(function(y) { + return (Math.abs(y - x) <= Sylvester.precision) ? x : y; + }); + }, + + // Returns the vector's distance from the argument, when considered as a point in space + distanceFrom: function(obj) { + if (obj.anchor || (obj.start && obj.end)) { return obj.distanceFrom(this); } + var V = obj.elements || obj; + if (V.length != this.elements.length) { return null; } + var sum = 0, part; + this.each(function(x, i) { + part = x - V[i - 1]; + sum += part * part; + }); + return Math.sqrt(sum); + }, + + // Returns true if the vector is point on the given line + liesOn: function(line) { + return line.contains(this); + }, + + // Return true iff the vector is a point in the given plane + liesIn: function(plane) { + return plane.contains(this); + }, + + // Rotates the vector about the given object. The object should be a + // point if the vector is 2D, and a line if it is 3D. Be careful with line directions! + rotate: function(t, obj) { + var V, R = null, x, y, z; + if (t.determinant) { R = t.elements; } + switch (this.elements.length) { + case 2: + V = obj.elements || obj; + if (V.length != 2) { return null; } + if (!R) { R = Matrix.Rotation(t).elements; } + x = this.elements[0] - V[0]; + y = this.elements[1] - V[1]; + return Vector.create([ + V[0] + R[0][0] * x + R[0][1] * y, + V[1] + R[1][0] * x + R[1][1] * y + ]); + break; + case 3: + if (!obj.direction) { return null; } + var C = obj.pointClosestTo(this).elements; + if (!R) { R = Matrix.Rotation(t, obj.direction).elements; } + x = this.elements[0] - C[0]; + y = this.elements[1] - C[1]; + z = this.elements[2] - C[2]; + return Vector.create([ + C[0] + R[0][0] * x + R[0][1] * y + R[0][2] * z, + C[1] + R[1][0] * x + R[1][1] * y + R[1][2] * z, + C[2] + R[2][0] * x + R[2][1] * y + R[2][2] * z + ]); + break; + default: + return null; + } + }, + + // Returns the result of reflecting the point in the given point, line or plane + reflectionIn: function(obj) { + if (obj.anchor) { + // obj is a plane or line + var P = this.elements.slice(); + var C = obj.pointClosestTo(P).elements; + return Vector.create([C[0] + (C[0] - P[0]), C[1] + (C[1] - P[1]), C[2] + (C[2] - (P[2] || 0))]); + } else { + // obj is a point + var Q = obj.elements || obj; + if (this.elements.length != Q.length) { return null; } + return this.map(function(x, i) { return Q[i - 1] + (Q[i - 1] - x); }); + } + }, + + // Utility to make sure vectors are 3D. If they are 2D, a zero z-component is added + to3D: function() { + var V = this.dup(); + switch (V.elements.length) { + case 3: break; + case 2: V.elements.push(0); break; + default: return null; + } + return V; + }, + + // Returns a string representation of the vector + inspect: function() { + return '[' + this.elements.join(', ') + ']'; + }, + + // Set vector's elements from an array + setElements: function(els) { + this.elements = (els.elements || els).slice(); + return this; + } +}; + +// Constructor function +Vector.create = function(elements) { + var V = new Vector(); + return V.setElements(elements); +}; + +// i, j, k unit vectors +Vector.i = Vector.create([1, 0, 0]); +Vector.j = Vector.create([0, 1, 0]); +Vector.k = Vector.create([0, 0, 1]); + +// Random vector of size n +Vector.Random = function(n) { + var elements = []; + while (n--) { elements.push(Math.random()); } + return Vector.create(elements); +}; + +Vector.Fill = function(n, v) { + var elements = []; + while (n--) { elements.push(v); } + return Vector.create(elements); +}; + +// Vector filled with zeros +Vector.Zero = function(n) { + return Vector.Fill(n, 0); +}; + +Vector.One = function(n) { + return Vector.Fill(n, 1); +}; + +Vector.log = function(v) { + return v.map(function(x) { + return Math.log(x); + }); +}; + +module.exports = Vector; + +},{"./matrix":15,"./sylvester":17}],19:[function(require,module,exports){ +"use strict"; + +/** + * Represents a 2-dimensional size value. + */ + +function Size(w, h) { + this.w = w; + this.h = h; +} + +Size.prototype = { + toString: function () { + return "(" + this.w + ", " + this.h + ")"; + }, + getHalfSize: function() { + return new Size(this.w >>> 1, this.h >>> 1); + }, + length: function() { + return this.w * this.h; + } +} +module.exports = Size; +},{}],20:[function(require,module,exports){ +"use strict"; + +var error = require('./error'); + +function assert(condition, message) { + if (!condition) { + error(message); + } +} + + +module.exports = assert; + +},{"./error":21}],21:[function(require,module,exports){ +"use strict"; + +function error(message) { + console.error(message); + console.trace(); +} + +module.exports = error; + +},{}],22:[function(require,module,exports){ +"use strict"; + +var Matrix = require('sylvester.js').Matrix; +var Vector = require('sylvester.js').Vector; +var $M = Matrix.create; + + +// augment Sylvester some +Matrix.Translation = function (v) +{ + if (v.elements.length == 2) { + var r = Matrix.I(3); + r.elements[2][0] = v.elements[0]; + r.elements[2][1] = v.elements[1]; + return r; + } + + if (v.elements.length == 3) { + var r = Matrix.I(4); + r.elements[0][3] = v.elements[0]; + r.elements[1][3] = v.elements[1]; + r.elements[2][3] = v.elements[2]; + return r; + } + + throw "Invalid length for Translation"; +} + +Matrix.prototype.flatten = function () +{ + var result = []; + if (this.elements.length == 0) + return []; + + + for (var j = 0; j < this.elements[0].length; j++) + for (var i = 0; i < this.elements.length; i++) + result.push(this.elements[i][j]); + return result; +} + +Matrix.prototype.ensure4x4 = function() +{ + if (this.elements.length == 4 && + this.elements[0].length == 4) + return this; + + if (this.elements.length > 4 || + this.elements[0].length > 4) + return null; + + for (var i = 0; i < this.elements.length; i++) { + for (var j = this.elements[i].length; j < 4; j++) { + if (i == j) + this.elements[i].push(1); + else + this.elements[i].push(0); + } + } + + for (var i = this.elements.length; i < 4; i++) { + if (i == 0) + this.elements.push([1, 0, 0, 0]); + else if (i == 1) + this.elements.push([0, 1, 0, 0]); + else if (i == 2) + this.elements.push([0, 0, 1, 0]); + else if (i == 3) + this.elements.push([0, 0, 0, 1]); + } + + return this; +}; + + +Vector.prototype.flatten = function () +{ + return this.elements; +}; + + + +// +// gluPerspective +// +function makePerspective(fovy, aspect, znear, zfar) +{ + var ymax = znear * Math.tan(fovy * Math.PI / 360.0); + var ymin = -ymax; + var xmin = ymin * aspect; + var xmax = ymax * aspect; + + return makeFrustum(xmin, xmax, ymin, ymax, znear, zfar); +} + +// +// glFrustum +// +function makeFrustum(left, right, + bottom, top, + znear, zfar) +{ + var X = 2*znear/(right-left); + var Y = 2*znear/(top-bottom); + var A = (right+left)/(right-left); + var B = (top+bottom)/(top-bottom); + var C = -(zfar+znear)/(zfar-znear); + var D = -2*zfar*znear/(zfar-znear); + + return $M([[X, 0, A, 0], + [0, Y, B, 0], + [0, 0, C, D], + [0, 0, -1, 0]]); +} + +module.exports.makePerspective = makePerspective; + + +},{"sylvester.js":12}],23:[function(require,module,exports){ +"use strict"; + +var Avc = require('../broadway/Decoder'); +var YUVWebGLCanvas = require('../canvas/YUVWebGLCanvas'); +var YUVCanvas = require('../canvas/YUVCanvas'); +var Size = require('../utils/Size'); +var Class = require('uclass'); +var Events = require('uclass/events'); +var debug = require('debug'); +var log = debug("wsavc"); + +var WSAvcPlayer = new Class({ + Implements : [Events], + + + initialize : function(canvas, canvastype) { + + this.canvas = canvas; + this.canvastype = canvastype; + + // AVC codec initialization + this.avc = new Avc(); + if(false) this.avc.configure({ + filter: "original", + filterHorLuma: "optimized", + filterVerLumaEdge: "optimized", + getBoundaryStrengthsA: "optimized" + }); + + //WebSocket variable + this.ws; + this.pktnum = 0; + + }, + + + decode : function(data) { + var naltype = "invalid frame"; + + if (data.length > 4) { + if (data[4] == 0x65) { + naltype = "I frame"; + } + else if (data[4] == 0x41) { + naltype = "P frame"; + } + else if (data[4] == 0x67) { + naltype = "SPS"; + } + else if (data[4] == 0x68) { + naltype = "PPS"; + } + } + //log("Passed " + naltype + " to decoder"); + this.avc.decode(data); + }, + + connect : function(url) { + + // Websocket initialization + if (this.ws != undefined) { + this.ws.close(); + delete this.ws; + } + this.ws = new WebSocket(url); + this.ws.binaryType = "arraybuffer"; + + this.ws.onopen = () => { + log("Connected to " + url); + }; + + + var framesList = []; + + this.ws.onmessage = (evt) => { + if(typeof evt.data == "string") + return this.cmd(JSON.parse(evt.data)); + + this.pktnum++; + var frame = new Uint8Array(evt.data); + //log("[Pkt " + this.pktnum + " (" + evt.data.byteLength + " bytes)]"); + //this.decode(frame); + framesList.push(frame); + }; + + + var running = true; + + var shiftFrame = function() { + if(!running) + return; + + + if(framesList.length > 10) { + log("Dropping frames", framesList.length); + framesList = []; + } + + var frame = framesList.shift(); + + + if(frame) + this.decode(frame); + + requestAnimationFrame(shiftFrame); + }.bind(this); + + + shiftFrame(); + + + + this.ws.onclose = () => { + running = false; + log("WSAvcPlayer: Connection closed") + }; + + }, + + initCanvas : function(width, height) { + var canvasFactory = this.canvastype == "webgl" || this.canvastype == "YUVWebGLCanvas" + ? YUVWebGLCanvas + : YUVCanvas; + + var canvas = new canvasFactory(this.canvas, new Size(width, height)); + this.avc.onPictureDecoded = canvas.decode; + this.emit("canvasReady", width, height); + }, + + cmd : function(cmd){ + log("Incoming request", cmd); + + if(cmd.action == "init") { + this.initCanvas(cmd.width, cmd.height); + this.canvas.width = cmd.width; + this.canvas.height = cmd.height; + } + }, + + disconnect : function() { + this.ws.close(); + }, + + playStream : function() { + var message = "REQUESTSTREAM "; + this.ws.send(message); + log("Sent " + message); + }, + + + stopStream : function() { + this.ws.send("STOPSTREAM"); + log("Sent STOPSTREAM"); + }, +}); + + +module.exports = WSAvcPlayer; +module.exports.debug = debug; + +},{"../broadway/Decoder":4,"../canvas/YUVCanvas":10,"../canvas/YUVWebGLCanvas":11,"../utils/Size":19,"debug":1,"uclass":47,"uclass/events":24}],24:[function(require,module,exports){ +"use strict"; + +var Class = require('../'); +var guid = require('mout/random/guid'); +var forIn = require('mout/object/forIn'); + +var EventEmitter = new Class({ + Binds : ['on', 'off', 'once', 'emit'], + + callbacks : {}, + + initialize : function() { + var self = this; + this.addEvent = this.on; + this.removeListener = this.off; + this.removeAllListeners = this.off; + this.fireEvent = this.emit; + }, + + emit:function(event, payload){ + if(!this.callbacks[event]) + return; + + var args = Array.prototype.slice.call(arguments, 1); + + forIn(this.callbacks[event], function(callback){ + callback.apply(null, args); + }); + }, + + + on:function(event, callback){ + if(typeof callback != "function") + return console.log("you try to register a non function in " , event) + if(!this.callbacks[event]) + this.callbacks[event] = {}; + this.callbacks[event][guid()] = callback; + }, + + once:function(event, callback){ + var self = this; + var once = function(){ + self.off(event, once); + self.off(event, callback); + }; + + this.on(event, callback); + this.on(event, once); + }, + + off:function(event, callback){ + if(!event) + this.callbacks = {}; + else if(!callback) + this.callbacks[event] = {}; + else forIn(this.callbacks[event] || {}, function(v, k) { + if(v == callback) + delete this.callbacks[event][k]; + }, this); + }, +}); + +module.exports = EventEmitter; +},{"../":47,"mout/object/forIn":36,"mout/random/guid":42}],25:[function(require,module,exports){ +"use strict"; + +var verbs = /^Implements|Extends|Binds$/ + +module.exports = function(ctx, obj){ + for(var key in obj) { + if(key.match(verbs)) continue; + if((typeof obj[key] == 'function') && obj[key].$static) + ctx[key] = obj[key]; + else + ctx.prototype[key] = obj[key]; + } + return ctx; +} +},{}],26:[function(require,module,exports){ +var kindOf = require('./kindOf'); +var isPlainObject = require('./isPlainObject'); +var mixIn = require('../object/mixIn'); + + /** + * Clone native types. + */ + function clone(val){ + switch (kindOf(val)) { + case 'Object': + return cloneObject(val); + case 'Array': + return cloneArray(val); + case 'RegExp': + return cloneRegExp(val); + case 'Date': + return cloneDate(val); + default: + return val; + } + } + + function cloneObject(source) { + if (isPlainObject(source)) { + return mixIn({}, source); + } else { + return source; + } + } + + function cloneRegExp(r) { + var flags = ''; + flags += r.multiline ? 'm' : ''; + flags += r.global ? 'g' : ''; + flags += r.ignoreCase ? 'i' : ''; + return new RegExp(r.source, flags); + } + + function cloneDate(date) { + return new Date(+date); + } + + function cloneArray(arr) { + return arr.slice(); + } + + module.exports = clone; + + + +},{"../object/mixIn":40,"./isPlainObject":32,"./kindOf":33}],27:[function(require,module,exports){ +var mixIn = require('../object/mixIn'); + + /** + * Create Object using prototypal inheritance and setting custom properties. + * - Mix between Douglas Crockford Prototypal Inheritance and the EcmaScript 5 `Object.create()` method. + * @param {object} parent Parent Object. + * @param {object} [props] Object properties. + * @return {object} Created object. + */ + function createObject(parent, props){ + function F(){} + F.prototype = parent; + return mixIn(new F(), props); + + } + module.exports = createObject; + + + +},{"../object/mixIn":40}],28:[function(require,module,exports){ +var clone = require('./clone'); +var forOwn = require('../object/forOwn'); +var kindOf = require('./kindOf'); +var isPlainObject = require('./isPlainObject'); + + /** + * Recursively clone native types. + */ + function deepClone(val, instanceClone) { + switch ( kindOf(val) ) { + case 'Object': + return cloneObject(val, instanceClone); + case 'Array': + return cloneArray(val, instanceClone); + default: + return clone(val); + } + } + + function cloneObject(source, instanceClone) { + if (isPlainObject(source)) { + var out = {}; + forOwn(source, function(val, key) { + this[key] = deepClone(val, instanceClone); + }, out); + return out; + } else if (instanceClone) { + return instanceClone(source); + } else { + return source; + } + } + + function cloneArray(arr, instanceClone) { + var out = [], + i = -1, + n = arr.length, + val; + while (++i < n) { + out[i] = deepClone(arr[i], instanceClone); + } + return out; + } + + module.exports = deepClone; + + + + +},{"../object/forOwn":37,"./clone":26,"./isPlainObject":32,"./kindOf":33}],29:[function(require,module,exports){ +var isKind = require('./isKind'); + /** + */ + var isArray = Array.isArray || function (val) { + return isKind(val, 'Array'); + }; + module.exports = isArray; + + +},{"./isKind":30}],30:[function(require,module,exports){ +var kindOf = require('./kindOf'); + /** + * Check if value is from a specific "kind". + */ + function isKind(val, kind){ + return kindOf(val) === kind; + } + module.exports = isKind; + + +},{"./kindOf":33}],31:[function(require,module,exports){ +var isKind = require('./isKind'); + /** + */ + function isObject(val) { + return isKind(val, 'Object'); + } + module.exports = isObject; + + +},{"./isKind":30}],32:[function(require,module,exports){ + + + /** + * Checks if the value is created by the `Object` constructor. + */ + function isPlainObject(value) { + return (!!value && typeof value === 'object' && + value.constructor === Object); + } + + module.exports = isPlainObject; + + + +},{}],33:[function(require,module,exports){ + + + var _rKind = /^\[object (.*)\]$/, + _toString = Object.prototype.toString, + UNDEF; + + /** + * Gets the "kind" of value. (e.g. "String", "Number", etc) + */ + function kindOf(val) { + if (val === null) { + return 'Null'; + } else if (val === UNDEF) { + return 'Undefined'; + } else { + return _rKind.exec( _toString.call(val) )[1]; + } + } + module.exports = kindOf; + + +},{}],34:[function(require,module,exports){ +/** + * @constant Maximum 32-bit signed integer value. (2^31 - 1) + */ + + module.exports = 2147483647; + + +},{}],35:[function(require,module,exports){ +/** + * @constant Minimum 32-bit signed integer value (-2^31). + */ + + module.exports = -2147483648; + + +},{}],36:[function(require,module,exports){ +var hasOwn = require('./hasOwn'); + + var _hasDontEnumBug, + _dontEnums; + + function checkDontEnum(){ + _dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' + ]; + + _hasDontEnumBug = true; + + for (var key in {'toString': null}) { + _hasDontEnumBug = false; + } + } + + /** + * Similar to Array/forEach but works over object properties and fixes Don't + * Enum bug on IE. + * based on: http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation + */ + function forIn(obj, fn, thisObj){ + var key, i = 0; + // no need to check if argument is a real object that way we can use + // it for arrays, functions, date, etc. + + //post-pone check till needed + if (_hasDontEnumBug == null) checkDontEnum(); + + for (key in obj) { + if (exec(fn, obj, key, thisObj) === false) { + break; + } + } + + + if (_hasDontEnumBug) { + var ctor = obj.constructor, + isProto = !!ctor && obj === ctor.prototype; + + while (key = _dontEnums[i++]) { + // For constructor, if it is a prototype object the constructor + // is always non-enumerable unless defined otherwise (and + // enumerated above). For non-prototype objects, it will have + // to be defined on this object, since it cannot be defined on + // any prototype objects. + // + // For other [[DontEnum]] properties, check if the value is + // different than Object prototype value. + if ( + (key !== 'constructor' || + (!isProto && hasOwn(obj, key))) && + obj[key] !== Object.prototype[key] + ) { + if (exec(fn, obj, key, thisObj) === false) { + break; + } + } + } + } + } + + function exec(fn, obj, key, thisObj){ + return fn.call(thisObj, obj[key], key, obj); + } + + module.exports = forIn; + + + +},{"./hasOwn":38}],37:[function(require,module,exports){ +var hasOwn = require('./hasOwn'); +var forIn = require('./forIn'); + + /** + * Similar to Array/forEach but works over object properties and fixes Don't + * Enum bug on IE. + * based on: http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation + */ + function forOwn(obj, fn, thisObj){ + forIn(obj, function(val, key){ + if (hasOwn(obj, key)) { + return fn.call(thisObj, obj[key], key, obj); + } + }); + } + + module.exports = forOwn; + + + +},{"./forIn":36,"./hasOwn":38}],38:[function(require,module,exports){ + + + /** + * Safer Object.hasOwnProperty + */ + function hasOwn(obj, prop){ + return Object.prototype.hasOwnProperty.call(obj, prop); + } + + module.exports = hasOwn; + + + +},{}],39:[function(require,module,exports){ +var hasOwn = require('./hasOwn'); +var deepClone = require('../lang/deepClone'); +var isObject = require('../lang/isObject'); + + /** + * Deep merge objects. + */ + function merge() { + var i = 1, + key, val, obj, target; + + // make sure we don't modify source element and it's properties + // objects are passed by reference + target = deepClone( arguments[0] ); + + while (obj = arguments[i++]) { + for (key in obj) { + if ( ! hasOwn(obj, key) ) { + continue; + } + + val = obj[key]; + + if ( isObject(val) && isObject(target[key]) ){ + // inception, deep merge objects + target[key] = merge(target[key], val); + } else { + // make sure arrays, regexp, date, objects are cloned + target[key] = deepClone(val); + } + + } + } + + return target; + } + + module.exports = merge; + + + +},{"../lang/deepClone":28,"../lang/isObject":31,"./hasOwn":38}],40:[function(require,module,exports){ +var forOwn = require('./forOwn'); + + /** + * Combine properties from all the objects into first one. + * - This method affects target object in place, if you want to create a new Object pass an empty object as first param. + * @param {object} target Target Object + * @param {...object} objects Objects to be combined (0...n objects). + * @return {object} Target Object. + */ + function mixIn(target, objects){ + var i = 0, + n = arguments.length, + obj; + while(++i < n){ + obj = arguments[i]; + if (obj != null) { + forOwn(obj, copyProp, target); + } + } + return target; + } + + function copyProp(val, key){ + this[key] = val; + } + + module.exports = mixIn; + + +},{"./forOwn":37}],41:[function(require,module,exports){ +var randInt = require('./randInt'); +var isArray = require('../lang/isArray'); + + /** + * Returns a random element from the supplied arguments + * or from the array (if single argument is an array). + */ + function choice(items) { + var target = (arguments.length === 1 && isArray(items))? items : arguments; + return target[ randInt(0, target.length - 1) ]; + } + + module.exports = choice; + + + +},{"../lang/isArray":29,"./randInt":45}],42:[function(require,module,exports){ +var randHex = require('./randHex'); +var choice = require('./choice'); + + /** + * Returns pseudo-random guid (UUID v4) + * IMPORTANT: it's not totally "safe" since randHex/choice uses Math.random + * by default and sequences can be predicted in some cases. See the + * "random/random" documentation for more info about it and how to replace + * the default PRNG. + */ + function guid() { + return ( + randHex(8)+'-'+ + randHex(4)+'-'+ + // v4 UUID always contain "4" at this position to specify it was + // randomly generated + '4' + randHex(3) +'-'+ + // v4 UUID always contain chars [a,b,8,9] at this position + choice(8, 9, 'a', 'b') + randHex(3)+'-'+ + randHex(12) + ); + } + module.exports = guid; + + +},{"./choice":41,"./randHex":44}],43:[function(require,module,exports){ +var random = require('./random'); +var MIN_INT = require('../number/MIN_INT'); +var MAX_INT = require('../number/MAX_INT'); + + /** + * Returns random number inside range + */ + function rand(min, max){ + min = min == null? MIN_INT : min; + max = max == null? MAX_INT : max; + return min + (max - min) * random(); + } + + module.exports = rand; + + +},{"../number/MAX_INT":34,"../number/MIN_INT":35,"./random":46}],44:[function(require,module,exports){ +var choice = require('./choice'); + + var _chars = '0123456789abcdef'.split(''); + + /** + * Returns a random hexadecimal string + */ + function randHex(size){ + size = size && size > 0? size : 6; + var str = ''; + while (size--) { + str += choice(_chars); + } + return str; + } + + module.exports = randHex; + + + +},{"./choice":41}],45:[function(require,module,exports){ +var MIN_INT = require('../number/MIN_INT'); +var MAX_INT = require('../number/MAX_INT'); +var rand = require('./rand'); + + /** + * Gets random integer inside range or snap to min/max values. + */ + function randInt(min, max){ + min = min == null? MIN_INT : ~~min; + max = max == null? MAX_INT : ~~max; + // can't be max + 0.5 otherwise it will round up if `rand` + // returns `max` causing it to overflow range. + // -0.5 and + 0.49 are required to avoid bias caused by rounding + return Math.round( rand(min - 0.5, max + 0.499999999999) ); + } + + module.exports = randInt; + + +},{"../number/MAX_INT":34,"../number/MIN_INT":35,"./rand":43}],46:[function(require,module,exports){ + + + /** + * Just a wrapper to Math.random. No methods inside mout/random should call + * Math.random() directly so we can inject the pseudo-random number + * generator if needed (ie. in case we need a seeded random or a better + * algorithm than the native one) + */ + function random(){ + return random.get(); + } + + // we expose the method so it can be swapped if needed + random.get = Math.random; + + module.exports = random; + + + +},{}],47:[function(require,module,exports){ +"use strict"; + +var hasOwn = require("mout/object/hasOwn"); +var create = require("mout/lang/createObject"); +var merge = require("mout/object/merge"); +var kindOf = require("mout/lang/kindOf"); +var mixIn = require("mout/object/mixIn"); + +var implement = require('./implement'); +var verbs = /^Implements|Extends|Binds$/ + + + + +var uClass = function(proto){ + + if(kindOf(proto) === "Function") proto = {initialize: proto}; + + var superprime = proto.Extends; + + var constructor = (hasOwn(proto, "initialize")) ? proto.initialize : superprime ? superprime : function(){}; + + + + var out = function() { + var self = this; + //autobinding takes place here + if(proto.Binds) proto.Binds.forEach(function(f){ + var original = self[f]; + if(original) + self[f] = mixIn(self[f].bind(self), original); + }); + + //clone non function/static properties to current instance + for(var key in out.prototype) { + var v = out.prototype[key], t = kindOf(v); + + if(key.match(verbs) || t === "Function" || t == "GeneratorFunction") + continue; + + if(t == "Object") + self[key] = merge({}, self[key]); //create(null, self[key]); + else if(t == "Array") + self[key] = v.slice(); //clone ?? + else + self[key] = v; + } + + if(proto.Implements) + proto.Implements.forEach(function(Mixin){ + Mixin.call(self); + }); + + + + + constructor.apply(this, arguments); + } + + + if (superprime) { + // inherit from superprime + var superproto = superprime.prototype; + if(superproto.Binds) + proto.Binds = (proto.Binds || []).concat(superproto.Binds); + + if(superproto.Implements) + proto.Implements = (proto.Implements || []).concat(superproto.Implements); + + var cproto = out.prototype = create(superproto); + // setting constructor.parent to superprime.prototype + // because it's the shortest possible absolute reference + out.parent = superproto; + cproto.constructor = out + + } + + + if(proto.Implements) { + if (kindOf(proto.Implements) !== "Array") + proto.Implements = [proto.Implements]; + proto.Implements.forEach(function(Mixin){ + implement(out, Mixin.prototype); + }); + } + + implement(out, proto); + if(proto.Binds) + out.prototype.Binds = proto.Binds; + if(proto.Implements) + out.prototype.Implements = proto.Implements; + + return out; +}; + + + +module.exports = uClass; +},{"./implement":25,"mout/lang/createObject":27,"mout/lang/kindOf":33,"mout/object/hasOwn":38,"mout/object/merge":39,"mout/object/mixIn":40}]},{},[23])(23) +}); \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/h264liveplayer/http-live-player.js b/tools/ffmpegToWeb/Player/broadway/h264liveplayer/http-live-player.js new file mode 100644 index 0000000..7021af6 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/h264liveplayer/http-live-player.js @@ -0,0 +1,5186 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.WSAvcPlayer = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +function useColors() { + // is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + return (typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style) || + // is firebug? http://stackoverflow.com/a/398120/376773 + (window.console && (console.firebug || (console.exception && console.table))) || + // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); +} + +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +exports.formatters.j = function(v) { + return JSON.stringify(v); +}; + + +/** + * Colorize log arguments if enabled. + * + * @api public + */ + +function formatArgs() { + var args = arguments; + var useColors = this.useColors; + + args[0] = (useColors ? '%c' : '') + + this.namespace + + (useColors ? ' %c' : ' ') + + args[0] + + (useColors ? '%c ' : ' ') + + '+' + exports.humanize(this.diff); + + if (!useColors) return args; + + var c = 'color: ' + this.color; + args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); + + // the final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + var index = 0; + var lastC = 0; + args[0].replace(/%[a-z%]/g, function(match) { + if ('%%' === match) return; + index++; + if ('%c' === match) { + // we only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + + args.splice(lastC, 0, c); + return args; +} + +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". + * + * @api public + */ + +function log() { + // this hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return 'object' === typeof console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + +function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch(e) {} +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + var r; + try { + r = exports.storage.debug; + } catch(e) {} + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if ('env' in (typeof process === 'undefined' ? {} : process)) { + r = process.env.DEBUG; + } + + return r; +} + +/** + * Enable namespaces listed in `localStorage.debug` initially. + */ + +exports.enable(load()); + +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + +function localstorage(){ + try { + return window.localStorage; + } catch (e) {} +} + +},{"./debug":2}],2:[function(require,module,exports){ + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = debug.debug = debug; +exports.coerce = coerce; +exports.disable = disable; +exports.enable = enable; +exports.enabled = enabled; +exports.humanize = require('ms'); + +/** + * The currently active debug mode names, and names to skip. + */ + +exports.names = []; +exports.skips = []; + +/** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lowercased letter, i.e. "n". + */ + +exports.formatters = {}; + +/** + * Previously assigned color. + */ + +var prevColor = 0; + +/** + * Previous log timestamp. + */ + +var prevTime; + +/** + * Select a color. + * + * @return {Number} + * @api private + */ + +function selectColor() { + return exports.colors[prevColor++ % exports.colors.length]; +} + +/** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + +function debug(namespace) { + + // define the `disabled` version + function disabled() { + } + disabled.enabled = false; + + // define the `enabled` version + function enabled() { + + var self = enabled; + + // set `diff` timestamp + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + + // add the `color` if not set + if (null == self.useColors) self.useColors = exports.useColors(); + if (null == self.color && self.useColors) self.color = selectColor(); + + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + + args[0] = exports.coerce(args[0]); + + if ('string' !== typeof args[0]) { + // anything else let's inspect with %o + args = ['%o'].concat(args); + } + + // apply any `formatters` transformations + var index = 0; + args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { + // if we encounter an escaped % then don't increase the array index + if (match === '%%') return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); + + // now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + // apply env-specific formatting + args = exports.formatArgs.apply(self, args); + + var logFn = enabled.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } + enabled.enabled = true; + + var fn = exports.enabled(namespace) ? enabled : disabled; + + fn.namespace = namespace; + + return fn; +} + +/** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + +function enable(namespaces) { + exports.save(namespaces); + + var split = (namespaces || '').split(/[\s,]+/); + var len = split.length; + + for (var i = 0; i < len; i++) { + if (!split[i]) continue; // ignore empty strings + namespaces = split[i].replace(/[\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } + } +} + +/** + * Disable debug output. + * + * @api public + */ + +function disable() { + exports.enable(''); +} + +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + +function enabled(name) { + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; +} + +/** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} + +},{"ms":3}],3:[function(require,module,exports){ +/** + * Helpers. + */ + +var s = 1000 +var m = s * 60 +var h = m * 60 +var d = h * 24 +var y = d * 365.25 + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} options + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ + +module.exports = function (val, options) { + options = options || {} + var type = typeof val + if (type === 'string' && val.length > 0) { + return parse(val) + } else if (type === 'number' && isNaN(val) === false) { + return options.long ? + fmtLong(val) : + fmtShort(val) + } + throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val)) +} + +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function parse(str) { + str = String(str) + if (str.length > 10000) { + return + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str) + if (!match) { + return + } + var n = parseFloat(match[1]) + var type = (match[2] || 'ms').toLowerCase() + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y + case 'days': + case 'day': + case 'd': + return n * d + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n + default: + return undefined + } +} + +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd' + } + if (ms >= h) { + return Math.round(ms / h) + 'h' + } + if (ms >= m) { + return Math.round(ms / m) + 'm' + } + if (ms >= s) { + return Math.round(ms / s) + 's' + } + return ms + 'ms' +} + +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtLong(ms) { + return plural(ms, d, 'day') || + plural(ms, h, 'hour') || + plural(ms, m, 'minute') || + plural(ms, s, 'second') || + ms + ' ms' +} + +/** + * Pluralization helper. + */ + +function plural(ms, n, name) { + if (ms < n) { + return + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name + } + return Math.ceil(ms / n) + ' ' + name + 's' +} + +},{}],4:[function(require,module,exports){ +(function (__dirname){ +// universal module definition +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], factory); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.Decoder = factory(); + } +}(this, function () { + + var global; + + function initglobal(){ + global = this; + if (!global){ + if (typeof window != "undefined"){ + global = window; + }else if (typeof self != "undefined"){ + global = self; + }; + }; + }; + initglobal(); + + + function error(message) { + console.error(message); + console.trace(); + }; + + + function assert(condition, message) { + if (!condition) { + error(message); + }; + }; + + + return (function(){ + "use strict"; + + + + + var getModule = function(_broadwayOnHeadersDecoded, _broadwayOnPictureDecoded){ + + var window = this; + //console.log(typeof window); + + window._broadwayOnHeadersDecoded = _broadwayOnHeadersDecoded; + window._broadwayOnPictureDecoded = _broadwayOnPictureDecoded; + + var Module = { + 'print': function(text) { console.log('stdout: ' + text); }, + 'printErr': function(text) { console.log('stderr: ' + text); } + }; + + + /* + + The reason why this is all packed into one file is that this file can also function as worker. + you can integrate the file into your build system and provide the original file to be loaded into a worker. + + */ + +function d(a){throw a;}var g=void 0,i=!0,k=null,m=!1;function n(){return function(){}}var p;p||(p=eval("(function() { try { return Module || {} } catch(e) { return {} } })()"));var aa={},r;for(r in p)p.hasOwnProperty(r)&&(aa[r]=p[r]);var t="object"===typeof process&&"function"===typeof null,ba="object"===typeof window,ca="function"===typeof importScripts,da=!ba&&!t&&!ca; +if(t){p.print||(p.print=function(a){process.stdout.write(a+"\n")});p.printErr||(p.printErr=function(a){process.stderr.write(a+"\n")});var fa=(null)("fs"),ga=(null)("path");p.read=function(a,b){var a=ga.normalize(a),c=fa.readFileSync(a);!c&&a!=ga.resolve(a)&&(a=path.join(__dirname,"..","src",a),c=fa.readFileSync(a));c&&!b&&(c=c.toString());return c};p.readBinary=function(a){return p.read(a,i)};p.load=function(a){ha(read(a))};p.thisProgram=1 0) var gc = undefined")):ba||ca?(p.read=function(a){var b=new XMLHttpRequest;b.open("GET",a,m);b.send(k);return b.responseText},"undefined"!=typeof arguments&&(p.arguments=arguments),"undefined"!==typeof console?(p.print||(p.print=function(a){console.log(a)}),p.printErr||(p.printErr=function(a){console.log(a)})):p.print||(p.print= +n()),ba?window.Module=p:p.load=importScripts):d("Unknown runtime environment. Where are we?");function ha(a){eval.call(k,a)}!p.load&&p.read&&(p.load=function(a){ha(p.read(a))});p.print||(p.print=n());p.printErr||(p.printErr=p.print);p.arguments||(p.arguments=[]);p.thisProgram||(p.thisProgram="./this.program");p.print=p.print;p.fa=p.printErr;p.preRun=[];p.postRun=[];for(r in aa)aa.hasOwnProperty(r)&&(p[r]=aa[r]); +var z={Yd:function(a){ja=a},xd:function(){return ja},Tb:function(){return y},Sb:function(a){y=a},oc:function(a){switch(a){case "i1":case "i8":return 1;case "i16":return 2;case "i32":return 4;case "i64":return 8;case "float":return 4;case "double":return 8;default:return"*"===a[a.length-1]?z.ia:"i"===a[0]?(a=parseInt(a.substr(1)),w(0===a%8),a/8):0}},vd:function(a){return Math.max(z.oc(a),z.ia)},Qf:16,ng:function(a,b,c){return!c&&("i64"==a||"double"==a)?8:!a?Math.min(b,8):Math.min(b||(a?z.vd(a):0), +z.ia)},Fa:function(a,b,c){return c&&c.length?(c.splice||(c=Array.prototype.slice.call(c)),c.splice(0,0,b),p["dynCall_"+a].apply(k,c)):p["dynCall_"+a].call(k,b)},eb:[],Vc:function(a){for(var b=0;b=F&&A("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+F+", (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.");return b},ub:function(a,b){return Math.ceil(a/(b?b:16))*(b?b:16)},Fg:function(a,b,c){return c?+(a>>>0)+4294967296*+(b>>>0):+(a>>>0)+4294967296* ++(b|0)},Pc:8,ia:4,Rf:0};p.Runtime=z;z.addFunction=z.Vc;z.removeFunction=z.Sd;var H=m,la,ma,ja;function w(a,b){a||A("Assertion failed: "+b)}function na(a){var b=p["_"+a];if(!b)try{b=eval("_"+a)}catch(c){}w(b,"Cannot call unknown function "+a+" (perhaps LLVM optimizations or closure removed it?)");return b}var oa,pa; +(function(){function a(a){a=a.toString().match(e).slice(1);return{arguments:a[0],body:a[1],returnValue:a[2]}}var b={stackSave:function(){z.Tb()},stackRestore:function(){z.Sb()},arrayToC:function(a){var b=z.pb(a.length);qa(a,b);return b},stringToC:function(a){var b=0;a!==k&&(a!==g&&0!==a)&&(b=z.pb((a.length<<2)+1),ra(a,b));return b}},c={string:b.stringToC,array:b.arrayToC};pa=function(a,b,e,f){var h=na(a),s=[],a=0;if(f)for(var v=0;v>0]=b;break;case "i8":I[a>>0]=b;break;case "i16":J[a>>1]=b;break;case "i32":K[a>>2]=b;break;case "i64":ma=[b>>>0,(la=b,1<=+ta(la)?0>>0:~~+xa((la-+(~~la>>>0))/4294967296)>>>0:0)];K[a>>2]=ma[0];K[a+4>>2]=ma[1];break;case "float":ya[a>>2]=b;break;case "double":za[a>>3]=b;break;default:A("invalid type for setValue: "+c)}}p.setValue=sa; +function Aa(a,b){b=b||"i8";"*"===b.charAt(b.length-1)&&(b="i32");switch(b){case "i1":return I[a>>0];case "i8":return I[a>>0];case "i16":return J[a>>1];case "i32":return K[a>>2];case "i64":return K[a>>2];case "float":return ya[a>>2];case "double":return za[a>>3];default:A("invalid type for setValue: "+b)}return k}p.getValue=Aa;var L=2,Ba=4;p.ALLOC_NORMAL=0;p.ALLOC_STACK=1;p.ALLOC_STATIC=L;p.ALLOC_DYNAMIC=3;p.ALLOC_NONE=Ba; +function M(a,b,c,e){var f,h;"number"===typeof a?(f=i,h=a):(f=m,h=a.length);var j="string"===typeof b?b:k,c=c==Ba?e:[Ca,z.pb,z.Ec,z.bb][c===g?L:c](Math.max(h,j?1:b.length));if(f){e=c;w(0==(c&3));for(a=c+(h&-4);e>2]=0;for(a=c+h;e>0]=0;return c}if("i8"===j)return a.subarray||a.slice?N.set(a,c):N.set(new Uint8Array(a),c),c;for(var e=0,l,u;e>0];if(128<=e)c=i;else if(0==e&&!b)break;f++;if(b&&f==b)break}b||(b=f);var h="";if(!c){for(;0>0],h+=c.nb(e);return h}p.Pointer_stringify=ka;p.UTF16ToString=function(a){for(var b=0,c="";;){var e=J[a+2*b>>1];if(0==e)return c;++b;c+=String.fromCharCode(e)}}; +p.stringToUTF16=function(a,b){for(var c=0;c>1]=a.charCodeAt(c);J[b+2*a.length>>1]=0};p.UTF32ToString=function(a){for(var b=0,c="";;){var e=K[a+4*b>>2];if(0==e)return c;++b;65536<=e?(e-=65536,c+=String.fromCharCode(55296|e>>10,56320|e&1023)):c+=String.fromCharCode(e)}};p.stringToUTF32=function(a,b){for(var c=0,e=0;e=f)var h=a.charCodeAt(++e),f=65536+((f&1023)<<10)|h&1023;K[b+4*c>>2]=f;++c}K[b+4*c>>2]=0}; +function Da(a){function b(c,e,f){var e=e||Infinity,h="",j=[],s;if("N"===a[l]){l++;"K"===a[l]&&l++;for(s=[];"E"!==a[l];)if("S"===a[l]){l++;var C=a.indexOf("_",l);s.push(q[a.substring(l,C)||0]||"?");l=C+1}else if("C"===a[l])s.push(s[s.length-1]),l+=2;else{var C=parseInt(a.substr(l)),P=C.toString().length;if(!C||!P){l--;break}var sb=a.substr(l+P,C);s.push(sb);q.push(sb);l+=P+C}l++;s=s.join("::");e--;if(0===e)return c?[s]:s}else if(("K"===a[l]||x&&"L"===a[l])&&l++,C=parseInt(a.substr(l)))P=C.toString().length, +s=a.substr(l+P,C),l+=P+C;x=m;"I"===a[l]?(l++,C=b(i),P=b(i,1,i),h+=P[0]+" "+s+"<"+C.join(", ")+">"):h=s;a:for(;lO?2*O:O+16777216; +O!==F&&(p.fa("increasing TOTAL_MEMORY to "+O+" to be compliant with the asm.js spec"),F=O);w("undefined"!==typeof Int32Array&&"undefined"!==typeof Float64Array&&!!(new Int32Array(1)).subarray&&!!(new Int32Array(1)).set,"JS engine does not provide full typed array support");var Q=new ArrayBuffer(F);I=new Int8Array(Q);J=new Int16Array(Q);K=new Int32Array(Q);N=new Uint8Array(Q);Ga=new Uint16Array(Q);Ha=new Uint32Array(Q);ya=new Float32Array(Q);za=new Float64Array(Q);K[0]=255;w(255===N[0]&&0===N[3],"Typed arrays 2 must be run on a little-endian system"); +p.HEAP=g;p.buffer=Q;p.HEAP8=I;p.HEAP16=J;p.HEAP32=K;p.HEAPU8=N;p.HEAPU16=Ga;p.HEAPU32=Ha;p.HEAPF32=ya;p.HEAPF64=za;function Na(a){for(;0>0]=a[c],c+=1}p.writeStringToMemory=ra;function qa(a,b){for(var c=0;c>0]=a[c]}p.writeArrayToMemory=qa; +p.writeAsciiToMemory=function(a,b,c){for(var e=0;e>0]=a.charCodeAt(e);c||(I[b+a.length>>0]=0)};if(!Math.imul||-5!==Math.imul(4294967295,5))Math.imul=function(a,b){var c=a&65535,e=b&65535;return c*e+((a>>>16)*e+c*(b>>>16)<<16)|0};Math.vg=Math.imul;var ta=Math.abs,xa=Math.ceil,wa=Math.floor,va=Math.min,S=0,Wa=k,Xa=k;function Ya(){S++;p.monitorRunDependencies&&p.monitorRunDependencies(S)}p.addRunDependency=Ya; +function Za(){S--;p.monitorRunDependencies&&p.monitorRunDependencies(S);if(0==S&&(Wa!==k&&(clearInterval(Wa),Wa=k),Xa)){var a=Xa;Xa=k;a()}}p.removeRunDependency=Za;p.preloadedImages={};p.preloadedAudios={};var T=k,Ia=8,D=Ia+7808;R.push(); +M([0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,0,0,0,0,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,0,0,0,0,10,0,0,0,13,0,0,0,16,0,0,0,11,0,0,0,14,0,0,0,18,0,0,0,13,0,0,0,16,0,0,0,20,0,0,0,14,0,0,0,18,0,0,0,23,0,0,0,16,0,0,0,20,0,0,0,25,0,0,0,18,0,0,0,23,0,0,0,29,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0, +0,0,14,0,0,0,15,0,0,0,16,0,0,0,17,0,0,0,18,0,0,0,19,0,0,0,20,0,0,0,21,0,0,0,22,0,0,0,23,0,0,0,24,0,0,0,25,0,0,0,26,0,0,0,27,0,0,0,28,0,0,0,29,0,0,0,29,0,0,0,30,0,0,0,31,0,0,0,32,0,0,0,32,0,0,0,33,0,0,0,34,0,0,0,34,0,0,0,35,0,0,0,35,0,0,0,36,0,0,0,36,0,0,0,37,0,0,0,37,0,0,0,37,0,0,0,38,0,0,0,38,0,0,0,38,0,0,0,39,0,0,0,39,0,0,0,39,0,0,0,39,0,0,0,1,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,16,0,0,0,32,0,0,0,64,0,0,0,128,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,1,0,0,0,4,0,0, +0,5,0,0,0,2,0,0,0,3,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,12,0,0,0,13,0,0,0,10,0,0,0,11,0,0,0,14,0,0,0,15,0,0,0,47,31,15,0,23,27,29,30,7,11,13,14,39,43,45,46,16,3,5,10,12,19,21,26,28,35,37,42,44,1,2,4,8,17,18,20,24,6,9,22,25,32,33,34,36,40,38,41,0,16,1,2,4,8,32,3,5,10,12,15,47,7,11,13,14,6,9,31,35,37,42,44,33,34,36,40,39,43,45,46,17,18,20,24,19,21,26,28,23,27,29,30,22,25,38,41,17,1,0,0,0,0,0,0,34,18,1,1,0,0,0,0,50,34,18,2,0,0,0,0,67,51,34,34,18,18,2,2,83,67,51,35,18,18,2,2,19,35,67,51,99,83,2,2,0, +0,101,85,68,68,52,52,35,35,35,35,19,19,19,19,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,249,233,217,200,200,184,184,167,167,167,167,151,151,151,151,134,134,134,134,134,134,134,134,118,118,118,118,118,118,118,118,230,214,198,182,165,165,149,149,132,132,132,132,116,116,116,116,100,100,100,100,84,84,84,84,67,67,67,67,67,67,67,67,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,19,19,19,19,19,19,19,19,3,3,3,3,3,3,3,3,214,182,197,197,165,165,149,149,132,132,132,132,84,84,84,84,68,68,68,68,4,4,4,4,115,115,115,115, +115,115,115,115,99,99,99,99,99,99,99,99,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,19,19,19,19,19,19,19,19,197,181,165,5,148,148,116,116,52,52,36,36,131,131,131,131,99,99,99,99,83,83,83,83,67,67,67,67,19,19,19,19,181,149,164,164,132,132,36,36,20,20,4,4,115,115,115,115,99,99,99,99,83,83,83,83,67,67,67,67,51,51,51,51,166,6,21,21,132,132,132,132,147,147,147,147,147,147,147,147,115,115,115,115,115,115,115,115,99,99,99,99,99,99,99,99,83,83,83,83,83,83,83,83,67,67,67,67,67,67,67,67,51,51,51,51,51, +51,51,51,35,35,35,35,35,35,35,35,150,6,21,21,116,116,116,116,131,131,131,131,131,131,131,131,99,99,99,99,99,99,99,99,67,67,67,67,67,67,67,67,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,134,6,37,37,20,20,20,20,115,115,115,115,115,115,115,115,99,99,99,99,99,99,99,99,51,51,51,51,51,51,51,51,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,22,6,117,117,36,36,36,36,83,83,83,83,83,83,83,83,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,21,5,100,100,35,35,35,35,82,82,82,82,82,82,82,82,66,66,66,66,66,66,66,66,50,50,50,50,50,50,50,50,4,20,35,35,51,51,83,83,65,65,65,65,65,65,65,65,4,20,67,67,34,34,34,34,49,49,49,49,49,49,49,49,3,19,50,50,33,33,33,33,2,18,33,33,0,0,0,0,0,0,0,0,0,0,102,32,38,16,6,8,101,24,101,24,67,16,67,16,67,16,67,16,67,16,67,16,67,16,67,16,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34, +8,34,8,34,8,34,8,34,8,34,8,34,8,0,0,0,0,0,0,0,0,106,64,74,48,42,40,10,32,105,56,105,56,73,40,73,40,41,32,41,32,9,24,9,24,104,48,104,48,104,48,104,48,72,32,72,32,72,32,72,32,40,24,40,24,40,24,40,24,8,16,8,16,8,16,8,16,103,40,103,40,103,40,103,40,103,40,103,40,103,40,103,40,71,24,71,24,71,24,71,24,71,24,71,24,71,24,71,24,110,96,78,88,46,80,14,80,110,88,78,80,46,72,14,72,13,64,13,64,77,72,77,72,45,64,45,64,13,56,13,56,109,80,109,80,77,64,77,64,45,56,45,56,13,48,13,48,107,72,107,72,107,72,107,72,107, +72,107,72,107,72,107,72,75,56,75,56,75,56,75,56,75,56,75,56,75,56,75,56,43,48,43,48,43,48,43,48,43,48,43,48,43,48,43,48,11,40,11,40,11,40,11,40,11,40,11,40,11,40,11,40,0,0,0,0,47,104,47,104,16,128,80,128,48,128,16,120,112,128,80,120,48,120,16,112,112,120,80,112,48,112,16,104,111,112,111,112,79,104,79,104,47,96,47,96,15,96,15,96,111,104,111,104,79,96,79,96,47,88,47,88,15,88,15,88,0,0,0,0,0,0,0,0,102,56,70,32,38,32,6,16,102,48,70,24,38,24,6,8,101,40,101,40,37,16,37,16,100,32,100,32,100,32,100,32,100, +24,100,24,100,24,100,24,67,16,67,16,67,16,67,16,67,16,67,16,67,16,67,16,0,0,0,0,0,0,0,0,105,72,73,56,41,56,9,48,8,40,8,40,72,48,72,48,40,48,40,48,8,32,8,32,103,64,103,64,103,64,103,64,71,40,71,40,71,40,71,40,39,40,39,40,39,40,39,40,7,24,7,24,7,24,7,24,0,0,0,0,109,120,109,120,110,128,78,128,46,128,14,128,46,120,14,120,78,120,46,112,77,112,77,112,13,112,13,112,109,112,109,112,77,104,77,104,45,104,45,104,13,104,13,104,109,104,109,104,77,96,77,96,45,96,45,96,13,96,13,96,12,88,12,88,12,88,12,88,76,88, +76,88,76,88,76,88,44,88,44,88,44,88,44,88,12,80,12,80,12,80,12,80,108,96,108,96,108,96,108,96,76,80,76,80,76,80,76,80,44,80,44,80,44,80,44,80,12,72,12,72,12,72,12,72,107,88,107,88,107,88,107,88,107,88,107,88,107,88,107,88,75,72,75,72,75,72,75,72,75,72,75,72,75,72,75,72,43,72,43,72,43,72,43,72,43,72,43,72,43,72,43,72,11,64,11,64,11,64,11,64,11,64,11,64,11,64,11,64,107,80,107,80,107,80,107,80,107,80,107,80,107,80,107,80,75,64,75,64,75,64,75,64,75,64,75,64,75,64,75,64,43,64,43,64,43,64,43,64,43,64,43, +64,43,64,43,64,11,56,11,56,11,56,11,56,11,56,11,56,11,56,11,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,24,70,56,38,56,6,16,102,72,70,48,38,48,6,8,37,40,37,40,69,40,69,40,37,32,37,32,69,32,69,32,37,24,37,24,101,64,101,64,69,24,69,24,37,16,37,16,100,56,100,56,100,56,100,56,100,48,100,48,100,48,100,48,100,40,100,40,100,40,100,40,100,32,100,32,100,32,100,32,100,24,100,24,100,24,100,24,68,16,68,16,68,16,68,16,36,8,36,8,36,8,36,8,4,0,4,0,4,0,4,0,0,0,10,128,106,128,74,128,42,128,10,120,106,120,74,120,42,120,10, +112,106,112,74,112,42,112,10,104,41,104,41,104,9,96,9,96,73,104,73,104,41,96,41,96,9,88,9,88,105,104,105,104,73,96,73,96,41,88,41,88,9,80,9,80,104,96,104,96,104,96,104,96,72,88,72,88,72,88,72,88,40,80,40,80,40,80,40,80,8,72,8,72,8,72,8,72,104,88,104,88,104,88,104,88,72,80,72,80,72,80,72,80,40,72,40,72,40,72,40,72,8,64,8,64,8,64,8,64,7,56,7,56,7,56,7,56,7,56,7,56,7,56,7,56,7,48,7,48,7,48,7,48,7,48,7,48,7,48,7,48,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,7,40,7,40,7,40,7,40,7,40,7,40,7,40,7,40, +103,80,103,80,103,80,103,80,103,80,103,80,103,80,103,80,71,64,71,64,71,64,71,64,71,64,71,64,71,64,71,64,39,64,39,64,39,64,39,64,39,64,39,64,39,64,39,64,7,32,7,32,7,32,7,32,7,32,7,32,7,32,7,32,6,8,38,8,0,0,6,0,6,16,38,16,70,16,0,0,6,24,38,24,70,24,102,24,6,32,38,32,70,32,102,32,6,40,38,40,70,40,102,40,6,48,38,48,70,48,102,48,6,56,38,56,70,56,102,56,6,64,38,64,70,64,102,64,6,72,38,72,70,72,102,72,6,80,38,80,70,80,102,80,6,88,38,88,70,88,102,88,6,96,38,96,70,96,102,96,6,104,38,104,70,104,102,104,6,112, +38,112,70,112,102,112,6,120,38,120,70,120,102,120,6,128,38,128,70,128,102,128,0,0,67,16,2,0,2,0,33,8,33,8,33,8,33,8,103,32,103,32,72,32,40,32,71,24,71,24,39,24,39,24,6,32,6,32,6,32,6,32,6,24,6,24,6,24,6,24,6,16,6,16,6,16,6,16,102,24,102,24,102,24,102,24,38,16,38,16,38,16,38,16,6,8,6,8,6,8,6,8,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,3, +0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,3,0,0,0,19,0,0,0,1,0,0,0,18,0,0,0,0,0,0,0,17,0,0,0,4,0,0,0,16,0,0,0,3,0,0,0,23,0,0,0,1,0,0,0,22,0,0,0,0,0,0,0,21,0,0,0,4,0,0,0,20,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,4,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,12,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,4,0,0,0,13,0,0,0,255,0,0,0,8,0,0,0,1,0,0,0,19,0,0,0,2,0,0,0,18,0,0,0,4,0, +0,0,17,0,0,0,255,0,0,0,16,0,0,0,1,0,0,0,23,0,0,0,2,0,0,0,22,0,0,0,4,0,0,0,21,0,0,0,255,0,0,0,20,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,13,0,0,0,1,0,0,0,18,0,0,0,1,0,0,0,19,0,0,0,4,0,0,0,16,0,0,0,4,0,0,0,17,0,0,0,1,0,0,0,22,0,0,0,1,0,0,0,23,0,0,0,4,0,0,0,20,0,0,0,4,0,0,0,21,0,0,0,0, +0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,15,0,0,0,4,0,0,0,10,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,11,0,0,0,4,0,0,0,14,0,0,0,0,0,0,0,17,0,0,0,4,0,0,0,16,0,0,0,0,0,0,0,19,0,0,0,4,0,0,0,18,0,0,0,0,0,0,0,21,0,0,0,4,0,0,0,20,0,0,0,0,0,0,0,23,0,0,0,4,0,0,0,22,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,12,0,0,0,8,0,0,0,12,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0, +12,0,0,0,8,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,8,0,0,0,8,0,0,0,12,0,0,0,12,0,0,0,8,0,0,0,8,0,0,0,12,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108, +109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234, +235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,0,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,1,0,0,0,255,0, +0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,13,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0, +0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,4,0,0,0,2,0,0,0,10,0,0, +0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,2,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0, +0,0,4,0,0,0,9,0,0,0,255,0,0,0,12,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,4,0,0,0,13,0,0,0,255,0,0,0,8,0,0,0,1,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,4,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,255,0, +0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0, +0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,13,0,0,0,0,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0, +0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,13,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0, +0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,15,0,0,0,4,0,0,0,10,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,11,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,11,0,0,0,4,0,0,0,14,0,0, +0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0,0,0,14,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,5,6,7,8,9,10,12,13,15,17,20,22,25,28,32,36,40,45,50,56,63,71,80,90,101,113,127,144,162,182,203,226,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,3,4,4,4,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,1,0,0,1,0,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,1,1,2,1,1,2,1,2,3,1,2,3,2,2,3,2,2,4,2,3,4,2,3,4,3,3,5,3,4,6,3,4,6,4,5,7,4,5,8,4,6,9,5,7,10,6,8,11,6,8,13,7,10,14,8,11,16,9,12,18,10,13,20,11,15,23,13,17,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,69,67,79,68,69,82,32,73,78,73,84,73,65,76,73,90,65,84,73,79,78,32,70,65,73,76,69,68,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"i8",Ba,z.Pc);var $a=z.ub(M(12,"i8",L),8);w(0==$a%8); +var U={O:1,Q:2,Ef:3,De:4,ha:5,Zb:6,be:7,$e:8,V:9,oe:10,Ca:11,Of:11,Mc:12,qb:13,ye:14,mf:15,ga:16,Xb:17,Oc:18,Qa:19,Sa:20,pa:21,B:22,Ve:23,Lc:24,Nc:25,Lf:26,ze:27,hf:28,Ua:29,Bf:30,Oe:31,uf:32,ve:33,yf:34,df:42,Be:43,pe:44,Fe:45,Ge:46,He:47,Ne:48,Mf:49,Ye:50,Ee:51,te:35,af:37,ge:52,je:53,Pf:54,We:55,ke:56,le:57,ue:35,me:59,kf:60,Ze:61,If:62,jf:63,ef:64,ff:65,Af:66,bf:67,ee:68,Ff:69,qe:70,vf:71,Qe:72,we:73,ie:74,qf:76,he:77,zf:78,Ie:79,Je:80,Me:81,Le:82,Ke:83,lf:38,sb:39,Re:36,rb:40,Ta:95,tf:96,se:104, +Xe:105,fe:97,xf:91,of:88,gf:92,Cf:108,Wb:111,ce:98,re:103,Ue:101,Se:100,Jf:110,Ae:112,Yb:113,Jc:115,Hc:114,Ic:89,Pe:90,wf:93,Df:94,de:99,Te:102,Kc:106,Ra:107,Kf:109,Nf:87,xe:122,Gf:116,pf:95,cf:123,Ce:84,rf:75,ne:125,nf:131,sf:130,Hf:86},ab={"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"},bb=0;function V(a){return K[bb>>2]=a} +function cb(a,b){for(var c=0,e=a.length-1;0<=e;e--){var f=a[e];"."===f?a.splice(e,1):".."===f?(a.splice(e,1),c++):c&&(a.splice(e,1),c--)}if(b)for(;c--;c)a.unshift("..");return a}function db(a){var b="/"===a.charAt(0),c="/"===a.substr(-1),a=cb(a.split("/").filter(function(a){return!!a}),!b).join("/");!a&&!b&&(a=".");a&&c&&(a+="/");return(b?"/":"")+a} +function eb(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 W(a){if("/"===a)return"/";var b=a.lastIndexOf("/");return-1===b?a:a.substr(b+1)}function fb(){var a=Array.prototype.slice.call(arguments,0);return db(a.join("/"))}function X(a,b){return db(a+"/"+b)} +function gb(){for(var a="",b=m,c=arguments.length-1;-1<=c&&!b;c--){b=0<=c?arguments[c]:B.yb();"string"!==typeof b&&d(new TypeError("Arguments to path.resolve must be strings"));if(!b)return"";a=b+"/"+a;b="/"===b.charAt(0)}a=cb(a.split("/").filter(function(a){return!!a}),!b).join("/");return(b?"/":"")+a||"."} +function hb(a,b){function c(a){for(var b=0;bc?[]:a.slice(b,c-b+1)}for(var a=gb(a).substr(1),b=gb(b).substr(1),e=c(a.split("/")),f=c(b.split("/")),h=Math.min(e.length,f.length),j=h,l=0;la.k.length)&&(a.k=Y.ud(a),a.q=a.k.length);if(!a.k||a.k.subarray){var c=a.k?a.k.buffer.byteLength:0;c>=b||(b=Math.max(b,c*(1048576>c?2:1.125)|0),0!=c&&(b=Math.max(b,256)),c=a.k,a.k=new Uint8Array(b),0b)a.k.length=b;else for(;a.k.length=a.g.q)return 0;a=Math.min(a.g.q-f,e);w(0<=a);if(8b&&d(new B.e(U.B));return b},Ea:function(a,b,c){Y.lc(a.g,b+c);a.g.q=Math.max(a.g.q,b+c)},Ja:function(a,b,c,e,f,h,j){B.isFile(a.g.mode)||d(new B.e(U.Qa));c=a.g.k;if(!(j&2)&&(c.buffer===b||c.buffer=== +b.buffer))a=m,e=c.byteOffset;else{if(0>>0)%B.T.length},tc:function(a){var b=B.Fb(a.parent.id,a.name);a.ma=B.T[b];B.T[b]=a},uc:function(a){var b=B.Fb(a.parent.id,a.name);if(B.T[b]===a)B.T[b]=a.ma;else for(b=B.T[b];b;){if(b.ma===a){b.ma=a.ma;break}b=b.ma}},aa:function(a,b){var c=B.Gd(a);c&&d(new B.e(c,a));for(c=B.T[B.Fb(a.id,b)];c;c=c.ma){var e=c.name;if(c.parent.id===a.id&&e===b)return c}return B.ra(a,b)},createNode:function(a,b,c,e){B.Va||(B.Va=function(a,b,c,e){a|| +(a=this);this.parent=a;this.F=a.F;this.Ka=k;this.id=B.Jd++;this.name=b;this.mode=c;this.n={};this.p={};this.ob=e},B.Va.prototype={},Object.defineProperties(B.Va.prototype,{M:{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}},Dd:{get:function(){return B.J(this.mode)}},Gb:{get:function(){return B.ib(this.mode)}}}));a=new B.Va(a,b,c,e);B.tc(a);return a}, +zb:function(a){B.uc(a)},jb:function(a){return a===a.parent},ka:function(a){return!!a.Ka},isFile:function(a){return 32768===(a&61440)},J:function(a){return 16384===(a&61440)},Ia:function(a){return 40960===(a&61440)},ib:function(a){return 8192===(a&61440)},Bd:function(a){return 24576===(a&61440)},Cd:function(a){return 4096===(a&61440)},Ed:function(a){return 49152===(a&49152)},rd:{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}, +wc:function(a){var b=B.rd[a];"undefined"===typeof b&&d(Error("Unknown file open mode: "+a));return b},sd:function(a){var b=["r","w","rw"][a&2097155];a&512&&(b+="w");return b},na:function(a,b){return B.vc?0:-1!==b.indexOf("r")&&!(a.mode&292)||-1!==b.indexOf("w")&&!(a.mode&146)||-1!==b.indexOf("x")&&!(a.mode&73)?U.qb:0},Gd:function(a){var b=B.na(a,"x");return b?b:!a.n.ra?U.qb:0},Jb:function(a,b){try{return B.aa(a,b),U.Xb}catch(c){}return B.na(a,"wx")},kb:function(a,b,c){var e;try{e=B.aa(a,b)}catch(f){return f.cb}if(a= +B.na(a,"wx"))return a;if(c){if(!B.J(e.mode))return U.Sa;if(B.jb(e)||B.da(e)===B.yb())return U.ga}else if(B.J(e.mode))return U.pa;return 0},Hd:function(a,b){return!a?U.Q:B.Ia(a.mode)?U.rb:B.J(a.mode)&&(0!==(b&2097155)||b&512)?U.pa:B.na(a,B.sd(b))},Qc:4096,Kd:function(a,b){for(var b=b||B.Qc,c=a||0;c<=b;c++)if(!B.oa[c])return c;d(new B.e(U.Lc))},qa:function(a){return B.oa[a]},fc:function(a,b,c){B.Wa||(B.Wa=n(),B.Wa.prototype={},Object.defineProperties(B.Wa.prototype,{object:{get:function(){return this.g}, +set:function(a){this.g=a}},yg:{get:function(){return 1!==(this.D&2097155)}},zg:{get:function(){return 0!==(this.D&2097155)}},xg:{get:function(){return this.D&1024}}}));var e=new B.Wa,f;for(f in a)e[f]=a[f];a=e;b=B.Kd(b,c);a.C=b;return B.oa[b]=a},dd:function(a){B.oa[a]=k},pc:function(a){return B.oa[a-1]},Eb:function(a){return a?a.C+1:0},bd:{open:function(a){a.p=B.td(a.g.ob).p;a.p.open&&a.p.open(a)},$:function(){d(new B.e(U.Ua))}},Ib:function(a){return a>>8},Gg:function(a){return a&255},la:function(a, +b){return a<<8|b},Ob:function(a,b){B.ic[a]={p:b}},td:function(a){return B.ic[a]},nc:function(a){for(var b=[],a=[a];a.length;){var c=a.pop();b.push(c);a.push.apply(a,c.La)}return b},Fc:function(a,b){function c(a){if(a){if(!c.pd)return c.pd=i,b(a)}else++f>=e.length&&b(k)}"function"===typeof a&&(b=a,a=m);var e=B.nc(B.root.F),f=0;e.forEach(function(b){if(!b.type.Fc)return c(k);b.type.Fc(b,a,c)})},F:function(a,b,c){var e="/"===c,f=!c,h;e&&B.root&&d(new B.e(U.ga));!e&&!f&&(h=B.u(c,{Bb:m}),c=h.path,h=h.g, +B.ka(h)&&d(new B.e(U.ga)),B.J(h.mode)||d(new B.e(U.Sa)));b={type:a,Kg:b,Id:c,La:[]};a=a.F(b);a.F=b;b.root=a;e?B.root=a:h&&(h.Ka=b,h.F&&h.F.La.push(b));return a},Qg:function(a){a=B.u(a,{Bb:m});B.ka(a.g)||d(new B.e(U.B));var a=a.g,b=a.Ka,c=B.nc(b);Object.keys(B.T).forEach(function(a){for(a=B.T[a];a;){var b=a.ma;-1!==c.indexOf(a.F)&&B.zb(a);a=b}});a.Ka=k;b=a.F.La.indexOf(b);w(-1!==b);a.F.La.splice(b,1)},ra:function(a,b){return a.n.ra(a,b)},ba:function(a,b,c){var e=B.u(a,{parent:i}).g,a=W(a);(!a||"."=== +a||".."===a)&&d(new B.e(U.B));var f=B.Jb(e,a);f&&d(new B.e(f));e.n.ba||d(new B.e(U.O));return e.n.ba(e,a,b,c)},create:function(a,b){b=(b!==g?b:438)&4095;b|=32768;return B.ba(a,b,0)},ea:function(a,b){b=(b!==g?b:511)&1023;b|=16384;return B.ba(a,b,0)},lb:function(a,b,c){"undefined"===typeof c&&(c=b,b=438);return B.ba(a,b|8192,c)},ca:function(a,b){gb(a)||d(new B.e(U.Q));var c=B.u(b,{parent:i}).g;c||d(new B.e(U.Q));var e=W(b),f=B.Jb(c,e);f&&d(new B.e(f));c.n.ca||d(new B.e(U.O));return c.n.ca(c,e,a)},rename:function(a, +b){var c=eb(a),e=eb(b),f=W(a),h=W(b),j,l,u;try{j=B.u(a,{parent:i}),l=j.g,j=B.u(b,{parent:i}),u=j.g}catch(q){d(new B.e(U.ga))}(!l||!u)&&d(new B.e(U.Q));l.F!==u.F&&d(new B.e(U.Oc));j=B.aa(l,f);e=hb(a,e);"."!==e.charAt(0)&&d(new B.e(U.B));e=hb(b,c);"."!==e.charAt(0)&&d(new B.e(U.sb));var x;try{x=B.aa(u,h)}catch(s){}if(j!==x){c=B.J(j.mode);(f=B.kb(l,f,c))&&d(new B.e(f));(f=x?B.kb(u,h,c):B.Jb(u,h))&&d(new B.e(f));l.n.rename||d(new B.e(U.O));(B.ka(j)||x&&B.ka(x))&&d(new B.e(U.ga));u!==l&&(f=B.na(l,"w"))&& +d(new B.e(f));try{B.H.willMovePath&&B.H.willMovePath(a,b)}catch(v){console.log("FS.trackingDelegate['willMovePath']('"+a+"', '"+b+"') threw an exception: "+v.message)}B.uc(j);try{l.n.rename(j,u,h)}catch(G){d(G)}finally{B.tc(j)}try{if(B.H.onMovePath)B.H.onMovePath(a,b)}catch(ua){console.log("FS.trackingDelegate['onMovePath']('"+a+"', '"+b+"') threw an exception: "+ua.message)}}},Oa:function(a){var b=B.u(a,{parent:i}).g,c=W(a),e=B.aa(b,c),f=B.kb(b,c,i);f&&d(new B.e(f));b.n.Oa||d(new B.e(U.O));B.ka(e)&& +d(new B.e(U.ga));try{B.H.willDeletePath&&B.H.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.n.Oa(b,c);B.zb(e);try{if(B.H.onDeletePath)B.H.onDeletePath(a)}catch(j){console.log("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+j.message)}},Na:function(a){a=B.u(a,{R:i}).g;a.n.Na||d(new B.e(U.Sa));return a.n.Na(a)},za:function(a){var b=B.u(a,{parent:i}).g,c=W(a),e=B.aa(b,c),f=B.kb(b,c,m);f&&(f===U.pa&&(f=U.O), +d(new B.e(f)));b.n.za||d(new B.e(U.O));B.ka(e)&&d(new B.e(U.ga));try{B.H.willDeletePath&&B.H.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.n.za(b,c);B.zb(e);try{if(B.H.onDeletePath)B.H.onDeletePath(a)}catch(j){console.log("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+j.message)}},ta:function(a){(a=B.u(a).g)||d(new B.e(U.Q));a.n.ta||d(new B.e(U.B));return a.n.ta(a)},Dc:function(a,b){var c=B.u(a,{R:!b}).g; +c||d(new B.e(U.Q));c.n.S||d(new B.e(U.O));return c.n.S(c)},Eg:function(a){return B.Dc(a,i)},Ya:function(a,b,c){a="string"===typeof a?B.u(a,{R:!c}).g:a;a.n.I||d(new B.e(U.O));a.n.I(a,{mode:b&4095|a.mode&-4096,timestamp:Date.now()})},Bg:function(a,b){B.Ya(a,b,i)},jg:function(a,b){var c=B.qa(a);c||d(new B.e(U.V));B.Ya(c.g,b)},dc:function(a,b,c,e){a="string"===typeof a?B.u(a,{R:!e}).g:a;a.n.I||d(new B.e(U.O));a.n.I(a,{timestamp:Date.now()})},Cg:function(a,b,c){B.dc(a,b,c,i)},kg:function(a,b,c){(a=B.qa(a))|| +d(new B.e(U.V));B.dc(a.g,b,c)},truncate:function(a,b){0>b&&d(new B.e(U.B));var c;c="string"===typeof a?B.u(a,{R:i}).g:a;c.n.I||d(new B.e(U.O));B.J(c.mode)&&d(new B.e(U.pa));B.isFile(c.mode)||d(new B.e(U.B));var e=B.na(c,"w");e&&d(new B.e(e));c.n.I(c,{size:b,timestamp:Date.now()})},mg:function(a,b){var c=B.qa(a);c||d(new B.e(U.V));0===(c.D&2097155)&&d(new B.e(U.B));B.truncate(c.g,b)},Rg:function(a,b,c){a=B.u(a,{R:i}).g;a.n.I(a,{timestamp:Math.max(b,c)})},open:function(a,b,c,e,f){""===a&&d(new B.e(U.Q)); +var b="string"===typeof b?B.wc(b):b,c=b&64?("undefined"===typeof c?438:c)&4095|32768:0,h;if("object"===typeof a)h=a;else{a=db(a);try{h=B.u(a,{R:!(b&131072)}).g}catch(j){}}var l=m;b&64&&(h?b&128&&d(new B.e(U.Xb)):(h=B.ba(a,c,0),l=i));h||d(new B.e(U.Q));B.ib(h.mode)&&(b&=-513);l||(c=B.Hd(h,b))&&d(new B.e(c));b&512&&B.truncate(h,0);b&=-641;e=B.fc({g:h,path:B.da(h),D:b,seekable:i,position:0,p:h.p,$d:[],error:m},e,f);e.p.open&&e.p.open(e);p.logReadFiles&&!(b&1)&&(B.Mb||(B.Mb={}),a in B.Mb||(B.Mb[a]=1, +p.printErr("read file: "+a)));try{B.H.onOpenFile&&(f=0,1!==(b&2097155)&&(f|=B.Gc.yc.Rc),0!==(b&2097155)&&(f|=B.Gc.yc.Sc),B.H.onOpenFile(a,f))}catch(u){console.log("FS.trackingDelegate['onOpenFile']('"+a+"', flags) threw an exception: "+u.message)}return e},close:function(a){try{a.p.close&&a.p.close(a)}catch(b){d(b)}finally{B.dd(a.C)}},$:function(a,b,c){(!a.seekable||!a.p.$)&&d(new B.e(U.Ua));a.position=a.p.$(a,b,c);a.$d=[];return a.position},M:function(a,b,c,e,f){(0>e||0>f)&&d(new B.e(U.B));1===(a.D& +2097155)&&d(new B.e(U.V));B.J(a.g.mode)&&d(new B.e(U.pa));a.p.M||d(new B.e(U.B));var h=i;"undefined"===typeof f?(f=a.position,h=m):a.seekable||d(new B.e(U.Ua));b=a.p.M(a,b,c,e,f);h||(a.position+=b);return b},write:function(a,b,c,e,f,h){(0>e||0>f)&&d(new B.e(U.B));0===(a.D&2097155)&&d(new B.e(U.V));B.J(a.g.mode)&&d(new B.e(U.pa));a.p.write||d(new B.e(U.B));a.D&1024&&B.$(a,0,2);var j=i;"undefined"===typeof f?(f=a.position,j=m):a.seekable||d(new B.e(U.Ua));b=a.p.write(a,b,c,e,f,h);j||(a.position+=b); +try{if(a.path&&B.H.onWriteToFile)B.H.onWriteToFile(a.path)}catch(l){console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: "+l.message)}return b},Ea:function(a,b,c){(0>b||0>=c)&&d(new B.e(U.B));0===(a.D&2097155)&&d(new B.e(U.V));!B.isFile(a.g.mode)&&!B.J(node.mode)&&d(new B.e(U.Qa));a.p.Ea||d(new B.e(U.Ta));a.p.Ea(a,b,c)},Ja:function(a,b,c,e,f,h,j){1===(a.D&2097155)&&d(new B.e(U.qb));a.p.Ja||d(new B.e(U.Qa));return a.p.Ja(a,b,c,e,f,h,j)},Ha:function(a,b,c){a.p.Ha||d(new B.e(U.Nc)); +return a.p.Ha(a,b,c)},Mg:function(a,b){b=b||{};b.D=b.D||"r";b.encoding=b.encoding||"binary";"utf8"!==b.encoding&&"binary"!==b.encoding&&d(Error('Invalid encoding type "'+b.encoding+'"'));var c,e=B.open(a,b.D),f=B.Dc(a).size,h=new Uint8Array(f);B.M(e,h,0,f,0);if("utf8"===b.encoding){c="";for(var j=new z.Da,l=0;l>2]=B.Eb(a);w(0===a.C,"invalid handle for stdin ("+a.C+")");a=B.open("/dev/stdout","w");K[pb>>2]=B.Eb(a);w(1===a.C,"invalid handle for stdout ("+a.C+")");a=B.open("/dev/stderr","w");K[qb>>2]=B.Eb(a);w(2===a.C,"invalid handle for stderr ("+a.C+")")},jc:function(){B.e||(B.e=function(a,b){this.g=b;this.Xd=function(a){this.cb=a;for(var b in U)if(U[b]=== +a){this.code=b;break}};this.Xd(a);this.message=ab[a]},B.e.prototype=Error(),[U.Q].forEach(function(a){B.Db[a]=new B.e(a);B.Db[a].stack=""}))},Zd:function(){B.jc();B.T=Array(4096);B.F(Y,{},"/");B.fd();B.ed()},Ga:function(a,b,c){w(!B.Ga.hb,"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)");B.Ga.hb=i;B.jc();p.stdin=a||p.stdin;p.stdout=b||p.stdout;p.stderr= +c||p.stderr;B.od()},Qd:function(){B.Ga.hb=m;for(var a=0;athis.length-1||0>a)){var b=a%this.cd;return this.yd(a/ +this.cd|0)[b]}};h.prototype.Wd=function(a){this.yd=a};h.prototype.bc=function(){var a=new XMLHttpRequest;a.open("HEAD",c,m);a.send(k);200<=a.status&&300>a.status||304===a.status||d(Error("Couldn't load "+c+". Status: "+a.status));var b=Number(a.getResponseHeader("Content-length")),e,f=1048576;if(!((e=a.getResponseHeader("Accept-Ranges"))&&"bytes"===e))f=b;var h=this;h.Wd(function(a){var e=a*f,j=(a+1)*f-1,j=Math.min(j,b-1);if("undefined"===typeof h.Za[a]){var l=h.Za;e>j&&d(Error("invalid range ("+ +e+", "+j+") or no bytes requested!"));j>b-1&&d(Error("only "+b+" bytes available! programmer error!"));var q=new XMLHttpRequest;q.open("GET",c,m);b!==f&&q.setRequestHeader("Range","bytes="+e+"-"+j);"undefined"!=typeof Uint8Array&&(q.responseType="arraybuffer");q.overrideMimeType&&q.overrideMimeType("text/plain; charset=x-user-defined");q.send(k);200<=q.status&&300>q.status||304===q.status||d(Error("Couldn't load "+c+". Status: "+q.status));e=q.response!==g?new Uint8Array(q.response||[]):Va(q.responseText|| +"",i);l[a]=e}"undefined"===typeof h.Za[a]&&d(Error("doXHR failed!"));return h.Za[a]});this.Uc=b;this.Tc=f;this.Hb=i};if("undefined"!==typeof XMLHttpRequest){ca||d("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc");var j=new h;Object.defineProperty(j,"length",{get:function(){this.Hb||this.bc();return this.Uc}});Object.defineProperty(j,"chunkSize",{get:function(){this.Hb||this.bc();return this.Tc}});j={Gb:m,k:j}}else j={Gb:m,url:c}; +var l=B.gd(a,b,j,e,f);j.k?l.k=j.k:j.url&&(l.k=k,l.url=j.url);Object.defineProperty(l,"usedBytes",{get:function(){return this.k.length}});var u={};Object.keys(l.p).forEach(function(a){var b=l.p[a];u[a]=function(){B.mc(l)||d(new B.e(U.ha));return b.apply(k,arguments)}});u.M=function(a,b,c,e,f){B.mc(l)||d(new B.e(U.ha));a=a.g.k;if(f>=a.length)return 0;e=Math.min(a.length-f,e);w(0<=e);if(a.slice)for(var h=0;h>h-6&63,h=h-6,c=c+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[q]}2==h?(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&3)<<4],c+="=="):4==h&&(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&15)<<2],c+="="); +s.src="data:audio/x-"+b.substr(-3)+";base64,"+c;f(s)}};s.src=l;p.noExitRuntime=i;setTimeout(function(){H||f(s)},1E4)}else return h()}});var v=p.canvas;v&&(v.Pb=v.requestPointerLock||v.mozRequestPointerLock||v.webkitRequestPointerLock||v.msRequestPointerLock||n(),v.kc=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock||document.msExitPointerLock||n(),v.kc=v.kc.bind(document),document.addEventListener("pointerlockchange",q,m),document.addEventListener("mozpointerlockchange", +q,m),document.addEventListener("webkitpointerlockchange",q,m),document.addEventListener("mspointerlockchange",q,m),p.elementPointerLock&&v.addEventListener("click",function(a){!rb&&v.Pb&&(v.Pb(),a.preventDefault())},m))}var G=b?gb(X(a,b)):a;Ya();"string"==typeof c?yb(c,function(a){x(a)},j):x(c)},indexedDB:function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},Ub:function(){return"EM_FS_"+window.location.pathname},Vb:20,Ba:"FILE_DATA",Og:function(a,b,c){var b= +b||n(),c=c||n(),e=B.indexedDB();try{var f=e.open(B.Ub(),B.Vb)}catch(h){return c(h)}f.Ld=function(){console.log("creating db");f.result.createObjectStore(B.Ba)};f.onsuccess=function(){var e=f.result.transaction([B.Ba],"readwrite"),h=e.objectStore(B.Ba),u=0,q=0,x=a.length;a.forEach(function(a){a=h.put(B.vb(a).object.k,a);a.onsuccess=function(){u++;u+q==x&&(0==q?b():c())};a.onerror=function(){q++;u+q==x&&(0==q?b():c())}});e.onerror=c};f.onerror=c},Dg:function(a,b,c){var b=b||n(),c=c||n(),e=B.indexedDB(); +try{var f=e.open(B.Ub(),B.Vb)}catch(h){return c(h)}f.Ld=c;f.onsuccess=function(){var e=f.result;try{var h=e.transaction([B.Ba],"readonly")}catch(u){c(u);return}var q=h.objectStore(B.Ba),x=0,s=0,v=a.length;a.forEach(function(a){var e=q.get(a);e.onsuccess=function(){B.vb(a).Ab&&B.za(a);B.xb(eb(a),W(a),e.result,i,i,i);x++;x+s==v&&(0==s?b():c())};e.onerror=function(){s++;x+s==v&&(0==s?b():c())}});h.onerror=c};f.onerror=c}};function zb(){d("TODO")} +var Z={F:function(){p.websocket=p.websocket&&"object"===typeof p.websocket?p.websocket:{};p.websocket.tb={};p.websocket.on=function(a,b){"function"===typeof b&&(this.tb[a]=b);return this};p.websocket.P=function(a,b){"function"===typeof this.tb[a]&&this.tb[a].call(this,b)};return B.createNode(k,"/",16895,0)},nd:function(a,b,c){c&&w(1==b==(6==c));a={qd:a,type:b,protocol:c,G:k,error:k,Ma:{},Kb:[],ua:[],wa:Z.L};b=Z.mb();c=B.createNode(Z.root,b,49152,0);c.va=a;b=B.fc({path:b,g:c,D:B.wc("r+"),seekable:m, +p:Z.p});a.A=b;return a},wd:function(a){a=B.qa(a);return!a||!B.Ed(a.g.mode)?k:a.g.va},p:{zc:function(a){a=a.g.va;return a.wa.zc(a)},Ha:function(a,b,c){a=a.g.va;return a.wa.Ha(a,b,c)},M:function(a,b,c,e){a=a.g.va;e=a.wa.Rd(a,e);if(!e)return 0;b.set(e.buffer,c);return e.buffer.length},write:function(a,b,c,e){a=a.g.va;return a.wa.Vd(a,b,c,e)},close:function(a){a=a.g.va;a.wa.close(a)}},mb:function(){Z.mb.gc||(Z.mb.gc=0);return"socket["+Z.mb.gc++ +"]"},L:{$a:function(a,b,c){var e;"object"===typeof b&&(e= +b,c=b=k);if(e)e._socket?(b=e._socket.remoteAddress,c=e._socket.remotePort):((c=/ws[s]?:\/\/([^:]+):(\d+)/.exec(e.url))||d(Error("WebSocket URL must be in the format ws(s)://address:port")),b=c[1],c=parseInt(c[2],10));else try{var f=p.websocket&&"object"===typeof p.websocket,h="ws:#".replace("#","//");f&&"string"===typeof p.websocket.url&&(h=p.websocket.url);if("ws://"===h||"wss://"===h)var j=b.split("/"),h=h+j[0]+":"+c+"/"+j.slice(1).join("/");j="binary";f&&"string"===typeof p.websocket.subprotocol&& +(j=p.websocket.subprotocol);var j=j.replace(/^ +| +$/g,"").split(/ *, */),l=t?{protocol:j.toString()}:j;e=new (t?(null)("ws"):window.WebSocket)(h,l);e.binaryType="arraybuffer"}catch(u){d(new B.e(U.Yb))}b={W:b,port:c,o:e,ab:[]};Z.L.$b(a,b);Z.L.zd(a,b);2===a.type&&"undefined"!==typeof a.ya&&b.ab.push(new Uint8Array([255,255,255,255,112,111,114,116,(a.ya&65280)>>8,a.ya&255]));return b},gb:function(a,b,c){return a.Ma[b+":"+c]},$b:function(a,b){a.Ma[b.W+":"+b.port]=b},Bc:function(a,b){delete a.Ma[b.W+ +":"+b.port]},zd:function(a,b){function c(){p.websocket.P("open",a.A.C);try{for(var c=b.ab.shift();c;)b.o.send(c),c=b.ab.shift()}catch(e){b.o.close()}}function e(c){w("string"!==typeof c&&c.byteLength!==g);var c=new Uint8Array(c),e=f;f=m;e&&10===c.length&&255===c[0]&&255===c[1]&&255===c[2]&&255===c[3]&&112===c[4]&&111===c[5]&&114===c[6]&&116===c[7]?(c=c[8]<<8|c[9],Z.L.Bc(a,b),b.port=c,Z.L.$b(a,b)):(a.ua.push({W:b.W,port:b.port,data:c}),p.websocket.P("message",a.A.C))}var f=i;t?(b.o.on("open",c),b.o.on("message", +function(a,b){b.binary&&e((new Uint8Array(a)).buffer)}),b.o.on("close",function(){p.websocket.P("close",a.A.C)}),b.o.on("error",function(){a.error=U.Wb;p.websocket.P("error",[a.A.C,a.error,"ECONNREFUSED: Connection refused"])})):(b.o.onopen=c,b.o.onclose=function(){p.websocket.P("close",a.A.C)},b.o.onmessage=function(a){e(a.data)},b.o.onerror=function(){a.error=U.Wb;p.websocket.P("error",[a.A.C,a.error,"ECONNREFUSED: Connection refused"])})},zc:function(a){if(1===a.type&&a.G)return a.Kb.length?65: +0;var b=0,c=1===a.type?Z.L.gb(a,a.Y,a.Z):k;if(a.ua.length||!c||c&&c.o.readyState===c.o.Pa||c&&c.o.readyState===c.o.CLOSED)b|=65;if(!c||c&&c.o.readyState===c.o.OPEN)b|=4;if(c&&c.o.readyState===c.o.Pa||c&&c.o.readyState===c.o.CLOSED)b|=16;return b},Ha:function(a,b,c){switch(b){case 21531:return b=0,a.ua.length&&(b=a.ua[0].data.length),K[c>>2]=b,0;default:return U.B}},close:function(a){if(a.G){try{a.G.close()}catch(b){}a.G=k}for(var c=Object.keys(a.Ma),e=0;e>0]=c;if(-1==Ab(Cb(b),Eb.Cc,1)){if(c=B.pc(b))c.error=i;return-1}return c}function Fb(a){Fb.$c||(E=E+4095&-4096,Fb.$c=i,w(z.bb),Fb.Wc=z.bb,z.bb=function(){A("cannot dynamically allocate, sbrk now has control")});var b=E;0!=a&&Fb.Wc(a);return b}p._memset=Gb;function Hb(a,b,c){window._broadwayOnPictureDecoded(a,b,c)}p._broadwayOnPictureDecoded=Hb;function Ib(){window._broadwayOnHeadersDecoded()}p._broadwayOnHeadersDecoded=Ib; +function Jb(a,b){Kb=a;Lb=b;if(!Mb)return 1;0==a?(Nb=function(){setTimeout(Ob,b)},Pb="timeout"):1==a&&(Nb=function(){Qb(Ob)},Pb="rAF");return 0} +function Rb(a,b,c,e){p.noExitRuntime=i;w(!Mb,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");Mb=a;Sb=e;var f=Tb;Ob=function(){if(!H)if(0=bc;)bc+=1E3/60;b=Math.max(bc-b,0);setTimeout(a,b)}function Qb(a){"undefined"===typeof window?cc(a):(window.requestAnimationFrame||(window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||cc),window.requestAnimationFrame(a))} +function xb(a){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",bmp:"image/bmp",ogg:"audio/ogg",wav:"audio/wav",mp3:"audio/mpeg"}[a.substr(a.lastIndexOf(".")+1)]} +function yb(a,b,c){function e(){c?c():d('Loading data file "'+a+'" failed.')}var f=new XMLHttpRequest;f.open("GET",a,i);f.responseType="arraybuffer";f.onload=function(){if(200==f.status||0==f.status&&f.response){var c=f.response;w(c,'Loading data file "'+a+'" failed (no arrayBuffer).');b(new Uint8Array(c));Za()}else e()};f.onerror=e;f.send(k);Ya()}var dc=[];function ec(){var a=p.canvas;dc.forEach(function(b){b(a.width,a.height)})} +function fc(a,b,c){b&&c?(a.ae=b,a.Ad=c):(b=a.ae,c=a.Ad);var e=b,f=c;p.forcedAspectRatio&&0>2]=0;R.unshift({ja:n()});Qa.push({ja:n()});var lb=new z.Da;t&&((null)("fs"),process.platform.match(/^win/));R.push({ja:function(){Z.root=B.F(Z,{},k)}}); +Eb.Cc=M([0],"i8",L); +p.requestFullScreen=function(a,b){function c(){Yb=m;var a=e.parentNode;(document.webkitFullScreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.mozFullscreenElement||document.fullScreenElement||document.fullscreenElement||document.msFullScreenElement||document.msFullscreenElement||document.webkitCurrentFullScreenElement)===a?(e.cc=document.cancelFullScreen||document.mozCancelFullScreen||document.webkitCancelFullScreen||document.msExitFullscreen||document.exitFullscreen|| +n(),e.cc=e.cc.bind(document),$b&&e.Pb(),Yb=i,ac&&("undefined"!=typeof SDL&&(a=Ha[SDL.screen+0*z.ia>>2],K[SDL.screen+0*z.ia>>2]=a|8388608),ec())):(a.parentNode.insertBefore(e,a),a.parentNode.removeChild(a),ac&&("undefined"!=typeof SDL&&(a=Ha[SDL.screen+0*z.ia>>2],K[SDL.screen+0*z.ia>>2]=a&-8388609),ec()));if(p.onFullScreen)p.onFullScreen(Yb);fc(e)}$b=a;ac=b;"undefined"===typeof $b&&($b=i);"undefined"===typeof ac&&(ac=m);var e=p.canvas;Zb||(Zb=i,document.addEventListener("fullscreenchange",c,m),document.addEventListener("mozfullscreenchange", +c,m),document.addEventListener("webkitfullscreenchange",c,m),document.addEventListener("MSFullscreenChange",c,m));var f=document.createElement("div");e.parentNode.insertBefore(f,e);f.appendChild(e);f.Td=f.requestFullScreen||f.mozRequestFullScreen||f.msRequestFullscreen||(f.webkitRequestFullScreen?function(){f.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}:k);f.Td()};p.requestAnimationFrame=function(a){Qb(a)};p.setCanvasSize=function(a,b,c){fc(p.canvas,a,b);c||ec()}; +p.pauseMainLoop=function(){Nb=k;Tb++};p.resumeMainLoop=function(){Tb++;var a=Kb,b=Lb,c=Mb;Mb=k;Rb(c,0,m,Sb);Jb(a,b)};p.getUserMedia=function(){window.qc||(window.qc=navigator.getUserMedia||navigator.mozGetUserMedia);window.qc(g)};Ja=y=z.ub(D);Ka=Ja+Ma;La=E=z.ub(Ka);w(La>2],a=Db(a,b);return 0>a?a:0>Eb(10,b)?-1:a+1},_fflush:n(),_fputc:Eb,_send:function(a,b,c){return!Z.wd(a)?(V(U.V),-1):Ab(a,b,c)},_pwrite:function(a,b,c,e){a=B.qa(a);if(!a)return V(U.V),-1;try{return B.write(a,I,b,c,e)}catch(f){return B.sc(f),-1}},_fputs:Db,_emscripten_set_main_loop:Rb, +_abort:function(){p.abort()},___setErrNo:V,_sbrk:Fb,_mkport:zb,_emscripten_set_main_loop_timing:Jb,_emscripten_memcpy_big:function(a,b,c){N.set(N.subarray(b,b+c),a);return a},_fileno:Cb,_broadwayOnHeadersDecoded:Ib,_write:Ab,_time:function(a){var b=Date.now()/1E3|0;a&&(K[a>>2]=b);return b},_sysconf:function(a){switch(a){case 30:return 4096;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 79:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809; +case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32; +case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1E3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:return"object"===typeof navigator?navigator.hardwareConcurrency||1:1}V(U.B);return-1}, +___errno_location:function(){return bb},STACKTOP:y,STACK_MAX:Ka,tempDoublePtr:$a,ABORT:H,NaN:NaN,Infinity:Infinity};// EMSCRIPTEN_START_ASM +var $=(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.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=0;var n=0;var o=0;var p=0;var q=+env.NaN,r=+env.Infinity;var s=0,t=0,u=0,v=0,w=0.0,x=0,y=0,z=0,A=0.0;var B=0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=global.Math.floor;var M=global.Math.abs;var N=global.Math.sqrt;var O=global.Math.pow;var P=global.Math.cos;var Q=global.Math.sin;var R=global.Math.tan;var S=global.Math.acos;var T=global.Math.asin;var U=global.Math.atan;var V=global.Math.atan2;var W=global.Math.exp;var X=global.Math.log;var Y=global.Math.ceil;var Z=global.Math.imul;var _=env.abort;var $=env.assert;var aa=env.min;var ba=env.invoke_viiiii;var ca=env._broadwayOnPictureDecoded;var da=env._puts;var ea=env._fflush;var fa=env._fputc;var ga=env._send;var ha=env._pwrite;var ia=env._fputs;var ja=env._emscripten_set_main_loop;var ka=env._abort;var la=env.___setErrNo;var ma=env._sbrk;var na=env._mkport;var oa=env._emscripten_set_main_loop_timing;var pa=env._emscripten_memcpy_big;var qa=env._fileno;var ra=env._broadwayOnHeadersDecoded;var sa=env._write;var ta=env._time;var ua=env._sysconf;var va=env.___errno_location;var wa=0.0; +// EMSCRIPTEN_START_FUNCS +function Sb(a,f,g,h,j,k){a=a|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var 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,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;X=i;i=i+32|0;W=X;p=c[j+4>>2]|0;V=(h>>>0)/(p>>>0)|0;U=V<<4;V=h-(Z(V,p)|0)<<4;c[W+4>>2]=p;c[W+8>>2]=c[j+8>>2];p=c[a>>2]|0;do if((p|0)==1|(p|0)==0){A=c[f+144>>2]|0;l=a+4|0;n=c[a+200>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){o=n+152|0;o=e[o>>1]|e[o+2>>1]<<16;m=1;v=o&65535;o=o>>>16&65535;s=c[n+104>>2]|0}else{m=1;v=0;o=0;s=-1}else{m=0;v=0;o=0;s=-1}n=c[a+204>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){w=n+172|0;w=e[w>>1]|e[w+2>>1]<<16;u=w&65535;q=1;r=c[n+108>>2]|0;w=w>>>16&65535}else{u=0;q=1;r=-1;w=0}else{u=0;q=0;r=-1;w=0}do if(!p)if(!((m|0)==0|(q|0)==0)){if((s|0)==0?((o&65535)<<16|v&65535|0)==0:0){n=0;o=0;break}if((r|0)==0?((w&65535)<<16|u&65535|0)==0:0){n=0;o=0}else T=16}else{n=0;o=0}else T=16;while(0);if((T|0)==16){y=b[f+160>>1]|0;z=b[f+162>>1]|0;n=c[a+208>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){t=n+172|0;p=c[n+108>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;T=25}else{p=-1;t=0;T=25}else T=20;do if((T|0)==20){p=c[a+212>>2]|0;if((p|0)!=0?(c[p+4>>2]|0)==(c[l>>2]|0):0){if((c[p>>2]|0)>>>0>=6){p=-1;t=0;T=25;break}t=p+192|0;p=c[p+112>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;T=25;break}if((m|0)==0|(q|0)!=0){p=-1;t=0;T=25}else n=v}while(0);do if((T|0)==25){m=(s|0)==(A|0);n=(r|0)==(A|0);if(((n&1)+(m&1)+((p|0)==(A|0)&1)|0)==1){if(m|n){n=m?v:u;o=m?o:w;break}n=t&65535;o=t>>>16&65535;break}n=v<<16>>16;l=u<<16>>16;p=t<<16>>16;if(u<<16>>16>v<<16>>16)m=l;else{m=n;n=(l|0)<(n|0)?l:n}if((m|0)<(p|0))p=m;else p=(n|0)>(p|0)?n:p;n=o<<16>>16;m=w<<16>>16;l=t>>16;if(w<<16>>16>o<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=p&65535;o=o&65535}while(0);n=(n&65535)+(y&65535)|0;o=(o&65535)+(z&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}else{n=n&65535;o=o&65535}}l=ic(g,A)|0;if(!l){G=1;i=X;return G|0}else{G=a+132|0;E=a+136|0;D=a+140|0;C=a+144|0;B=a+148|0;z=a+152|0;y=a+156|0;x=a+160|0;w=a+164|0;v=a+168|0;m=a+172|0;p=a+176|0;q=a+180|0;r=a+184|0;s=a+188|0;F=a+192|0;b[a+192>>1]=n;b[a+194>>1]=o;F=e[F>>1]|e[F+2>>1]<<16;b[s>>1]=F;b[s+2>>1]=F>>>16;b[r>>1]=F;b[r+2>>1]=F>>>16;b[q>>1]=F;b[q+2>>1]=F>>>16;b[p>>1]=F;b[p+2>>1]=F>>>16;b[m>>1]=F;b[m+2>>1]=F>>>16;b[v>>1]=F;b[v+2>>1]=F>>>16;b[w>>1]=F;b[w+2>>1]=F>>>16;b[x>>1]=F;b[x+2>>1]=F>>>16;b[y>>1]=F;b[y+2>>1]=F>>>16;b[z>>1]=F;b[z+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+100>>2]=A;c[a+104>>2]=A;c[a+108>>2]=A;c[a+112>>2]=A;c[a+116>>2]=l;c[a+120>>2]=l;c[a+124>>2]=l;c[a+128>>2]=l;c[W>>2]=l;dc(k,a+132|0,W,V,U,0,0,16,16);break}}else if((p|0)==3){x=b[f+160>>1]|0;y=b[f+162>>1]|0;C=c[f+144>>2]|0;u=a+4|0;o=c[a+200>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){w=o+152|0;w=e[w>>1]|e[w+2>>1]<<16;n=1;s=w&65535;w=w>>>16&65535;o=c[o+104>>2]|0}else{n=1;s=0;w=0;o=-1}else{n=0;s=0;w=0;o=-1}a:do if((o|0)==(C|0)){n=s;o=w}else{o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){G=o+172|0;G=e[G>>1]|e[G+2>>1]<<16;t=o+188|0;p=c[o+108>>2]|0;l=c[o+112>>2]|0;n=G&65535;o=G>>>16&65535;t=e[t>>1]|e[t+2>>1]<<16}else{p=-1;l=-1;n=0;o=0;t=0}else T=107;do if((T|0)==107){o=c[a+212>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0){if((c[o>>2]|0)>>>0>=6){p=-1;l=-1;n=0;o=0;t=0;break}t=o+192|0;p=-1;l=c[o+112>>2]|0;n=0;o=0;t=e[t>>1]|e[t+2>>1]<<16;break}if(!n){p=-1;l=-1;n=0;o=0;t=0}else{n=s;o=w;break a}}while(0);m=(p|0)==(C|0);if(((m&1)+((l|0)==(C|0)&1)|0)==1){if(m)break;n=t&65535;o=t>>>16&65535;break}l=s<<16>>16;p=n<<16>>16;q=t<<16>>16;if(n<<16>>16>s<<16>>16){m=p;n=l}else{m=l;n=(p|0)<(l|0)?p:l}if((m|0)<(q|0))q=m;else q=(n|0)>(q|0)?n:q;n=w<<16>>16;m=o<<16>>16;l=t>>16;if(o<<16>>16>w<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=q&65535;o=o&65535}while(0);n=(n&65535)+(x&65535)|0;o=(o&65535)+(y&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}m=ic(g,C)|0;if(!m){G=1;i=X;return G|0}x=a+132|0;z=a+136|0;A=a+140|0;y=a+144|0;G=a+164|0;F=a+168|0;E=a+172|0;w=a+176|0;b[a+176>>1]=n;b[a+178>>1]=o;w=e[w>>1]|e[w+2>>1]<<16;b[E>>1]=w;b[E+2>>1]=w>>>16;b[F>>1]=w;b[F+2>>1]=w>>>16;b[G>>1]=w;b[G+2>>1]=w>>>16;b[y>>1]=w;b[y+2>>1]=w>>>16;b[A>>1]=w;b[A+2>>1]=w>>>16;b[z>>1]=w;b[z+2>>1]=w>>>16;b[x>>1]=w;b[x+2>>1]=w>>>16;c[a+100>>2]=C;c[a+108>>2]=C;x=a+116|0;c[x>>2]=m;c[a+124>>2]=m;z=b[f+164>>1]|0;A=b[f+166>>1]|0;y=c[f+148>>2]|0;o=c[a+208>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){r=o+172|0;o=c[o+108>>2]|0;p=1;r=e[r>>1]|e[r+2>>1]<<16}else{o=-1;p=1;r=0}else{o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){r=o+176|0;o=c[o+108>>2]|0;p=1;r=e[r>>1]|e[r+2>>1]<<16}else{o=-1;p=1;r=0}else{o=-1;p=0;r=0}}do if((o|0)!=(y|0)){s=w&65535;o=w>>>16;v=o&65535;n=c[a+204>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[u>>2]|0):0)if((c[n>>2]|0)>>>0<6){u=n+188|0;u=e[u>>1]|e[u+2>>1]<<16;p=c[n+112>>2]|0;l=u&65535;u=u>>>16&65535}else{p=-1;l=0;u=0}else if(!p){m=w;break}else{p=-1;l=0;u=0}m=(C|0)==(y|0);n=(p|0)==(y|0);if(((n&1)+(m&1)|0)==1){if(m){m=w;break}if(n){o=u&65535;m=o<<16|l&65535;break}else{m=r;o=r>>>16;break}}o=w<<16>>16;p=l<<16>>16;q=r<<16>>16;if(l<<16>>16>s<<16>>16)m=p;else{m=o;o=(p|0)<(o|0)?p:o}if((m|0)>=(q|0))m=(o|0)>(q|0)?o:q;n=w>>16;l=u<<16>>16;p=r>>16;if(u<<16>>16>v<<16>>16)o=l;else{o=n;n=(l|0)<(n|0)?l:n}if((o|0)>=(p|0))o=(n|0)>(p|0)?n:p}else{m=r;o=r>>>16}while(0);m=(m&65535)+(z&65535)|0;n=(o&65535)+(A&65535)|0;if(((m<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((n<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}o=ic(g,y)|0;if(!o){G=1;i=X;return G|0}else{G=a+148|0;E=a+152|0;D=a+156|0;C=a+160|0;B=a+180|0;A=a+184|0;z=a+188|0;F=a+192|0;b[a+192>>1]=m;b[a+194>>1]=n;F=e[F>>1]|e[F+2>>1]<<16;b[z>>1]=F;b[z+2>>1]=F>>>16;b[A>>1]=F;b[A+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+104>>2]=y;c[a+112>>2]=y;F=a+120|0;c[F>>2]=o;c[a+128>>2]=o;c[W>>2]=c[x>>2];dc(k,a+132|0,W,V,U,0,0,8,16);c[W>>2]=c[F>>2];dc(k,G,W,V,U,8,0,8,16);break}}else if((p|0)==2){z=b[f+160>>1]|0;A=b[f+162>>1]|0;C=c[f+144>>2]|0;B=a+4|0;o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[B>>2]|0):0)if((c[o>>2]|0)>>>0<6){w=o+172|0;w=e[w>>1]|e[w+2>>1]<<16;m=1;o=c[o+108>>2]|0;r=w&65535;w=w>>>16&65535}else{m=1;o=-1;r=0;w=0}else{m=0;o=-1;r=0;w=0}b:do if((o|0)==(C|0)){n=r;o=w}else{n=c[a+200>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0)if((c[n>>2]|0)>>>0<6){o=n+152|0;o=e[o>>1]|e[o+2>>1]<<16;q=1;s=o&65535;o=o>>>16&65535;p=c[n+104>>2]|0}else{q=1;s=0;o=0;p=-1}else{q=0;s=0;o=0;p=-1}n=c[a+208>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0)if((c[n>>2]|0)>>>0<6){t=n+172|0;n=c[n+108>>2]|0;t=e[t>>1]|e[t+2>>1]<<16}else{n=-1;t=0}else T=54;do if((T|0)==54){n=c[a+212>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0){if((c[n>>2]|0)>>>0>=6){n=-1;t=0;break}t=n+192|0;n=c[n+112>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;break}if((q|0)==0|(m|0)!=0){n=-1;t=0}else{n=s;break b}}while(0);m=(p|0)==(C|0);if((((n|0)==(C|0)&1)+(m&1)|0)==1){if(m){n=m?s:r;o=m?o:w;break}n=t&65535;o=t>>>16&65535;break}n=s<<16>>16;l=r<<16>>16;p=t<<16>>16;if(r<<16>>16>s<<16>>16)m=l;else{m=n;n=(l|0)<(n|0)?l:n}if((m|0)<(p|0))q=m;else q=(n|0)>(p|0)?n:p;n=o<<16>>16;m=w<<16>>16;l=t>>16;if(w<<16>>16>o<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=q&65535;o=o&65535}while(0);n=(n&65535)+(z&65535)|0;o=(o&65535)+(A&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}m=ic(g,C)|0;if(!m){G=1;i=X;return G|0}A=a+132|0;x=a+136|0;y=a+140|0;z=a+144|0;q=a+148|0;p=a+152|0;G=a+156|0;v=a+160|0;b[a+160>>1]=n;b[a+162>>1]=o;v=e[v>>1]|e[v+2>>1]<<16;b[G>>1]=v;b[G+2>>1]=v>>>16;b[p>>1]=v;b[p+2>>1]=v>>>16;b[q>>1]=v;b[q+2>>1]=v>>>16;b[z>>1]=v;b[z+2>>1]=v>>>16;b[y>>1]=v;b[y+2>>1]=v>>>16;b[x>>1]=v;b[x+2>>1]=v>>>16;b[A>>1]=v;b[A+2>>1]=v>>>16;c[a+100>>2]=C;c[a+104>>2]=C;A=a+116|0;c[A>>2]=m;c[a+120>>2]=m;x=b[f+164>>1]|0;y=b[f+166>>1]|0;z=c[f+148>>2]|0;q=c[a+200>>2]|0;p=(q|0)==0;if((!p?(c[q+4>>2]|0)==(c[B>>2]|0):0)?(c[q>>2]|0)>>>0<6:0){w=q+184|0;w=e[w>>1]|e[w+2>>1]<<16;r=w&65535;w=w>>>16&65535;o=c[q+112>>2]|0}else{r=0;w=0;o=-1}do if((o|0)!=(z|0)){s=v&65535;n=v>>>16;u=n&65535;if((!p?(c[q+4>>2]|0)==(c[B>>2]|0):0)?(c[q>>2]|0)>>>0<6:0){t=q+160|0;p=c[q+104>>2]|0;t=e[t>>1]|e[t+2>>1]<<16}else{p=-1;t=0}o=(C|0)==(z|0);if((((p|0)==(z|0)&1)+(o&1)|0)==1){m=o?v:t;o=o?n:t>>>16;break}o=r<<16>>16;p=v<<16>>16;q=t<<16>>16;if(s<<16>>16>r<<16>>16)m=p;else{m=o;o=(p|0)<(o|0)?p:o}if((m|0)>=(q|0))m=(o|0)>(q|0)?o:q;n=w<<16>>16;l=v>>16;p=t>>16;if(u<<16>>16>w<<16>>16)o=l;else{o=n;n=(l|0)<(n|0)?l:n}if((o|0)>=(p|0))o=(n|0)>(p|0)?n:p}else{o=w&65535;m=o<<16|r&65535}while(0);m=(m&65535)+(x&65535)|0;n=(o&65535)+(y&65535)|0;if(((m<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((n<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}o=ic(g,z)|0;if(!o){G=1;i=X;return G|0}else{G=a+164|0;E=a+168|0;D=a+172|0;C=a+176|0;B=a+180|0;y=a+184|0;x=a+188|0;F=a+192|0;b[a+192>>1]=m;b[a+194>>1]=n;F=e[F>>1]|e[F+2>>1]<<16;b[x>>1]=F;b[x+2>>1]=F>>>16;b[y>>1]=F;b[y+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+108>>2]=z;c[a+112>>2]=z;F=a+124|0;c[F>>2]=o;c[a+128>>2]=o;c[W>>2]=c[A>>2];dc(k,a+132|0,W,V,U,0,0,16,8);c[W>>2]=c[F>>2];dc(k,G,W,V,U,0,8,16,8);break}}else{S=a+4|0;H=0;c:while(1){D=f+(H<<2)+176|0;G=eb(c[D>>2]|0)|0;E=f+(H<<2)+192|0;c[a+(H<<2)+100>>2]=c[E>>2];F=ic(g,c[E>>2]|0)|0;c[a+(H<<2)+116>>2]=F;if(!F){l=1;T=212;break}if(G){J=H<<2;K=a+(J<<2)+132|0;O=a+(J<<2)+134|0;P=J|1;L=a+(P<<2)+132|0;P=a+(P<<2)+134|0;Q=J|2;M=a+(Q<<2)+132|0;Q=a+(Q<<2)+134|0;R=J|3;N=a+(R<<2)+132|0;R=a+(R<<2)+134|0;I=0;do{C=b[f+(H<<4)+(I<<2)+208>>1]|0;B=b[f+(H<<4)+(I<<2)+210>>1]|0;F=hb(c[D>>2]|0)|0;n=c[E>>2]|0;s=ub(a,c[6288+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;r=d[6288+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((s|0)!=0?(c[s+4>>2]|0)==(c[S>>2]|0):0)if((c[s>>2]|0)>>>0<6){q=s+(r<<2)+132|0;q=e[q>>1]|e[q+2>>1]<<16;A=c[s+(r>>>2<<2)+100>>2]|0;o=q&65535;z=1;q=q>>>16&65535}else{A=-1;o=0;z=1;q=0}else{A=-1;o=0;z=0;q=0}v=ub(a,c[5776+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;l=d[5776+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((v|0)!=0?(c[v+4>>2]|0)==(c[S>>2]|0):0)if((c[v>>2]|0)>>>0<6){p=v+(l<<2)+132|0;p=e[p>>1]|e[p+2>>1]<<16;y=1;x=c[v+(l>>>2<<2)+100>>2]|0;m=p&65535;p=p>>>16&65535}else{y=1;x=-1;m=0;p=0}else{y=0;x=-1;m=0;p=0}w=ub(a,c[5264+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;v=d[5264+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((w|0)!=0?(c[w+4>>2]|0)==(c[S>>2]|0):0)if((c[w>>2]|0)>>>0<6){z=w+(v<<2)+132|0;z=e[z>>1]|e[z+2>>1]<<16;v=c[w+(v>>>2<<2)+100>>2]|0;T=180}else{z=0;v=-1;T=180}else T=175;do if((T|0)==175){T=0;w=ub(a,c[4752+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;v=d[4752+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((w|0)!=0?(c[w+4>>2]|0)==(c[S>>2]|0):0){if((c[w>>2]|0)>>>0>=6){z=0;v=-1;T=180;break}z=w+(v<<2)+132|0;z=e[z>>1]|e[z+2>>1]<<16;v=c[w+(v>>>2<<2)+100>>2]|0;T=180;break}if((z|0)==0|(y|0)!=0){z=0;v=-1;T=180}else{v=o;t=q}}while(0);do if((T|0)==180){l=(A|0)==(n|0);w=(x|0)==(n|0);if(((w&1)+(l&1)+((v|0)==(n|0)&1)|0)==1){if(l|w){v=l?o:m;t=l?q:p;break}v=z&65535;t=z>>>16&65535;break}u=o<<16>>16;w=m<<16>>16;l=z<<16>>16;if(m<<16>>16>o<<16>>16)v=w;else{v=u;u=(w|0)<(u|0)?w:u}if((v|0)<(l|0))w=v;else w=(u|0)>(l|0)?u:l;t=q<<16>>16;v=p<<16>>16;l=z>>16;if(p<<16>>16>q<<16>>16)s=v;else{s=t;t=(v|0)<(t|0)?v:t}if((s|0)>=(l|0))s=(t|0)>(l|0)?t:l;v=w&65535;t=s&65535}while(0);C=(v&65535)+(C&65535)|0;q=C&65535;s=(t&65535)+(B&65535)|0;r=s&65535;if(((C<<16>>16)+8192|0)>>>0>16383){l=1;T=212;break c}if(((s<<16>>16)+2048|0)>>>0>4095){l=1;T=212;break c}if(!F){b[K>>1]=q;b[O>>1]=r;b[L>>1]=q;b[P>>1]=r;b[M>>1]=q;b[Q>>1]=r;b[N>>1]=q;b[R>>1]=r}else if((F|0)==1){F=(I<<1)+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r;F=F|1;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}else if((F|0)==2){F=I+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r;F=F+2|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}else if((F|0)==3){F=I+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}I=I+1|0}while(I>>>0>>0)}H=H+1|0;if(H>>>0>=4){T=201;break}}if((T|0)==201){o=0;do{c[W>>2]=c[a+(o<<2)+116>>2];m=hb(c[f+(o<<2)+176>>2]|0)|0;l=o<<3&8;n=o>>>0<2?0:8;if(!m)dc(k,a+(o<<2<<2)+132|0,W,V,U,l,n,8,8);else if((m|0)==1){G=o<<2;dc(k,a+(G<<2)+132|0,W,V,U,l,n,8,4);dc(k,a+((G|2)<<2)+132|0,W,V,U,l,n|4,8,4)}else if((m|0)==2){G=o<<2;dc(k,a+(G<<2)+132|0,W,V,U,l,n,4,8);dc(k,a+((G|1)<<2)+132|0,W,V,U,l|4,n,4,8)}else{E=o<<2;dc(k,a+(E<<2)+132|0,W,V,U,l,n,4,4);F=l|4;dc(k,a+((E|1)<<2)+132|0,W,V,U,F,n,4,4);G=n|4;dc(k,a+((E|2)<<2)+132|0,W,V,U,l,G,4,4);dc(k,a+((E|3)<<2)+132|0,W,V,U,F,G,4,4)}o=o+1|0}while((o|0)!=4)}else if((T|0)==212){i=X;return l|0}}while(0);if((c[a+196>>2]|0)>>>0>1){G=0;i=X;return G|0}if(!(c[a>>2]|0)){sc(j,k);G=0;i=X;return G|0}else{tc(j,h,k,f+328|0);G=0;i=X;return G|0}return 0}function Tb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0,D=0,E=0,F=0;B=i;i=i+144|0;m=B;if((e|0)>=0?!((e+1+k|0)>>>0>g>>>0|(f|0)<0|(l+f|0)>>>0>h>>>0):0)m=b;else{A=k+1|0;Ub(b,m,e,f,g,h,A,l,A);Ub(b+(Z(h,g)|0)|0,m+(Z(A,l)|0)|0,e,f,g,h,A,l,A);h=l;g=A;e=0;f=0}A=8-j|0;v=l>>>1;z=(v|0)==0;w=k>>>1;y=(w|0)==0;x=16-k|0;u=(g<<1)-k|0;s=g+1|0;t=g+2|0;p=w<<1;r=0;do{l=m+((Z((Z(r,h)|0)+f|0,g)|0)+e)|0;if(!(z|y)){q=c+(r<<6)|0;o=v;while(1){k=q;b=l;n=w;while(1){D=d[b>>0]|0;E=d[b+s>>0]|0;F=b;b=b+2|0;C=d[F+1>>0]|0;a[k+8>>0]=(((Z(E,j)|0)+(Z(d[F+g>>0]|0,A)|0)<<3)+32|0)>>>6;a[k>>0]=(((Z(C,j)|0)+(Z(D,A)|0)<<3)+32|0)>>>6;D=d[b>>0]|0;a[k+9>>0]=(((Z(d[F+t>>0]|0,j)|0)+(Z(E,A)|0)<<3)+32|0)>>>6;a[k+1>>0]=(((Z(D,j)|0)+(Z(C,A)|0)<<3)+32|0)>>>6;n=n+-1|0;if(!n)break;else k=k+2|0}o=o+-1|0;if(!o)break;else{q=q+(p+x)|0;l=l+(p+u)|0}}}r=r+1|0}while((r|0)!=2);i=B;return}function Ub(a,b,c,d,e,f,g,h,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;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;k=g+c|0;o=h+d|0;s=(c|0)<0|(k|0)>(e|0)?2:1;m=(o|0)<0?0-h|0:d;d=(k|0)<0?0-g|0:c;m=(m|0)>(f|0)?f:m;d=(d|0)>(e|0)?e:d;k=d+g|0;l=m+h|0;if((d|0)>0)a=a+d|0;if((m|0)>0)a=a+(Z(m,e)|0)|0;r=(d|0)<0?0-d|0:0;q=(k|0)>(e|0)?k-e|0:0;p=g-r-q|0;g=0-m|0;m=(m|0)<0?g:0;c=l-f|0;n=(l|0)>(f|0)?c:0;k=h-m|0;d=k-n|0;if(m){m=h+-1-((o|0)>0?o:0)|0;l=~f;l=(m|0)>(l|0)?m:l;m=~l;m=Z(l+((m|0)>0?m:0)+1|0,j)|0;l=b;while(1){xa[s&3](a,l,r,p,q);g=g+-1|0;if(!g)break;else l=l+j|0}b=b+m|0}if((k|0)!=(n|0)){l=h+-1|0;g=l-((o|0)>0?o:0)|0;k=~f;k=(g|0)>(k|0)?g:k;l=l-k|0;g=~k;g=h+f+-1-((l|0)<(f|0)?f:l)-k-((g|0)>0?g:0)|0;k=Z(g,j)|0;g=Z(g,e)|0;l=b;m=a;while(1){xa[s&3](m,l,r,p,q);d=d+-1|0;if(!d)break;else{l=l+j|0;m=m+e|0}}b=b+k|0;a=a+g|0}a=a+(0-e)|0;if(!n){i=t;return}while(1){xa[s&3](a,b,r,p,q);c=c+-1|0;if(!c)break;else b=b+j|0}i=t;return}function Vb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0,D=0,E=0;C=i;i=i+144|0;m=C;if(((e|0)>=0?!((k+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+1+l|0)>>>0<=h>>>0:0)m=b;else{A=l+1|0;Ub(b,m,e,f,g,h,k,A,k);Ub(b+(Z(h,g)|0)|0,m+(Z(A,k)|0)|0,e,f,g,h,k,A,k);h=A;g=k;e=0;f=0}B=8-j|0;w=l>>>1;A=(w|0)==0;x=k>>>1;z=(x|0)==0;y=16-k|0;v=g<<1;u=v-k|0;t=v|1;s=g+1|0;p=x<<1;r=0;do{l=m+((Z((Z(r,h)|0)+f|0,g)|0)+e)|0;if(!(A|z)){q=c+(r<<6)|0;o=w;while(1){k=q;b=l;n=x;while(1){D=d[b+g>>0]|0;E=d[b>>0]|0;a[k+8>>0]=(((Z(D,B)|0)+(Z(d[b+v>>0]|0,j)|0)<<3)+32|0)>>>6;a[k>>0]=(((Z(E,B)|0)+(Z(D,j)|0)<<3)+32|0)>>>6;D=d[b+s>>0]|0;E=d[b+1>>0]|0;a[k+9>>0]=(((Z(D,B)|0)+(Z(d[b+t>>0]|0,j)|0)<<3)+32|0)>>>6;a[k+1>>0]=(((Z(E,B)|0)+(Z(D,j)|0)<<3)+32|0)>>>6;n=n+-1|0;if(!n)break;else{k=k+2|0;b=b+2|0}}o=o+-1|0;if(!o)break;else{q=q+(p+y)|0;l=l+(p+u)|0}}}r=r+1|0}while((r|0)!=2);i=C;return}function Wb(b,c,e,f,g,h,j,k,l,m){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,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;I=i;i=i+176|0;n=I;if(((e|0)>=0?!((e+1+l|0)>>>0>g>>>0|(f|0)<0):0)?(f+1+m|0)>>>0<=h>>>0:0)n=b;else{B=l+1|0;A=m+1|0;Ub(b,n,e,f,g,h,B,A,B);Ub(b+(Z(h,g)|0)|0,n+(Z(A,B)|0)|0,e,f,g,h,B,A,B);h=A;g=B;e=0;f=0}G=8-j|0;H=8-k|0;B=m>>>1;E=(B|0)==0;A=g<<1;C=l>>>1;F=(C|0)==0;D=16-l|0;z=A-l|0;v=g+1|0;w=A|1;x=g+2|0;y=A+2|0;s=C<<1;u=0;do{l=n+((Z((Z(u,h)|0)+f|0,g)|0)+e)|0;if(!(E|F)){t=c+(u<<6)|0;r=B;while(1){p=d[l+g>>0]|0;m=t;b=l;o=(Z(p,k)|0)+(Z(d[l>>0]|0,H)|0)|0;p=(Z(d[l+A>>0]|0,k)|0)+(Z(p,H)|0)|0;q=C;while(1){K=d[b+v>>0]|0;J=(Z(K,k)|0)+(Z(d[b+1>>0]|0,H)|0)|0;K=(Z(d[b+w>>0]|0,k)|0)+(Z(K,H)|0)|0;M=((Z(o,G)|0)+32+(Z(J,j)|0)|0)>>>6;a[m+8>>0]=((Z(p,G)|0)+32+(Z(K,j)|0)|0)>>>6;a[m>>0]=M;M=b;b=b+2|0;L=d[M+x>>0]|0;o=(Z(L,k)|0)+(Z(d[b>>0]|0,H)|0)|0;p=(Z(d[M+y>>0]|0,k)|0)+(Z(L,H)|0)|0;J=((Z(J,G)|0)+32+(Z(o,j)|0)|0)>>>6;a[m+9>>0]=((Z(K,G)|0)+32+(Z(p,j)|0)|0)>>>6;a[m+1>>0]=J;q=q+-1|0;if(!q)break;else m=m+2|0}r=r+-1|0;if(!r)break;else{t=t+(s+D)|0;l=l+(s+z)|0}}}u=u+1|0}while((u|0)!=2);i=I;return}function Xb(b,c,e,f,g,h,j,k){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var 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;r=i;i=i+448|0;l=r;if(((e|0)>=0?!((j+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)l=b;else{Ub(b,l,e,f,g,h,j,k+5|0,j);g=j;e=0;f=0}h=e+g+(Z(f,g)|0)|0;b=k>>>2;if(!b){i=r;return}n=g<<2;q=0-g|0;o=q<<1;p=g<<1;if(!j){i=r;return}else{m=l+h|0;e=l+(h+(g*5|0))|0}while(1){l=j;h=c;k=m;f=e;while(1){u=d[f+o>>0]|0;v=d[f+q>>0]|0;w=d[f+g>>0]|0;y=d[f>>0]|0;x=w+u|0;s=d[k+p>>0]|0;a[h+48>>0]=a[((d[f+p>>0]|0)+16-x-(x<<2)+s+((y+v|0)*20|0)>>5)+3984>>0]|0;x=s+y|0;t=d[k+g>>0]|0;a[h+32>>0]=a[(w+16-x-(x<<2)+t+((v+u|0)*20|0)>>5)+3984>>0]|0;x=t+v|0;w=d[k>>0]|0;a[h+16>>0]=a[(y+16-x-(x<<2)+w+((s+u|0)*20|0)>>5)+3984>>0]|0;u=w+u|0;a[h>>0]=a[(v+16-u-(u<<2)+(d[k+q>>0]|0)+((t+s|0)*20|0)>>5)+3984>>0]|0;l=l+-1|0;if(!l)break;else{h=h+1|0;k=k+1|0;f=f+1|0}}b=b+-1|0;if(!b)break;else{c=c+64|0;m=m+n|0;e=e+n|0}}i=r;return}function Yb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0;v=i;i=i+448|0;m=v;if(((e|0)>=0?!((j+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)m=b;else{Ub(b,m,e,f,g,h,j,k+5|0,j);g=j;e=0;f=0}h=e+g+(Z(f,g)|0)|0;b=k>>>2;if(!b){i=v;return}u=(j|0)==0;s=(g<<2)-j|0;t=64-j|0;r=0-g|0;p=r<<1;q=g<<1;e=m+h|0;f=m+(h+(Z(g,l+2|0)|0))|0;m=m+(h+(g*5|0))|0;while(1){if(u){h=c;k=f}else{k=f+j|0;h=c+j|0;l=j;o=e;n=m;while(1){y=d[n+p>>0]|0;z=d[n+r>>0]|0;A=d[n+g>>0]|0;C=d[n>>0]|0;B=A+y|0;w=d[o+q>>0]|0;a[c+48>>0]=((d[((d[n+q>>0]|0)+16-B-(B<<2)+w+((C+z|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+q>>0]|0)|0)>>>1;B=w+C|0;x=d[o+g>>0]|0;a[c+32>>0]=((d[(A+16-B-(B<<2)+x+((z+y|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+g>>0]|0)|0)>>>1;B=x+z|0;A=d[o>>0]|0;a[c+16>>0]=((d[(C+16-B-(B<<2)+A+((w+y|0)*20|0)>>5)+3984>>0]|0)+1+(d[f>>0]|0)|0)>>>1;y=A+y|0;a[c>>0]=((d[(z+16-y-(y<<2)+(d[o+r>>0]|0)+((x+w|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+r>>0]|0)|0)>>>1;l=l+-1|0;if(!l)break;else{c=c+1|0;o=o+1|0;f=f+1|0;n=n+1|0}}e=e+j|0;m=m+j|0}b=b+-1|0;if(!b)break;else{c=h+t|0;e=e+s|0;f=k+s|0;m=m+s|0}}i=v;return}function Zb(b,c,e,f,g,h,j,k){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;u=i;i=i+448|0;l=u;if((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0|(k+f|0)>>>0>h>>>0):0)l=b;else{n=j+5|0;Ub(b,l,e,f,g,h,n,k,n);g=n;e=0;f=0}if(!k){i=u;return}r=j>>>2;t=(r|0)==0;s=g-j|0;q=16-j|0;p=r<<2;b=c;l=l+(e+5+(Z(f,g)|0))|0;o=k;while(1){if(t)h=b;else{h=b+p|0;e=l;g=d[l+-1>>0]|0;k=d[l+-2>>0]|0;m=d[l+-3>>0]|0;n=d[l+-4>>0]|0;j=d[l+-5>>0]|0;c=r;while(1){f=n+g|0;v=n;n=d[e>>0]|0;a[b>>0]=a[(j+16-f-(f<<2)+n+((m+k|0)*20|0)>>5)+3984>>0]|0;j=n+m|0;f=m;m=d[e+1>>0]|0;a[b+1>>0]=a[(v+16-j-(j<<2)+m+((k+g|0)*20|0)>>5)+3984>>0]|0;j=m+k|0;v=k;k=d[e+2>>0]|0;a[b+2>>0]=a[(f+16-j-(j<<2)+k+((n+g|0)*20|0)>>5)+3984>>0]|0;j=k+g|0;f=d[e+3>>0]|0;a[b+3>>0]=a[(v+16-j-(j<<2)+f+((m+n|0)*20|0)>>5)+3984>>0]|0;c=c+-1|0;if(!c)break;else{j=g;b=b+4|0;e=e+4|0;g=f}}l=l+p|0}o=o+-1|0;if(!o)break;else{b=h+q|0;l=l+s|0}}i=u;return}function _b(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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;v=i;i=i+448|0;m=v;if((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0|(k+f|0)>>>0>h>>>0):0)m=b;else{o=j+5|0;Ub(b,m,e,f,g,h,o,k,o);g=o;e=0;f=0}if(!k){i=v;return}s=j>>>2;u=(s|0)==0;t=g-j|0;r=16-j|0;q=(l|0)!=0;p=s<<2;b=c;m=m+(e+5+(Z(f,g)|0))|0;while(1){if(u)h=b;else{h=b+p|0;l=m;e=d[m+-1>>0]|0;g=d[m+-2>>0]|0;n=d[m+-3>>0]|0;o=d[m+-4>>0]|0;j=d[m+-5>>0]|0;c=s;while(1){f=o+e|0;w=o;o=d[l>>0]|0;a[b>>0]=((q?g:n)+1+(d[(j+16-f-(f<<2)+o+((n+g|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=o+n|0;f=n;n=d[l+1>>0]|0;a[b+1>>0]=((q?e:g)+1+(d[(w+16-j-(j<<2)+n+((g+e|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=n+g|0;w=g;g=d[l+2>>0]|0;a[b+2>>0]=((q?o:e)+1+(d[(f+16-j-(j<<2)+g+((o+e|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=g+e|0;f=d[l+3>>0]|0;a[b+3>>0]=((q?n:o)+1+(d[(w+16-j-(j<<2)+f+((n+o|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;c=c+-1|0;if(!c)break;else{j=e;b=b+4|0;l=l+4|0;e=f}}m=m+p|0}k=k+-1|0;if(!k)break;else{b=h+r|0;m=m+t|0}}i=v;return}function $b(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0;z=i;i=i+448|0;m=z;if(((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)m=b;else{y=j+5|0;Ub(b,m,e,f,g,h,y,k+5|0,y);g=y;e=0;f=0}b=(Z(f,g)|0)+e|0;y=(l&1|2)+g+b|0;n=m+y|0;if(!k){i=z;return}u=j>>>2;w=(u|0)==0;v=g-j|0;x=16-j|0;t=u<<2;b=m+((Z(g,l>>>1&1|2)|0)+5+b)|0;s=k;while(1){if(!w){r=c+t|0;h=b;e=d[b+-1>>0]|0;f=d[b+-2>>0]|0;o=d[b+-3>>0]|0;p=d[b+-4>>0]|0;l=d[b+-5>>0]|0;q=u;while(1){A=p+e|0;B=p;p=d[h>>0]|0;a[c>>0]=a[(l+16-A-(A<<2)+p+((o+f|0)*20|0)>>5)+3984>>0]|0;A=p+o|0;l=o;o=d[h+1>>0]|0;a[c+1>>0]=a[(B+16-A-(A<<2)+o+((f+e|0)*20|0)>>5)+3984>>0]|0;A=o+f|0;B=f;f=d[h+2>>0]|0;a[c+2>>0]=a[(l+16-A-(A<<2)+f+((p+e|0)*20|0)>>5)+3984>>0]|0;A=f+e|0;l=d[h+3>>0]|0;a[c+3>>0]=a[(B+16-A-(A<<2)+l+((o+p|0)*20|0)>>5)+3984>>0]|0;q=q+-1|0;if(!q)break;else{A=e;c=c+4|0;h=h+4|0;e=l;l=A}}c=r;b=b+t|0}s=s+-1|0;if(!s)break;else{c=c+x|0;b=b+v|0}}b=k>>>2;if(!b){i=z;return}t=(j|0)==0;p=(g<<2)-j|0;o=64-j|0;q=0-g|0;s=q<<1;r=g<<1;c=c+(x-(k<<4))|0;h=m+(y+(g*5|0))|0;l=b;while(1){if(t){b=c;m=n}else{b=c+j|0;m=c;e=n;f=h;c=j;while(1){x=d[f+s>>0]|0;w=d[f+q>>0]|0;u=d[f+g>>0]|0;B=d[f>>0]|0;y=u+x|0;k=d[e+r>>0]|0;A=m+48|0;a[A>>0]=((d[((d[f+r>>0]|0)+16-y-(y<<2)+k+((B+w|0)*20|0)>>5)+3984>>0]|0)+1+(d[A>>0]|0)|0)>>>1;A=k+B|0;y=d[e+g>>0]|0;v=m+32|0;a[v>>0]=((d[(u+16-A-(A<<2)+y+((w+x|0)*20|0)>>5)+3984>>0]|0)+1+(d[v>>0]|0)|0)>>>1;v=d[e>>0]|0;A=y+w|0;u=m+16|0;a[u>>0]=((d[(B+16-A-(A<<2)+v+((k+x|0)*20|0)>>5)+3984>>0]|0)+1+(d[u>>0]|0)|0)>>>1;x=v+x|0;a[m>>0]=((d[(w+16-x-(x<<2)+(d[e+q>>0]|0)+((y+k|0)*20|0)>>5)+3984>>0]|0)+1+(d[m>>0]|0)|0)>>>1;c=c+-1|0;if(!c)break;else{m=m+1|0;e=e+1|0;f=f+1|0}}m=n+j|0;h=h+j|0}l=l+-1|0;if(!l)break;else{c=b+o|0;n=m+p|0;h=h+p|0}}i=z;return}function ac(b,e,f,g,h,j,k,l){b=b|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0;x=i;i=i+1792|0;m=x+1344|0;w=x;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0){o=l+5|0;m=b;n=f+5|0}else{n=k+5|0;o=l+5|0;Ub(b,m,f,g,h,j,n,o,n);h=n;n=5;g=0}if(o){t=k>>>2;v=(t|0)==0;s=h-k|0;u=t<<2;f=w;m=m+(n+(Z(g,h)|0))|0;while(1){if(v)b=f;else{b=f+(u<<2)|0;g=m;h=d[m+-1>>0]|0;j=d[m+-2>>0]|0;p=d[m+-3>>0]|0;q=d[m+-4>>0]|0;n=d[m+-5>>0]|0;r=t;while(1){y=q+h|0;z=q;q=d[g>>0]|0;c[f>>2]=n-y-(y<<2)+q+((p+j|0)*20|0);y=q+p|0;n=p;p=d[g+1>>0]|0;c[f+4>>2]=z-y+p-(y<<2)+((j+h|0)*20|0);y=p+j|0;z=j;j=d[g+2>>0]|0;c[f+8>>2]=n-y+j-(y<<2)+((q+h|0)*20|0);y=j+h|0;n=d[g+3>>0]|0;c[f+12>>2]=z-y+n-(y<<2)+((p+q|0)*20|0);r=r+-1|0;if(!r)break;else{y=h;f=f+16|0;g=g+4|0;h=n;n=y}}m=m+u|0}o=o+-1|0;if(!o)break;else{f=b;m=m+s|0}}}h=l>>>2;if(!h){i=x;return}u=(k|0)==0;s=64-k|0;p=k*3|0;t=0-k|0;q=t<<1;r=k<<1;g=e;b=w+(k<<2)|0;m=w+(k*6<<2)|0;o=h;while(1){if(u)h=g;else{h=g+k|0;f=b;j=m;n=k;while(1){e=c[j+(q<<2)>>2]|0;w=c[j+(t<<2)>>2]|0;z=c[j+(k<<2)>>2]|0;A=c[j>>2]|0;y=z+e|0;v=c[f+(r<<2)>>2]|0;a[g+48>>0]=a[((c[j+(r<<2)>>2]|0)+512-y-(y<<2)+v+((A+w|0)*20|0)>>10)+3984>>0]|0;y=v+A|0;l=c[f+(k<<2)>>2]|0;a[g+32>>0]=a[(z+512-y-(y<<2)+l+((w+e|0)*20|0)>>10)+3984>>0]|0;y=c[f>>2]|0;z=l+w|0;a[g+16>>0]=a[(A+512-z-(z<<2)+y+((v+e|0)*20|0)>>10)+3984>>0]|0;e=y+e|0;a[g>>0]=a[(w+512-e-(e<<2)+(c[f+(t<<2)>>2]|0)+((l+v|0)*20|0)>>10)+3984>>0]|0;n=n+-1|0;if(!n)break;else{g=g+1|0;f=f+4|0;j=j+4|0}}b=b+(k<<2)|0;m=m+(k<<2)|0}o=o+-1|0;if(!o)break;else{g=h+s|0;b=b+(p<<2)|0;m=m+(p<<2)|0}}i=x;return}function bc(b,e,f,g,h,j,k,l,m){b=b|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0;y=i;i=i+1792|0;n=y+1344|0;x=y;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0){o=l+5|0;n=b;f=f+5|0}else{q=k+5|0;o=l+5|0;Ub(b,n,f,g,h,j,q,o,q);h=q;f=5;g=0}if(o){v=k>>>2;t=(v|0)==0;u=h-k|0;w=v<<2;p=x;n=n+(f+(Z(g,h)|0))|0;s=o;while(1){if(t)b=p;else{b=p+(w<<2)|0;g=n;f=d[n+-1>>0]|0;h=d[n+-2>>0]|0;j=d[n+-3>>0]|0;q=d[n+-4>>0]|0;o=d[n+-5>>0]|0;r=v;while(1){z=q+f|0;A=q;q=d[g>>0]|0;c[p>>2]=o-z-(z<<2)+q+((j+h|0)*20|0);z=q+j|0;o=j;j=d[g+1>>0]|0;c[p+4>>2]=A-z+j-(z<<2)+((h+f|0)*20|0);z=j+h|0;A=h;h=d[g+2>>0]|0;c[p+8>>2]=o-z+h-(z<<2)+((q+f|0)*20|0);z=h+f|0;o=d[g+3>>0]|0;c[p+12>>2]=A-z+o-(z<<2)+((j+q|0)*20|0);r=r+-1|0;if(!r)break;else{z=f;p=p+16|0;g=g+4|0;f=o;o=z}}n=n+w|0}s=s+-1|0;if(!s)break;else{p=b;n=n+u|0}}}f=l>>>2;if(!f){i=y;return}w=(k|0)==0;u=64-k|0;q=k*3|0;v=0-k|0;t=v<<1;s=k<<1;b=x+(k<<2)|0;n=x+((Z(m+2|0,k)|0)+k<<2)|0;h=x+(k*6<<2)|0;r=f;while(1){if(w){g=e;f=n}else{f=n+(k<<2)|0;g=e+k|0;p=b;j=h;o=k;while(1){m=c[j+(t<<2)>>2]|0;l=c[j+(v<<2)>>2]|0;B=c[j+(k<<2)>>2]|0;C=c[j>>2]|0;A=B+m|0;z=c[p+(s<<2)>>2]|0;a[e+48>>0]=((d[((c[j+(s<<2)>>2]|0)+512-A-(A<<2)+z+((C+l|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(s<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;A=z+C|0;x=c[p+(k<<2)>>2]|0;a[e+32>>0]=((d[(B+512-A-(A<<2)+x+((l+m|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(k<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;A=c[p>>2]|0;B=x+l|0;a[e+16>>0]=((d[(C+512-B-(B<<2)+A+((z+m|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=A+m|0;a[e>>0]=((d[(l+512-m-(m<<2)+(c[p+(v<<2)>>2]|0)+((x+z|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(v<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;o=o+-1|0;if(!o)break;else{e=e+1|0;p=p+4|0;n=n+4|0;j=j+4|0}}b=b+(k<<2)|0;h=h+(k<<2)|0}r=r+-1|0;if(!r)break;else{e=g+u|0;b=b+(q<<2)|0;n=f+(q<<2)|0;h=h+(q<<2)|0}}i=y;return}function cc(b,e,f,g,h,j,k,l,m){b=b|0;e=e|0;f=f|0;g=g|0;h=h|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,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;B=i;i=i+1792|0;n=B+1344|0;A=B;z=k+5|0;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0)n=b;else{Ub(b,n,f,g,h,j,z,l+5|0,z);h=z;f=0;g=0}s=f+h+(Z(g,h)|0)|0;g=l>>>2;if(g){y=(z|0)==0;x=(h<<2)-k+-5|0;t=z*3|0;p=0-h|0;w=p<<1;v=h<<1;u=z<<1;q=-5-k|0;j=A+(z<<2)|0;r=n+s|0;f=n+(s+(h*5|0))|0;while(1){if(y)s=j;else{s=j+(z<<2)|0;n=r;b=f;o=z;while(1){E=d[b+w>>0]|0;F=d[b+p>>0]|0;H=d[b+h>>0]|0;I=d[b>>0]|0;G=H+E|0;C=d[n+v>>0]|0;c[j+(u<<2)>>2]=(d[b+v>>0]|0)-G-(G<<2)+C+((I+F|0)*20|0);G=C+I|0;D=d[n+h>>0]|0;c[j+(z<<2)>>2]=H-G+D-(G<<2)+((F+E|0)*20|0);G=d[n>>0]|0;H=D+F|0;c[j>>2]=I-H+G-(H<<2)+((C+E|0)*20|0);E=G+E|0;c[j+(q<<2)>>2]=F-E+(d[n+p>>0]|0)-(E<<2)+((D+C|0)*20|0);o=o+-1|0;if(!o)break;else{j=j+4|0;n=n+1|0;b=b+1|0}}r=r+z|0;f=f+z|0}g=g+-1|0;if(!g)break;else{j=s+(t<<2)|0;r=r+x|0;f=f+x|0}}}if(!l){i=B;return}v=k>>>2;w=(v|0)==0;u=16-k|0;t=v<<2;h=A+(m+2<<2)|0;g=A+20|0;while(1){if(w)f=h;else{f=h+(t<<2)|0;s=e;n=g;j=c[g+-4>>2]|0;o=c[g+-8>>2]|0;p=c[g+-12>>2]|0;q=c[g+-16>>2]|0;b=c[g+-20>>2]|0;r=v;while(1){m=q+j|0;k=q;q=c[n>>2]|0;a[s>>0]=((d[(b+512-m-(m<<2)+q+((p+o|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=q+p|0;b=p;p=c[n+4>>2]|0;a[s+1>>0]=((d[(k+512-m-(m<<2)+p+((o+j|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+4>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=p+o|0;k=o;o=c[n+8>>2]|0;a[s+2>>0]=((d[(b+512-m-(m<<2)+o+((q+j|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+8>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=o+j|0;b=c[n+12>>2]|0;a[s+3>>0]=((d[(k+512-m-(m<<2)+b+((p+q|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+12>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;r=r+-1|0;if(!r)break;else{m=j;s=s+4|0;h=h+16|0;n=n+16|0;j=b;b=m}}e=e+t|0;g=g+(t<<2)|0}l=l+-1|0;if(!l)break;else{e=e+u|0;h=f+20|0;g=g+20|0}}i=B;return}function dc(a,d,e,f,g,h,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|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;x=i;q=a+((j<<4)+h)|0;u=b[d>>1]|0;w=d+2|0;t=b[w>>1]|0;s=e+4|0;p=c[s>>2]<<4;r=e+8|0;o=c[r>>2]<<4;f=h+f|0;m=f+(u>>2)|0;g=j+g|0;n=g+(t>>2)|0;do switch(c[6800+((u&3)<<4)+((t&3)<<2)>>2]|0){case 10:{ac(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l);break}case 6:{cc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 4:{_b(c[e>>2]|0,q,m+-2|0,n,p,o,k,l,0);break}case 1:{Yb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l,0);break}case 2:{Xb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l);break}case 12:{_b(c[e>>2]|0,q,m+-2|0,n,p,o,k,l,1);break}case 14:{cc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}case 7:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,2);break}case 13:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}case 5:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 0:{Ub(c[e>>2]|0,q,m,n,p,o,k,l,16);break}case 9:{bc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 8:{Zb(c[e>>2]|0,q,m+-2|0,n,p,o,k,l);break}case 3:{Yb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l,1);break}case 11:{bc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}default:$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,3)}while(0);u=(h>>>1)+256+(j>>>1<<3)|0;v=a+u|0;t=c[e>>2]|0;m=c[s>>2]|0;j=c[r>>2]|0;r=m<<3;s=j<<3;p=b[d>>1]|0;e=(p>>3)+(f>>>1)|0;q=b[w>>1]|0;o=(q>>3)+(g>>>1)|0;p=p&7;q=q&7;g=k>>>1;h=l>>>1;j=Z(m<<8,j)|0;f=t+j|0;m=(p|0)!=0;n=(q|0)!=0;if(m&n){Wb(f,v,e,o,r,s,p,q,g,h);i=x;return}if(m){Tb(f,v,e,o,r,s,p,g,h);i=x;return}if(n){Vb(f,v,e,o,r,s,q,g,h);i=x;return}else{Ub(f,v,e,o,r,s,g,h,8);Ub(t+((Z(s,r)|0)+j)|0,a+(u+64)|0,e,o,r,s,g,h,8);i=x;return}}function ec(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,j=0;j=i;if(d){nd(c|0,a[b>>0]|0,d|0)|0;c=c+d|0}if(e){h=c+e|0;g=e;d=b;while(1){a[c>>0]=a[d>>0]|0;g=g+-1|0;if(!g)break;else{c=c+1|0;d=d+1|0}}c=h;b=b+e|0}if(!f){i=j;return}nd(c|0,a[b+-1>>0]|0,f|0)|0;i=j;return}function fc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;c=i;hd(b,a,d);i=c;return}function gc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;f=c[a+40>>2]|0;if(f){h=c[a>>2]|0;k=a+32|0;j=0;do{if(((c[h+(j*40|0)+20>>2]|0)+-1|0)>>>0<2){g=c[h+(j*40|0)+12>>2]|0;if(g>>>0>d>>>0)g=g-(c[k>>2]|0)|0;c[h+(j*40|0)+8>>2]=g}j=j+1|0}while((j|0)!=(f|0))}if(!(c[b>>2]|0)){p=0;i=q;return p|0}g=c[b+4>>2]|0;if(g>>>0>=3){p=0;i=q;return p|0}o=a+32|0;p=a+24|0;n=a+4|0;f=d;m=0;a:while(1){b:do if(g>>>0<2){k=c[b+(m*12|0)+8>>2]|0;if(!g){g=f-k|0;if((g|0)<0)g=(c[o>>2]|0)+g|0}else{l=k+f|0;g=c[o>>2]|0;g=l-((l|0)<(g|0)?0:g)|0}if(g>>>0>d>>>0)f=g-(c[o>>2]|0)|0;else f=g;j=c[p>>2]|0;if(!j){f=1;g=37;break a}k=c[a>>2]|0;l=0;while(1){h=c[k+(l*40|0)+20>>2]|0;if((h+-1|0)>>>0<2?(c[k+(l*40|0)+8>>2]|0)==(f|0):0){f=g;break b}l=l+1|0;if(l>>>0>=j>>>0){f=1;g=37;break a}}}else{j=c[b+(m*12|0)+12>>2]|0;h=c[p>>2]|0;if(!h){f=1;g=37;break a}k=c[a>>2]|0;g=0;while(1){if((c[k+(g*40|0)+20>>2]|0)==3?(c[k+(g*40|0)+8>>2]|0)==(j|0):0){h=3;l=g;break b}g=g+1|0;if(g>>>0>=h>>>0){f=1;g=37;break a}}}while(0);if(!((l|0)>-1&h>>>0>1)){f=1;g=37;break}if(m>>>0>>0){k=e;do{j=k;k=k+-1|0;h=c[n>>2]|0;c[h+(j<<2)>>2]=c[h+(k<<2)>>2]}while(k>>>0>m>>>0);k=c[a>>2]|0}c[(c[n>>2]|0)+(m<<2)>>2]=k+(l*40|0);m=m+1|0;if(m>>>0<=e>>>0){g=m;k=m;do{j=c[n>>2]|0;h=c[j+(g<<2)>>2]|0;if((h|0)!=((c[a>>2]|0)+(l*40|0)|0)){c[j+(k<<2)>>2]=h;k=k+1|0}g=g+1|0}while(g>>>0<=e>>>0)}g=c[b+(m*12|0)+4>>2]|0;if(g>>>0>=3){f=0;g=37;break}}if((g|0)==37){i=q;return f|0}return 0}function hc(a,b,d,e,f,g,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var 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,G=0,H=0,I=0,J=0,K=0;K=i;I=c[d>>2]|0;J=c[a+8>>2]|0;if((I|0)!=(c[J>>2]|0)){D=1;i=K;return D|0}B=a+52|0;c[B>>2]=0;G=c[a+56>>2]|0;o=(G|0)==0;H=o&1;do if(!b){c[J+20>>2]=0;c[J+12>>2]=e;c[J+8>>2]=e;c[J+16>>2]=f;c[J+24>>2]=H;if(o){d=a+44|0;c[d>>2]=(c[d>>2]|0)+1;d=0;r=0}else{d=G;r=0}}else{if(g){k=a+20|0;c[k>>2]=0;l=a+16|0;c[l>>2]=0;r=c[a>>2]|0;s=a+44|0;q=0;do{p=r+(q*40|0)+20|0;if((c[p>>2]|0)!=0?(c[p>>2]=0,(c[r+(q*40|0)+24>>2]|0)==0):0)c[s>>2]=(c[s>>2]|0)+-1;q=q+1|0}while((q|0)!=16);a:do if(o){n=c[a+28>>2]|0;m=a+12|0;q=0;while(1){e=0;p=2147483647;o=0;do{if(c[r+(e*40|0)+24>>2]|0){C=c[r+(e*40|0)+16>>2]|0;D=(C|0)<(p|0);p=D?C:p;o=D?r+(e*40|0)|0:o}e=e+1|0}while(e>>>0<=n>>>0);if(!o){d=0;break a}D=c[m>>2]|0;c[D+(q<<4)>>2]=c[o>>2];c[D+(q<<4)+12>>2]=c[o+36>>2];c[D+(q<<4)+4>>2]=c[o+28>>2];c[D+(q<<4)+8>>2]=c[o+32>>2];q=q+1|0;c[l>>2]=q;c[o+24>>2]=0;if(c[o+20>>2]|0)continue;c[s>>2]=(c[s>>2]|0)+-1}}else d=G;while(0);p=a+40|0;c[p>>2]=0;o=a+36|0;c[o>>2]=65535;c[a+48>>2]=0;if(!(c[b>>2]|d))d=0;else{c[l>>2]=0;c[k>>2]=0}r=(c[b+4>>2]|0)==0;c[J+20>>2]=r?2:3;c[o>>2]=r?65535:0;c[J+12>>2]=0;c[J+8>>2]=0;c[J+16>>2]=0;c[J+24>>2]=H;c[s>>2]=1;c[p>>2]=1;r=0;break}if(!(c[b+8>>2]|0)){d=a+40|0;q=c[d>>2]|0;p=c[a+24>>2]|0;if(q>>>0>=p>>>0)if(q){l=c[a>>2]|0;m=0;o=-1;n=0;do{if(((c[l+(m*40|0)+20>>2]|0)+-1|0)>>>0<2){D=c[l+(m*40|0)+8>>2]|0;C=(D|0)<(n|0)|(o|0)==-1;o=C?m:o;n=C?D:n}m=m+1|0}while((m|0)!=(q|0));if((o|0)>-1){q=q+-1|0;c[l+(o*40|0)+20>>2]=0;c[d>>2]=q;if(!(c[l+(o*40|0)+24>>2]|0)){d=a+44|0;c[d>>2]=(c[d>>2]|0)+-1;d=G;n=0}else{d=G;n=0}}else{d=G;n=1}}else{q=0;d=G;n=1}else{d=G;n=0}}else{E=a+24|0;C=a+40|0;v=a+44|0;x=a+36|0;A=a+48|0;u=a+28|0;y=a+16|0;z=a+12|0;r=G;d=G;t=0;w=0;b:while(1){switch(c[b+(t*20|0)+12>>2]|0){case 4:{l=c[b+(t*20|0)+28>>2]|0;c[x>>2]=l;m=c[E>>2]|0;if(!m)s=w;else{n=c[a>>2]|0;s=l;o=0;do{k=n+(o*40|0)+20|0;do if((c[k>>2]|0)==3){if((c[n+(o*40|0)+8>>2]|0)>>>0<=l>>>0)if((s|0)==65535)s=65535;else break;c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[n+(o*40|0)+24>>2]|0))c[v>>2]=(c[v>>2]|0)+-1}while(0);o=o+1|0}while((o|0)!=(m|0));s=w}break}case 1:{n=e-(c[b+(t*20|0)+16>>2]|0)|0;l=c[E>>2]|0;if(!l){n=1;break b}m=c[a>>2]|0;s=0;while(1){k=m+(s*40|0)+20|0;if(((c[k>>2]|0)+-1|0)>>>0<2?(c[m+(s*40|0)+8>>2]|0)==(n|0):0)break;s=s+1|0;if(s>>>0>=l>>>0){n=1;break b}}if((s|0)<0){n=1;break b}c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[m+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=w}else s=w;break}case 6:{m=c[b+(t*20|0)+24>>2]|0;s=c[x>>2]|0;if((s|0)==65535|s>>>0>>0){n=1;F=101;break b}r=c[E>>2]|0;c:do if(r){l=c[a>>2]|0;s=0;while(1){k=l+(s*40|0)+20|0;if((c[k>>2]|0)==3?(c[l+(s*40|0)+8>>2]|0)==(m|0):0)break;s=s+1|0;if(s>>>0>=r>>>0){F=88;break c}}c[k>>2]=0;k=(c[C>>2]|0)+-1|0;c[C>>2]=k;if(!(c[l+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=k}else s=k}else{r=0;F=88}while(0);if((F|0)==88){F=0;s=c[C>>2]|0}if(s>>>0>=r>>>0){n=1;F=101;break b}c[J+12>>2]=e;c[J+8>>2]=m;c[J+16>>2]=f;c[J+20>>2]=3;c[J+24>>2]=H;c[C>>2]=s+1;c[v>>2]=(c[v>>2]|0)+1;r=G;d=G;s=1;break}case 2:{l=c[b+(t*20|0)+20>>2]|0;m=c[E>>2]|0;if(!m){n=1;break b}n=c[a>>2]|0;s=0;while(1){k=n+(s*40|0)+20|0;if((c[k>>2]|0)==3?(c[n+(s*40|0)+8>>2]|0)==(l|0):0)break;s=s+1|0;if(s>>>0>=m>>>0){n=1;break b}}if((s|0)<0){n=1;break b}c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[n+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=w}else s=w;break}case 3:{s=c[b+(t*20|0)+16>>2]|0;n=c[b+(t*20|0)+24>>2]|0;k=c[x>>2]|0;if((k|0)==65535|k>>>0>>0){n=1;break b}o=c[E>>2]|0;if(!o){n=1;break b}p=c[a>>2]|0;k=0;while(1){m=p+(k*40|0)+20|0;if((c[m>>2]|0)==3?(c[p+(k*40|0)+8>>2]|0)==(n|0):0){F=47;break}l=k+1|0;if(l>>>0>>0)k=l;else break}if((F|0)==47?(F=0,c[m>>2]=0,c[C>>2]=(c[C>>2]|0)+-1,(c[p+(k*40|0)+24>>2]|0)==0):0)c[v>>2]=(c[v>>2]|0)+-1;m=e-s|0;s=0;while(1){l=p+(s*40|0)+20|0;k=c[l>>2]|0;if((k+-1|0)>>>0<2?(D=p+(s*40|0)+8|0,(c[D>>2]|0)==(m|0)):0)break;s=s+1|0;if(s>>>0>=o>>>0){n=1;break b}}if(!((s|0)>-1&k>>>0>1)){n=1;break b}c[l>>2]=3;c[D>>2]=n;s=w;break}case 5:{n=c[a>>2]|0;q=0;do{p=n+(q*40|0)+20|0;if((c[p>>2]|0)!=0?(c[p>>2]=0,(c[n+(q*40|0)+24>>2]|0)==0):0)c[v>>2]=(c[v>>2]|0)+-1;q=q+1|0}while((q|0)!=16);d:do if(!d){l=c[u>>2]|0;m=r;while(1){d=0;s=2147483647;k=0;do{if(c[n+(d*40|0)+24>>2]|0){o=c[n+(d*40|0)+16>>2]|0;e=(o|0)<(s|0);s=e?o:s;k=e?n+(d*40|0)|0:k}d=d+1|0}while(d>>>0<=l>>>0);if(!k){r=m;d=0;break d}s=c[y>>2]|0;d=c[z>>2]|0;c[d+(s<<4)>>2]=c[k>>2];c[d+(s<<4)+12>>2]=c[k+36>>2];c[d+(s<<4)+4>>2]=c[k+28>>2];c[d+(s<<4)+8>>2]=c[k+32>>2];c[y>>2]=s+1;c[k+24>>2]=0;if(!(c[k+20>>2]|0))c[v>>2]=(c[v>>2]|0)+-1;if(!m)m=0;else{r=m;d=m;break}}}while(0);c[C>>2]=0;c[x>>2]=65535;c[A>>2]=0;c[B>>2]=1;e=0;s=w;break}case 0:{n=0;F=101;break b}default:{n=1;break b}}t=t+1|0;w=s}if(w){r=n;break}q=c[C>>2]|0;p=c[E>>2]|0}if(q>>>0

>>0){c[J+12>>2]=e;c[J+8>>2]=e;c[J+16>>2]=f;c[J+20>>2]=2;c[J+24>>2]=H;r=a+44|0;c[r>>2]=(c[r>>2]|0)+1;c[a+40>>2]=q+1;r=n}else r=1}while(0);c[J+36>>2]=g;c[J+28>>2]=h;c[J+32>>2]=j;if(!d){o=a+44|0;d=c[o>>2]|0;k=c[a+28>>2]|0;if(d>>>0>k>>>0){p=a+16|0;q=a+12|0;do{n=c[a>>2]|0;e=0;l=2147483647;m=0;do{if(c[n+(e*40|0)+24>>2]|0){C=c[n+(e*40|0)+16>>2]|0;D=(C|0)<(l|0);l=D?C:l;m=D?n+(e*40|0)|0:m}e=e+1|0}while(e>>>0<=k>>>0);if((m|0)!=0?(D=c[p>>2]|0,C=c[q>>2]|0,c[C+(D<<4)>>2]=c[m>>2],c[C+(D<<4)+12>>2]=c[m+36>>2],c[C+(D<<4)+4>>2]=c[m+28>>2],c[C+(D<<4)+8>>2]=c[m+32>>2],c[p>>2]=D+1,c[m+24>>2]=0,(c[m+20>>2]|0)==0):0){d=d+-1|0;c[o>>2]=d}}while(d>>>0>k>>>0)}}else{k=a+16|0;D=c[k>>2]|0;C=c[a+12>>2]|0;c[C+(D<<4)>>2]=I;c[C+(D<<4)+12>>2]=g;c[C+(D<<4)+4>>2]=h;c[C+(D<<4)+8>>2]=j;c[k>>2]=D+1;k=c[a+28>>2]|0}rc(c[a>>2]|0,k+1|0);D=r;i=K;return D|0}function ic(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;if((b>>>0<=16?(d=c[(c[a+4>>2]|0)+(b<<2)>>2]|0,(d|0)!=0):0)?(c[d+20>>2]|0)>>>0>1:0)d=c[d>>2]|0;else d=0;i=e;return d|0}function jc(a){a=a|0;var b=0;b=(c[a>>2]|0)+((c[a+28>>2]|0)*40|0)|0;c[a+8>>2]=b;return c[b>>2]|0}function kc(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,j=0;j=i;c[a+36>>2]=65535;e=e>>>0>1?e:1;c[a+24>>2]=e;h=a+28|0;c[h>>2]=(g|0)==0?d:e;c[a+32>>2]=f;c[a+56>>2]=g;c[a+44>>2]=0;c[a+40>>2]=0;c[a+48>>2]=0;g=fd(680)|0;c[a>>2]=g;if(!g){g=65535;i=j;return g|0}id(g,0,680);a:do if((c[h>>2]|0)!=-1){f=b*384|47;e=0;while(1){d=fd(f)|0;g=c[a>>2]|0;c[g+(e*40|0)+4>>2]=d;if(!d){g=65535;break}c[g+(e*40|0)>>2]=d+(0-d&15);e=e+1|0;if(e>>>0>=((c[h>>2]|0)+1|0)>>>0)break a}i=j;return g|0}while(0);g=a+4|0;c[g>>2]=fd(68)|0;f=fd((c[h>>2]<<4)+16|0)|0;c[a+12>>2]=f;g=c[g>>2]|0;if((g|0)==0|(f|0)==0){g=65535;i=j;return g|0}id(g,0,68);c[a+20>>2]=0;c[a+16>>2]=0;g=0;i=j;return g|0}function lc(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,j=0,k=0,l=0;l=i;h=c[a>>2]|0;if(h){k=a+28|0;if((c[k>>2]|0)!=-1){j=0;do{gd(c[h+(j*40|0)+4>>2]|0);h=c[a>>2]|0;c[h+(j*40|0)+4>>2]=0;j=j+1|0}while(j>>>0<((c[k>>2]|0)+1|0)>>>0)}}else h=0;gd(h);c[a>>2]=0;h=a+4|0;gd(c[h>>2]|0);c[h>>2]=0;h=a+12|0;gd(c[h>>2]|0);c[h>>2]=0;h=kc(a,b,d,e,f,g)|0;i=l;return h|0}function mc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;b=c[a>>2]|0;if(b){e=a+28|0;if((c[e>>2]|0)!=-1){d=0;do{gd(c[b+(d*40|0)+4>>2]|0);b=c[a>>2]|0;c[b+(d*40|0)+4>>2]=0;d=d+1|0}while(d>>>0<((c[e>>2]|0)+1|0)>>>0)}}else b=0;gd(b);c[a>>2]=0;b=a+4|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+12|0;gd(c[b>>2]|0);c[b>>2]=0;i=f;return}function nc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;b=c[a+40>>2]|0;if(!b){i=f;return}e=a+4|0;d=0;do{c[(c[e>>2]|0)+(d<<2)>>2]=(c[a>>2]|0)+(d*40|0);d=d+1|0}while(d>>>0>>0);i=f;return}function oc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=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;y=i;v=a+16|0;c[v>>2]=0;c[a+20>>2]=0;if(!e){b=0;i=y;return b|0}x=a+48|0;e=c[x>>2]|0;f=(e|0)==(b|0);a:do if(!f?(u=a+32|0,l=c[u>>2]|0,k=((e+1|0)>>>0)%(l>>>0)|0,(k|0)!=(b|0)):0){t=a+28|0;w=c[(c[a>>2]|0)+((c[t>>2]|0)*40|0)>>2]|0;r=a+40|0;p=a+24|0;o=a+44|0;q=a+56|0;s=a+12|0;n=k;while(1){k=c[r>>2]|0;if(!k)k=0;else{j=c[a>>2]|0;h=0;do{if(((c[j+(h*40|0)+20>>2]|0)+-1|0)>>>0<2){e=c[j+(h*40|0)+12>>2]|0;c[j+(h*40|0)+8>>2]=e-(e>>>0>n>>>0?l:0)}h=h+1|0}while((h|0)!=(k|0))}if(k>>>0>=(c[p>>2]|0)>>>0){if(!k){e=1;g=46;break}f=c[a>>2]|0;h=0;l=-1;j=0;while(1){if(((c[f+(h*40|0)+20>>2]|0)+-1|0)>>>0<2){e=c[f+(h*40|0)+8>>2]|0;m=(e|0)<(j|0)|(l|0)==-1;g=m?h:l;j=m?e:j}else g=l;h=h+1|0;if((h|0)==(k|0))break;else l=g}if((g|0)<=-1){e=1;g=46;break}l=k+-1|0;c[f+(g*40|0)+20>>2]=0;c[r>>2]=l;if(!(c[f+(g*40|0)+24>>2]|0)){c[o>>2]=(c[o>>2]|0)+-1;k=l}else k=l}l=c[o>>2]|0;m=c[t>>2]|0;if(l>>>0>=m>>>0){e=(c[q>>2]|0)==0;do if(e){g=c[a>>2]|0;f=0;j=2147483647;h=0;do{if(c[g+(f*40|0)+24>>2]|0){A=c[g+(f*40|0)+16>>2]|0;z=(A|0)<(j|0);j=z?A:j;h=z?g+(f*40|0)|0:h}f=f+1|0}while(f>>>0<=m>>>0);if((h|0)!=0?(f=c[v>>2]|0,g=c[s>>2]|0,c[g+(f<<4)>>2]=c[h>>2],c[g+(f<<4)+12>>2]=c[h+36>>2],c[g+(f<<4)+4>>2]=c[h+28>>2],c[g+(f<<4)+8>>2]=c[h+32>>2],c[v>>2]=f+1,c[h+24>>2]=0,(c[h+20>>2]|0)==0):0){l=l+-1|0;c[o>>2]=l}}while(l>>>0>=m>>>0)}e=c[a>>2]|0;c[e+(m*40|0)+20>>2]=1;c[e+(m*40|0)+12>>2]=n;c[e+(m*40|0)+8>>2]=n;c[e+(m*40|0)+16>>2]=0;c[e+(m*40|0)+24>>2]=0;c[o>>2]=l+1;c[r>>2]=k+1;rc(e,m+1|0);l=c[u>>2]|0;n=((n+1|0)>>>0)%(l>>>0)|0;if((n|0)==(b|0)){g=31;break}}if((g|0)==31){g=c[v>>2]|0;if(!g){g=41;break}e=c[s>>2]|0;h=c[t>>2]|0;j=c[a>>2]|0;l=j+(h*40|0)|0;k=c[l>>2]|0;f=0;while(1){if((c[e+(f<<4)>>2]|0)==(k|0))break;f=f+1|0;if(f>>>0>=g>>>0){g=41;break a}}if(!h){g=41;break}else e=0;while(1){f=j+(e*40|0)|0;e=e+1|0;if((c[f>>2]|0)==(w|0))break;if(e>>>0>=h>>>0){g=41;break a}}c[f>>2]=k;c[l>>2]=w;g=41;break}else if((g|0)==46){i=y;return e|0}}else g=39;while(0);if((g|0)==39)if(d)if(f){b=1;i=y;return b|0}else g=41;do if((g|0)==41){if(!d){e=c[x>>2]|0;break}c[x>>2]=b;b=0;i=y;return b|0}while(0);if((e|0)==(b|0)){b=0;i=y;return b|0}a=c[a+32>>2]|0;c[x>>2]=((b+-1+a|0)>>>0)%(a>>>0)|0;b=0;i=y;return b|0}function pc(a){a=a|0;var b=0,d=0,e=0;e=i;d=a+20|0;b=c[d>>2]|0;if(b>>>0>=(c[a+16>>2]|0)>>>0){b=0;i=e;return b|0}a=c[a+12>>2]|0;c[d>>2]=b+1;b=a+(b<<4)|0;i=e;return b|0}function qc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;k=i;f=c[a>>2]|0;if(!f){i=k;return}c[a+60>>2]=1;if(c[a+56>>2]|0){i=k;return}g=c[a+28>>2]|0;h=a+16|0;j=a+12|0;e=a+44|0;a=0;b=2147483647;d=0;while(1){if(c[f+(a*40|0)+24>>2]|0){m=c[f+(a*40|0)+16>>2]|0;l=(m|0)<(b|0);b=l?m:b;d=l?f+(a*40|0)|0:d}a=a+1|0;if(a>>>0<=g>>>0)continue;if(!d)break;l=c[h>>2]|0;b=c[j>>2]|0;c[b+(l<<4)>>2]=c[d>>2];c[b+(l<<4)+12>>2]=c[d+36>>2];c[b+(l<<4)+4>>2]=c[d+28>>2];c[b+(l<<4)+8>>2]=c[d+32>>2];c[h>>2]=l+1;c[d+24>>2]=0;if(c[d+20>>2]|0){a=0;b=2147483647;d=0;continue}c[e>>2]=(c[e>>2]|0)+-1;a=0;b=2147483647;d=0}i=k;return}function rc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=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;v=i;i=i+32|0;q=v+16|0;t=v;o=7;do{if(o>>>0>>0){n=o;do{m=a+(n*40|0)|0;l=c[m>>2]|0;m=c[m+4>>2]|0;p=c[a+(n*40|0)+8>>2]|0;k=a+(n*40|0)+12|0;s=c[k+4>>2]|0;r=q;c[r>>2]=c[k>>2];c[r+4>>2]=s;r=c[a+(n*40|0)+20>>2]|0;s=c[a+(n*40|0)+24>>2]|0;k=a+(n*40|0)+28|0;c[t+0>>2]=c[k+0>>2];c[t+4>>2]=c[k+4>>2];c[t+8>>2]=c[k+8>>2];a:do if(n>>>0>>0){d=n;u=8}else{f=(s|0)==0;j=r+-1|0;k=j>>>0<2;b:do if(!r){e=n;while(1){d=e-o|0;if(c[a+(d*40|0)+20>>2]|0){d=e;break b}if((c[a+(d*40|0)+24>>2]|0)!=0|f){d=e;break b}e=a+(e*40|0)+0|0;g=a+(d*40|0)+0|0;h=e+40|0;do{c[e>>2]=c[g>>2];e=e+4|0;g=g+4|0}while((e|0)<(h|0));if(d>>>0>>0){u=8;break a}else e=d}}else{d=n;while(1){f=d-o|0;e=c[a+(f*40|0)+20>>2]|0;do if(e){e=e+-1|0;if((e|j)>>>0<2){e=c[a+(f*40|0)+8>>2]|0;if((e|0)>(p|0))break b;d=a+(d*40|0)|0;if((e|0)<(p|0))break;else break a}if(e>>>0<2)break b;if(!k?(c[a+(f*40|0)+8>>2]|0)<=(p|0):0)break b;else u=16}else u=16;while(0);if((u|0)==16){u=0;d=a+(d*40|0)|0}e=d+0|0;g=a+(f*40|0)+0|0;h=e+40|0;do{c[e>>2]=c[g>>2];e=e+4|0;g=g+4|0}while((e|0)<(h|0));if(f>>>0>>0){d=f;u=8;break a}else d=f}}while(0);d=a+(d*40|0)|0}while(0);if((u|0)==8){u=0;d=a+(d*40|0)|0}k=d;c[k>>2]=l;c[k+4>>2]=m;c[d+8>>2]=p;k=q;l=c[k+4>>2]|0;m=d+12|0;c[m>>2]=c[k>>2];c[m+4>>2]=l;c[d+20>>2]=r;c[d+24>>2]=s;m=d+28|0;c[m+0>>2]=c[t+0>>2];c[m+4>>2]=c[t+4>>2];c[m+8>>2]=c[t+8>>2];n=n+1|0}while((n|0)!=(b|0))}o=o>>>1}while((o|0)!=0);i=v;return}function sc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;e=c[a+4>>2]|0;f=c[a+16>>2]|0;g=c[a+20>>2]|0;j=e<<2;k=b+256|0;h=16;a=c[a+12>>2]|0;d=b;while(1){m=c[d+4>>2]|0;c[a>>2]=c[d>>2];c[a+4>>2]=m;m=c[d+12>>2]|0;c[a+8>>2]=c[d+8>>2];c[a+12>>2]=m;h=h+-1|0;if(!h)break;else{a=a+(j<<2)|0;d=d+16|0}}j=e<<1&2147483646;h=c[b+260>>2]|0;c[f>>2]=c[k>>2];c[f+4>>2]=h;k=c[b+268>>2]|0;c[f+(j<<2)>>2]=c[b+264>>2];c[f+((j|1)<<2)>>2]=k;k=e<<2;h=c[b+276>>2]|0;c[f+(k<<2)>>2]=c[b+272>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+284>>2]|0;c[f+(k<<2)>>2]=c[b+280>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+292>>2]|0;c[f+(k<<2)>>2]=c[b+288>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+300>>2]|0;c[f+(k<<2)>>2]=c[b+296>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+308>>2]|0;c[f+(k<<2)>>2]=c[b+304>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+316>>2]|0;c[f+(k<<2)>>2]=c[b+312>>2];c[f+((k|1)<<2)>>2]=h;k=c[b+324>>2]|0;c[g>>2]=c[b+320>>2];c[g+4>>2]=k;k=c[b+332>>2]|0;c[g+(j<<2)>>2]=c[b+328>>2];c[g+((j|1)<<2)>>2]=k;k=e<<2;h=c[b+340>>2]|0;c[g+(k<<2)>>2]=c[b+336>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+348>>2]|0;c[g+(k<<2)>>2]=c[b+344>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+356>>2]|0;c[g+(k<<2)>>2]=c[b+352>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+364>>2]|0;c[g+(k<<2)>>2]=c[b+360>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+372>>2]|0;c[g+(k<<2)>>2]=c[b+368>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;j=c[b+380>>2]|0;c[g+(k<<2)>>2]=c[b+376>>2];c[g+((k|1)<<2)>>2]=j;i=l;return}function tc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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;y=i;r=c[b+4>>2]|0;s=Z(c[b+8>>2]|0,r)|0;w=(e>>>0)%(r>>>0)|0;x=c[b>>2]|0;u=e-w|0;b=(u<<8)+(w<<4)|0;v=s<<8;w=w<<3;p=r<<4;o=r<<2&1073741820;l=o<<1;m=l+o|0;n=0;do{k=c[3344+(n<<2)>>2]|0;j=c[3408+(n<<2)>>2]|0;e=(j<<4)+k|0;h=f+e|0;j=b+k+(Z(j,p)|0)|0;k=x+j|0;q=c[g+(n<<6)>>2]|0;if((q|0)==16777215){j=c[f+(e+16)>>2]|0;c[k>>2]=c[h>>2];c[k+(o<<2)>>2]=j;j=c[f+(e+48)>>2]|0;c[k+(l<<2)>>2]=c[f+(e+32)>>2];c[k+(m<<2)>>2]=j}else{A=d[f+(e+1)>>0]|0;z=c[g+(n<<6)+4>>2]|0;a[k>>0]=a[3472+(q+512+(d[h>>0]|0))>>0]|0;q=d[f+(e+2)>>0]|0;t=c[g+(n<<6)+8>>2]|0;a[x+(j+1)>>0]=a[3472+((A|512)+z)>>0]|0;k=d[f+(e+3)>>0]|0;h=c[g+(n<<6)+12>>2]|0;a[x+(j+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(j+3)>>0]=a[3472+(h+512+k)>>0]|0;k=j+p|0;h=d[f+(e+17)>>0]|0;j=c[g+(n<<6)+20>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+16>>2]|0)+512+(d[f+(e+16)>>0]|0))>>0]|0;q=d[f+(e+18)>>0]|0;t=c[g+(n<<6)+24>>2]|0;a[x+(k+1)>>0]=a[3472+((h|512)+j)>>0]|0;j=d[f+(e+19)>>0]|0;h=c[g+(n<<6)+28>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(h+512+j)>>0]|0;k=k+p|0;j=d[f+(e+33)>>0]|0;h=c[g+(n<<6)+36>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+32>>2]|0)+512+(d[f+(e+32)>>0]|0))>>0]|0;q=d[f+(e+34)>>0]|0;t=c[g+(n<<6)+40>>2]|0;a[x+(k+1)>>0]=a[3472+((j|512)+h)>>0]|0;h=d[f+(e+35)>>0]|0;j=c[g+(n<<6)+44>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(j+512+h)>>0]|0;k=k+p|0;h=d[f+(e+49)>>0]|0;j=c[g+(n<<6)+52>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+48>>2]|0)+512+(d[f+(e+48)>>0]|0))>>0]|0;q=d[f+(e+50)>>0]|0;t=c[g+(n<<6)+56>>2]|0;a[x+(k+1)>>0]=a[3472+((h|512)+j)>>0]|0;j=d[f+(e+51)>>0]|0;h=c[g+(n<<6)+60>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(h+512+j)>>0]|0}n=n+1|0}while((n|0)!=16);t=s<<6;s=r<<3&2147483640;r=f+256|0;f=f+320|0;l=w+v+(u<<6)|0;p=s>>>2;j=s>>>1;k=j+p|0;o=16;do{q=o&3;h=c[3344+(q<<2)>>2]|0;q=c[3408+(q<<2)>>2]|0;e=o>>>0>19;m=e?f:r;n=(q<<3)+h|0;b=m+n|0;q=l+(e?t:0)+h+(Z(q,s)|0)|0;h=x+q|0;e=c[g+(o<<6)>>2]|0;if((e|0)==16777215){z=c[m+(n+8)>>2]|0;c[h>>2]=c[b>>2];c[h+(p<<2)>>2]=z;z=c[m+(n+24)>>2]|0;c[h+(j<<2)>>2]=c[m+(n+16)>>2];c[h+(k<<2)>>2]=z}else{v=d[m+(n+1)>>0]|0;z=c[g+(o<<6)+4>>2]|0;a[h>>0]=a[3472+(e+512+(d[b>>0]|0))>>0]|0;w=d[m+(n+2)>>0]|0;u=c[g+(o<<6)+8>>2]|0;a[x+(q+1)>>0]=a[3472+((v|512)+z)>>0]|0;z=d[m+(n+3)>>0]|0;v=c[g+(o<<6)+12>>2]|0;a[x+(q+2)>>0]=a[3472+(u+512+w)>>0]|0;a[x+(q+3)>>0]=a[3472+(v+512+z)>>0]|0;z=q+s|0;v=d[m+(n+9)>>0]|0;w=c[g+(o<<6)+20>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+16>>2]|0)+512+(d[m+(n+8)>>0]|0))>>0]|0;u=d[m+(n+10)>>0]|0;q=c[g+(o<<6)+24>>2]|0;a[x+(z+1)>>0]=a[3472+((v|512)+w)>>0]|0;w=d[m+(n+11)>>0]|0;v=c[g+(o<<6)+28>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(v+512+w)>>0]|0;z=z+s|0;w=d[m+(n+17)>>0]|0;v=c[g+(o<<6)+36>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+32>>2]|0)+512+(d[m+(n+16)>>0]|0))>>0]|0;u=d[m+(n+18)>>0]|0;q=c[g+(o<<6)+40>>2]|0;a[x+(z+1)>>0]=a[3472+((w|512)+v)>>0]|0;v=d[m+(n+19)>>0]|0;w=c[g+(o<<6)+44>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(w+512+v)>>0]|0;z=z+s|0;v=d[m+(n+25)>>0]|0;w=c[g+(o<<6)+52>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+48>>2]|0)+512+(d[m+(n+24)>>0]|0))>>0]|0;u=d[m+(n+26)>>0]|0;q=c[g+(o<<6)+56>>2]|0;a[x+(z+1)>>0]=a[3472+((v|512)+w)>>0]|0;w=d[m+(n+27)>>0]|0;v=c[g+(o<<6)+60>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(v+512+w)>>0]|0}o=o+1|0}while((o|0)!=24);i=y;return}function uc(e,f){e=e|0;f=f|0;var g=0,h=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,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,_=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,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;bb=i;i=i+176|0;ia=bb+40|0;La=bb;ea=c[e+4>>2]|0;ka=e+8|0;Wa=c[ka>>2]|0;g=Z(Wa,ea)|0;if(!Wa){i=bb;return}Za=ia+24|0;_a=ia+16|0;$a=ia+8|0;la=ia+100|0;ma=ia+68|0;na=ia+36|0;oa=ia+4|0;Ma=ia+120|0;Na=ia+112|0;Pa=ia+104|0;Qa=ia+96|0;Ra=ia+88|0;Sa=ia+80|0;Ta=ia+72|0;Ua=ia+64|0;Va=ia+56|0;Wa=ia+48|0;Xa=ia+40|0;Ya=ia+32|0;pa=ia+124|0;qa=ia+116|0;ra=ia+108|0;sa=ia+92|0;ta=ia+84|0;ua=ia+76|0;va=ia+60|0;wa=ia+52|0;xa=ia+44|0;ya=ia+28|0;za=ia+20|0;Aa=ia+12|0;ha=La+28|0;ja=La+32|0;Ka=La+24|0;Da=ea<<4;Ja=0-Da|0;Ca=Ja<<1;Ha=Z(ea,-48)|0;Ia=ea<<5;Ea=Ja<<2;Ga=ea*48|0;Ba=ea<<6;ga=La+24|0;fa=La+12|0;Fa=g<<8;ba=g<<6;ca=ea<<3;W=Da|4;Y=La+16|0;$=La+20|0;da=La+12|0;X=La+4|0;_=La+8|0;U=0;aa=0;V=f;while(1){f=c[V+8>>2]|0;do if((f|0)!=1){T=V+200|0;n=c[T>>2]|0;do if(!n)g=1;else{if((f|0)==2?(c[V+4>>2]|0)!=(c[n+4>>2]|0):0){g=1;break}g=5}while(0);S=V+204|0;l=c[S>>2]|0;do if(l){if((f|0)==2?(c[V+4>>2]|0)!=(c[l+4>>2]|0):0)break;g=g|2}while(0);R=(g&2|0)==0;do if(R){c[Za>>2]=0;c[_a>>2]=0;c[$a>>2]=0;c[ia>>2]=0;m=0}else{if((c[V>>2]|0)>>>0<=5?(c[l>>2]|0)>>>0<=5:0){if((b[V+28>>1]|0)==0?(b[l+48>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[l+124>>2]|0)?(B=(b[V+132>>1]|0)-(b[l+172>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){h=(b[V+134>>1]|0)-(b[l+174>>1]|0)|0;h=(((h|0)>-1?h:0-h|0)|0)>3&1}else h=1;else h=2;c[ia>>2]=h;if((b[V+30>>1]|0)==0?(b[l+50>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[l+124>>2]|0)?(B=(b[V+136>>1]|0)-(b[l+176>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){j=(b[V+138>>1]|0)-(b[l+178>>1]|0)|0;j=(((j|0)>-1?j:0-j|0)|0)>3&1}else j=1;else j=2;c[$a>>2]=j;if((b[V+36>>1]|0)==0?(b[l+56>>1]|0)==0:0)if((c[V+120>>2]|0)==(c[l+128>>2]|0)?(B=(b[V+148>>1]|0)-(b[l+188>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){k=(b[V+150>>1]|0)-(b[l+190>>1]|0)|0;k=(((k|0)>-1?k:0-k|0)|0)>3&1}else k=1;else k=2;c[_a>>2]=k;if((b[V+38>>1]|0)==0?(b[l+58>>1]|0)==0:0)if((c[V+120>>2]|0)==(c[l+128>>2]|0)?(B=(b[V+152>>1]|0)-(b[l+192>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){f=(b[V+154>>1]|0)-(b[l+194>>1]|0)|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=1;else f=2;c[Za>>2]=f;m=(j|h|k|f|0)!=0&1;break}c[Za>>2]=4;c[_a>>2]=4;c[$a>>2]=4;c[ia>>2]=4;m=1}while(0);Q=(g&4|0)==0;do if(Q){c[la>>2]=0;c[ma>>2]=0;c[na>>2]=0;c[oa>>2]=0;k=c[V>>2]|0}else{k=c[V>>2]|0;if(k>>>0<=5?(c[n>>2]|0)>>>0<=5:0){if((b[V+28>>1]|0)==0?(b[n+38>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[n+120>>2]|0)?(B=(b[V+132>>1]|0)-(b[n+152>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){j=(b[V+134>>1]|0)-(b[n+154>>1]|0)|0;j=(((j|0)>-1?j:0-j|0)|0)>3&1}else j=1;else j=2;c[oa>>2]=j;if((b[V+32>>1]|0)==0?(b[n+42>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[n+120>>2]|0)?(B=(b[V+140>>1]|0)-(b[n+160>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){h=(b[V+142>>1]|0)-(b[n+162>>1]|0)|0;h=(((h|0)>-1?h:0-h|0)|0)>3&1}else h=1;else h=2;c[na>>2]=h;if((b[V+44>>1]|0)==0?(b[n+54>>1]|0)==0:0)if((c[V+124>>2]|0)==(c[n+128>>2]|0)?(B=(b[V+164>>1]|0)-(b[n+184>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){f=(b[V+166>>1]|0)-(b[n+186>>1]|0)|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=1;else f=2;c[ma>>2]=f;if((b[V+48>>1]|0)==0?(b[n+58>>1]|0)==0:0)if((c[V+124>>2]|0)==(c[n+128>>2]|0)?(B=(b[V+172>>1]|0)-(b[n+192>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){l=(b[V+174>>1]|0)-(b[n+194>>1]|0)|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=1;else l=2;c[la>>2]=l;if(m)break;m=(h|j|f|l|0)!=0&1;break}c[la>>2]=4;c[ma>>2]=4;c[na>>2]=4;c[oa>>2]=4;m=1}while(0);if(k>>>0<=5){do if((db(k)|0)!=1){f=c[V>>2]|0;if((f|0)==2){w=V+28|0;x=b[V+32>>1]|0;if(!(x<<16>>16))f=(b[w>>1]|0)!=0?2:0;else f=2;c[Ya>>2]=f;q=b[V+34>>1]|0;A=q<<16>>16==0;if(A)f=(b[V+30>>1]|0)!=0?2:0;else f=2;c[Xa>>2]=f;g=b[V+40>>1]|0;z=g<<16>>16==0;if(z)l=(b[V+36>>1]|0)!=0?2:0;else l=2;c[Wa>>2]=l;v=b[V+42>>1]|0;y=v<<16>>16==0;if(y)l=(b[V+38>>1]|0)!=0?2:0;else l=2;c[Va>>2]=l;h=b[V+48>>1]|0;if(!(h<<16>>16))l=(b[V+44>>1]|0)!=0?2:0;else l=2;c[Qa>>2]=l;k=b[V+50>>1]|0;B=k<<16>>16==0;if(B)l=(b[V+46>>1]|0)!=0?2:0;else l=2;c[Pa>>2]=l;p=b[V+56>>1]|0;f=p<<16>>16==0;if(f)n=(b[V+52>>1]|0)!=0?2:0;else n=2;c[Na>>2]=n;j=(b[V+58>>1]|0)==0;if(j)n=(b[V+54>>1]|0)!=0?2:0;else n=2;c[Ma>>2]=n;r=b[V+44>>1]|0;o=b[V+166>>1]|0;n=b[V+142>>1]|0;do if(!((r|x)<<16>>16)){u=(b[V+164>>1]|0)-(b[V+140>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){n=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){n=1;break}n=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else n=2;while(0);c[Ua>>2]=n;s=b[V+46>>1]|0;o=b[V+170>>1]|0;n=b[V+146>>1]|0;do if(!((s|q)<<16>>16)){u=(b[V+168>>1]|0)-(b[V+144>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[Ta>>2]=o;t=b[V+52>>1]|0;o=b[V+182>>1]|0;n=b[V+158>>1]|0;do if(!((t|g)<<16>>16)){u=(b[V+180>>1]|0)-(b[V+156>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Sa>>2]=o;u=b[V+54>>1]|0;o=b[V+186>>1]|0;n=b[V+162>>1]|0;do if(!((u|v)<<16>>16)){v=(b[V+184>>1]|0)-(b[V+160>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){o=1;break}v=o-n|0;if((((v|0)>-1?v:0-v|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Ra>>2]=o;l=b[V+30>>1]|0;if(!(l<<16>>16))o=(b[w>>1]|0)!=0?2:0;else o=2;c[Aa>>2]=o;n=b[V+36>>1]|0;if(!(n<<16>>16))o=l<<16>>16!=0?2:0;else o=2;c[za>>2]=o;if(!(b[V+38>>1]|0))o=n<<16>>16!=0?2:0;else o=2;c[ya>>2]=o;if(A)n=x<<16>>16!=0?2:0;else n=2;c[xa>>2]=n;if(z)l=q<<16>>16!=0?2:0;else l=2;c[wa>>2]=l;if(y)l=g<<16>>16!=0?2:0;else l=2;c[va>>2]=l;if(!(s<<16>>16))l=r<<16>>16!=0?2:0;else l=2;c[ua>>2]=l;if(!(t<<16>>16))l=s<<16>>16!=0?2:0;else l=2;c[ta>>2]=l;if(!(u<<16>>16))l=t<<16>>16!=0?2:0;else l=2;c[sa>>2]=l;if(B)h=h<<16>>16!=0?2:0;else h=2;c[ra>>2]=h;if(f)f=k<<16>>16!=0?2:0;else f=2;c[qa>>2]=f;if(j)f=p<<16>>16!=0?2:0;else f=2;c[pa>>2]=f;break}else if((f|0)==3){j=V+28|0;v=b[V+32>>1]|0;if(!(v<<16>>16))f=(b[j>>1]|0)!=0?2:0;else f=2;c[Ya>>2]=f;B=b[V+34>>1]|0;p=B<<16>>16==0;if(p)h=(b[V+30>>1]|0)!=0?2:0;else h=2;c[Xa>>2]=h;z=b[V+40>>1]|0;if(!(z<<16>>16))k=(b[V+36>>1]|0)!=0?2:0;else k=2;c[Wa>>2]=k;o=b[V+42>>1]|0;h=o<<16>>16==0;if(h)l=(b[V+38>>1]|0)!=0?2:0;else l=2;c[Va>>2]=l;f=b[V+44>>1]|0;if(!(f<<16>>16))l=v<<16>>16!=0?2:0;else l=2;c[Ua>>2]=l;A=b[V+46>>1]|0;g=A<<16>>16==0;if(g)l=B<<16>>16!=0?2:0;else l=2;c[Ta>>2]=l;y=b[V+52>>1]|0;if(!(y<<16>>16))l=z<<16>>16!=0?2:0;else l=2;c[Sa>>2]=l;k=b[V+54>>1]|0;q=k<<16>>16==0;if(q)l=o<<16>>16!=0?2:0;else l=2;c[Ra>>2]=l;r=b[V+48>>1]|0;if(!(r<<16>>16))n=f<<16>>16!=0?2:0;else n=2;c[Qa>>2]=n;x=b[V+50>>1]|0;s=x<<16>>16==0;if(s)n=A<<16>>16!=0?2:0;else n=2;c[Pa>>2]=n;w=b[V+56>>1]|0;if(!(w<<16>>16))o=y<<16>>16!=0?2:0;else o=2;c[Na>>2]=o;u=(b[V+58>>1]|0)==0;if(u)o=k<<16>>16!=0?2:0;else o=2;c[Ma>>2]=o;t=b[V+30>>1]|0;if(!(t<<16>>16))o=(b[j>>1]|0)!=0?2:0;else o=2;c[Aa>>2]=o;if(!(b[V+38>>1]|0))o=(b[V+36>>1]|0)!=0?2:0;else o=2;c[ya>>2]=o;if(p)n=v<<16>>16!=0?2:0;else n=2;c[xa>>2]=n;if(h)n=z<<16>>16!=0?2:0;else n=2;c[va>>2]=n;if(g)l=f<<16>>16!=0?2:0;else l=2;c[ua>>2]=l;if(q)l=y<<16>>16!=0?2:0;else l=2;c[sa>>2]=l;if(s)l=r<<16>>16!=0?2:0;else l=2;c[ra>>2]=l;if(u)l=w<<16>>16!=0?2:0;else l=2;c[pa>>2]=l;l=b[V+150>>1]|0;k=b[V+138>>1]|0;do if(!((b[V+36>>1]|t)<<16>>16)){v=(b[V+148>>1]|0)-(b[V+136>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){l=1;break}v=l-k|0;if((((v|0)>-1?v:0-v|0)|0)>3){l=1;break}l=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else l=2;while(0);c[za>>2]=l;l=b[V+158>>1]|0;k=b[V+146>>1]|0;do if(!((z|B)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+144>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}B=l-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}k=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else k=2;while(0);c[wa>>2]=k;l=b[V+182>>1]|0;k=b[V+170>>1]|0;do if(!((y|A)<<16>>16)){B=(b[V+180>>1]|0)-(b[V+168>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}B=l-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else f=2;while(0);c[ta>>2]=f;f=b[V+190>>1]|0;g=b[V+178>>1]|0;do if(!((w|x)<<16>>16)){B=(b[V+188>>1]|0)-(b[V+176>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}B=f-g|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else f=2;while(0);c[qa>>2]=f;break}else{K=b[V+32>>1]|0;z=b[V+28>>1]|0;P=b[V+142>>1]|0;q=b[V+134>>1]|0;if(!((z|K)<<16>>16)){B=(b[V+140>>1]|0)-(b[V+132>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)k=1;else{k=P-q|0;k=(((k|0)>-1?k:0-k|0)|0)>3&1}}else k=2;c[Ya>>2]=k;L=b[V+34>>1]|0;y=b[V+30>>1]|0;O=b[V+146>>1]|0;r=b[V+138>>1]|0;if(!((y|L)<<16>>16)){B=(b[V+144>>1]|0)-(b[V+136>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)l=1;else{l=O-r|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}}else l=2;c[Xa>>2]=l;M=b[V+40>>1]|0;x=b[V+36>>1]|0;N=b[V+158>>1]|0;s=b[V+150>>1]|0;if(!((x|M)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+148>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)n=1;else{n=N-s|0;n=(((n|0)>-1?n:0-n|0)|0)>3&1}}else n=2;c[Wa>>2]=n;n=b[V+42>>1]|0;B=b[V+38>>1]|0;J=b[V+162>>1]|0;A=b[V+154>>1]|0;if(!((B|n)<<16>>16)){w=(b[V+160>>1]|0)-(b[V+152>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3)o=1;else{o=J-A|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}}else o=2;c[Va>>2]=o;D=b[V+44>>1]|0;I=b[V+166>>1]|0;do if(!((D|K)<<16>>16)){w=(b[V+164>>1]|0)-(b[V+140>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3)o=1;else{w=I-P|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}}else o=2;while(0);c[Ua>>2]=o;E=b[V+46>>1]|0;H=b[V+170>>1]|0;do if(!((E|L)<<16>>16)){w=(b[V+168>>1]|0)-(b[V+144>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}w=H-O|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[Ta>>2]=o;F=b[V+52>>1]|0;G=b[V+182>>1]|0;do if(!((F|M)<<16>>16)){w=(b[V+180>>1]|0)-(b[V+156>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}w=G-N|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Sa>>2]=o;g=b[V+54>>1]|0;l=b[V+186>>1]|0;do if(!((g|n)<<16>>16)){w=(b[V+184>>1]|0)-(b[V+160>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}w=l-J|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else u=2;while(0);c[Ra>>2]=u;f=b[V+48>>1]|0;C=b[V+174>>1]|0;do if(!((f|D)<<16>>16)){w=(b[V+172>>1]|0)-(b[V+164>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=C-I|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Qa>>2]=u;h=b[V+50>>1]|0;k=b[V+178>>1]|0;do if(!((h|E)<<16>>16)){w=(b[V+176>>1]|0)-(b[V+168>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=k-H|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Pa>>2]=u;j=b[V+56>>1]|0;p=b[V+190>>1]|0;do if(!((j|F)<<16>>16)){w=(b[V+188>>1]|0)-(b[V+180>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=p-G|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Na>>2]=u;w=b[V+58>>1]|0;t=b[V+194>>1]|0;do if(!((w|g)<<16>>16)){v=(b[V+192>>1]|0)-(b[V+184>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){v=1;break}v=t-l|0;v=(((v|0)>-1?v:0-v|0)|0)>3&1}else v=2;while(0);c[Ma>>2]=v;do if(!((y|z)<<16>>16)){z=(b[V+136>>1]|0)-(b[V+132>>1]|0)|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}u=r-q|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Aa>>2]=u;do if(!((x|y)<<16>>16)){z=(b[V+148>>1]|0)-(b[V+136>>1]|0)|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}z=s-r|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}u=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else u=2;while(0);c[za>>2]=u;do if(!((B|x)<<16>>16)){B=(b[V+152>>1]|0)-(b[V+148>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){u=1;break}u=A-s|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[ya>>2]=u;do if(!((L|K)<<16>>16)){B=(b[V+144>>1]|0)-(b[V+140>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=O-P|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}else o=2;while(0);c[xa>>2]=o;do if(!((M|L)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+144>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}B=N-O|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[wa>>2]=o;do if(!((n|M)<<16>>16)){B=(b[V+160>>1]|0)-(b[V+156>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=J-N|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}else o=2;while(0);c[va>>2]=o;do if(!((E|D)<<16>>16)){B=(b[V+168>>1]|0)-(b[V+164>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}n=H-I|0;n=(((n|0)>-1?n:0-n|0)|0)>3&1}else n=2;while(0);c[ua>>2]=n;do if(!((F|E)<<16>>16)){B=(b[V+180>>1]|0)-(b[V+168>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}B=G-H|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}n=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else n=2;while(0);c[ta>>2]=n;do if(!((g|F)<<16>>16)){B=(b[V+184>>1]|0)-(b[V+180>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){l=1;break}l=l-G|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=2;while(0);c[sa>>2]=l;do if(!((h|f)<<16>>16)){B=(b[V+176>>1]|0)-(b[V+172>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){l=1;break}l=k-C|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=2;while(0);c[ra>>2]=l;do if(!((j|h)<<16>>16)){B=(b[V+188>>1]|0)-(b[V+176>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}B=p-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}k=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else k=2;while(0);c[qa>>2]=k;do if(!((w|j)<<16>>16)){B=(b[V+192>>1]|0)-(b[V+188>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=t-p|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=2;while(0);c[pa>>2]=f;break}}else vc(V,ia);while(0);if(!(m|c[Ya>>2]|c[Xa>>2]|c[Wa>>2]|c[Va>>2]|c[Ua>>2]|c[Ta>>2]|c[Sa>>2]|c[Ra>>2]|c[Qa>>2]|c[Pa>>2]|c[Na>>2]|c[Ma>>2]|c[Aa>>2]|c[za>>2]|c[ya>>2]|c[xa>>2]|c[wa>>2]|c[va>>2]|c[ua>>2]|c[ta>>2]|c[sa>>2]|c[ra>>2]|c[qa>>2]|c[pa>>2]))break}else{c[Ma>>2]=3;c[Na>>2]=3;c[Pa>>2]=3;c[Qa>>2]=3;c[Ra>>2]=3;c[Sa>>2]=3;c[Ta>>2]=3;c[Ua>>2]=3;c[Va>>2]=3;c[Wa>>2]=3;c[Xa>>2]=3;c[Ya>>2]=3;c[pa>>2]=3;c[qa>>2]=3;c[ra>>2]=3;c[sa>>2]=3;c[ta>>2]=3;c[ua>>2]=3;c[va>>2]=3;c[wa>>2]=3;c[xa>>2]=3;c[ya>>2]=3;c[za>>2]=3;c[Aa>>2]=3}J=V+20|0;g=c[J>>2]|0;L=V+12|0;k=Oa(0,51,(c[L>>2]|0)+g|0)|0;K=V+16|0;h=Oa(0,51,(c[K>>2]|0)+g|0)|0;j=d[6864+k>>0]|0;c[ha>>2]=j;h=d[6920+h>>0]|0;c[ja>>2]=h;k=6976+(k*3|0)|0;c[Ka>>2]=k;do if(!R){l=c[(c[S>>2]|0)+20>>2]|0;if((l|0)==(g|0)){c[X>>2]=j;c[_>>2]=h;c[La>>2]=k;break}else{A=(g+1+l|0)>>>1;B=Oa(0,51,(c[L>>2]|0)+A|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[X>>2]=d[6864+B>>0];c[_>>2]=d[6920+A>>0];c[La>>2]=6976+(B*3|0);break}}while(0);do if(!Q){f=c[(c[T>>2]|0)+20>>2]|0;if((f|0)==(g|0)){c[Y>>2]=c[ha>>2];c[$>>2]=c[ja>>2];c[da>>2]=c[Ka>>2];break}else{A=(g+1+f|0)>>>1;B=Oa(0,51,(c[L>>2]|0)+A|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[Y>>2]=d[6864+B>>0];c[$>>2]=d[6920+A>>0];c[da>>2]=6976+(B*3|0);break}}while(0);M=Z(aa,ea)|0;P=3;o=0;O=(c[e>>2]|0)+((M<<8)+(U<<4))|0;N=ia;while(1){l=c[N+4>>2]|0;if(l)wc(O,l,fa,Da);l=c[N+12>>2]|0;if(l)wc(O+4|0,l,ga,Da);k=N+16|0;m=c[N+20>>2]|0;if(m)wc(O+8|0,m,ga,Da);j=N+24|0;m=c[N+28>>2]|0;if(m)wc(O+12|0,m,ga,Da);n=c[N>>2]|0;l=N+8|0;m=c[l>>2]|0;a:do if(((n|0)==(m|0)?(n|0)==(c[k>>2]|0):0)?(n|0)==(c[j>>2]|0):0){if(!n)break;y=c[La+(o*12|0)+4>>2]|0;x=c[La+(o*12|0)+8>>2]|0;if(n>>>0<4){t=d[(c[La+(o*12|0)>>2]|0)+(n+-1)>>0]|0;k=0-t|0;j=t+1|0;f=O;h=16;while(1){o=f+Ca|0;s=d[o>>0]|0;u=f+Ja|0;r=d[u>>0]|0;q=d[f>>0]|0;m=f+Da|0;g=d[m>>0]|0;B=r-q|0;do if(((B|0)>-1?B:0-B|0)>>>0>>0){B=s-r|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=g-q|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;n=d[f+Ha>>0]|0;B=n-r|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[o>>0]=(Oa(k,t,((r+1+q|0)>>>1)-(s<<1)+n>>1)|0)+s;o=j}else o=t;n=d[f+Ia>>0]|0;B=n-q|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[m>>0]=(Oa(k,t,((r+1+q|0)>>>1)-(g<<1)+n>>1)|0)+g;o=o+1|0}A=Oa(0-o|0,o,s+4-g+(q-r<<2)>>3)|0;B=a[3472+((q|512)-A)>>0]|0;a[u>>0]=a[3472+(A+(r|512))>>0]|0;a[f>>0]=B}while(0);h=h+-1|0;if(!h)break a;else f=f+1|0}}n=(y>>>2)+2|0;t=O;u=16;while(1){m=t+Ca|0;f=d[m>>0]|0;l=t+Ja|0;g=d[l>>0]|0;p=d[t>>0]|0;k=t+Da|0;q=d[k>>0]|0;o=g-p|0;o=(o|0)>-1?o:0-o|0;b:do if(o>>>0>>0){B=f-g|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=q-p|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;j=t+Ha|0;r=d[j>>0]|0;h=t+Ia|0;s=d[h>>0]|0;do if(o>>>0>>0){B=r-g|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){B=g+f+p|0;a[l>>0]=(q+4+(B<<1)+r|0)>>>3;a[m>>0]=(B+2+r|0)>>>2;a[j>>0]=(B+4+(r*3|0)+(d[t+Ea>>0]<<1)|0)>>>3}else a[l>>0]=(g+2+(f<<1)+q|0)>>>2;B=s-p|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=p+g+q|0;a[t>>0]=(f+4+(B<<1)+s|0)>>>3;a[k>>0]=(B+2+s|0)>>>2;a[h>>0]=(B+4+(s*3|0)+(d[t+Ga>>0]<<1)|0)>>>3;break b}else a[l>>0]=(g+2+(f<<1)+q|0)>>>2;while(0);a[t>>0]=(f+2+p+(q<<1)|0)>>>2}while(0);u=u+-1|0;if(!u)break;else t=t+1|0}}else ab=311;while(0);do if((ab|0)==311){ab=0;if(n){xc(O,n,La+(o*12|0)|0,Da);m=c[l>>2]|0}if(m)xc(O+4|0,m,La+(o*12|0)|0,Da);m=c[k>>2]|0;if(m)xc(O+8|0,m,La+(o*12|0)|0,Da);l=c[j>>2]|0;if(!l)break;xc(O+12|0,l,La+(o*12|0)|0,Da)}while(0);if(!P)break;else{P=P+-1|0;o=2;O=O+Ba|0;N=N+32|0}}h=c[V+24>>2]|0;g=c[192+((Oa(0,51,(c[J>>2]|0)+h|0)|0)<<2)>>2]|0;m=Oa(0,51,(c[L>>2]|0)+g|0)|0;j=Oa(0,51,(c[K>>2]|0)+g|0)|0;k=d[6864+m>>0]|0;c[ha>>2]=k;j=d[6920+j>>0]|0;c[ja>>2]=j;m=6976+(m*3|0)|0;c[Ka>>2]=m;do if(!R){l=c[(c[S>>2]|0)+20>>2]|0;if((l|0)==(c[J>>2]|0)){c[X>>2]=k;c[_>>2]=j;c[La>>2]=m;break}else{A=(g+1+(c[192+((Oa(0,51,l+h|0)|0)<<2)>>2]|0)|0)>>>1;B=Oa(0,51,A+(c[L>>2]|0)|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[X>>2]=d[6864+B>>0];c[_>>2]=d[6920+A>>0];c[La>>2]=6976+(B*3|0);break}}while(0);do if(!Q){f=c[(c[T>>2]|0)+20>>2]|0;if((f|0)==(c[J>>2]|0)){c[Y>>2]=c[ha>>2];c[$>>2]=c[ja>>2];c[da>>2]=c[Ka>>2];break}else{A=(g+1+(c[192+((Oa(0,51,f+h|0)|0)<<2)>>2]|0)|0)>>>1;B=Oa(0,51,A+(c[L>>2]|0)|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[Y>>2]=d[6864+B>>0];c[$>>2]=d[6920+A>>0];c[da>>2]=6976+(B*3|0);break}}while(0);j=c[e>>2]|0;l=(U<<3)+Fa+(M<<6)|0;n=j+l|0;l=j+(l+ba)|0;j=0;h=ia;o=0;while(1){g=h+4|0;f=c[g>>2]|0;if(f){yc(n,f,fa,ca);yc(l,c[g>>2]|0,fa,ca)}g=h+36|0;f=c[g>>2]|0;if(f){yc(n+Da|0,f,fa,ca);yc(l+Da|0,c[g>>2]|0,fa,ca)}m=h+16|0;g=h+20|0;f=c[g>>2]|0;if(f){yc(n+4|0,f,ga,ca);yc(l+4|0,c[g>>2]|0,ga,ca)}g=h+52|0;f=c[g>>2]|0;if(f){yc(n+W|0,f,ga,ca);yc(l+W|0,c[g>>2]|0,ga,ca)}g=c[h>>2]|0;k=h+8|0;f=c[k>>2]|0;do if((g|0)==(f|0)){if((g|0)!=(c[m>>2]|0)){ab=342;break}if((g|0)!=(c[h+24>>2]|0)){ab=342;break}if(!g)break;B=La+(j*12|0)|0;zc(n,g,B,ca);zc(l,c[h>>2]|0,B,ca)}else ab=342;while(0);do if((ab|0)==342){ab=0;if(g){f=La+(j*12|0)|0;Ac(n,g,f,ca);Ac(l,c[h>>2]|0,f,ca);f=c[k>>2]|0}if(f){B=La+(j*12|0)|0;Ac(n+2|0,f,B,ca);Ac(l+2|0,c[k>>2]|0,B,ca)}f=c[m>>2]|0;if(f){B=La+(j*12|0)|0;Ac(n+4|0,f,B,ca);Ac(l+4|0,c[m>>2]|0,B,ca)}g=h+24|0;f=c[g>>2]|0;if(!f)break;B=La+(j*12|0)|0;Ac(n+6|0,f,B,ca);Ac(l+6|0,c[g>>2]|0,B,ca)}while(0);o=o+1|0;if((o|0)==2)break;else{n=n+Ia|0;l=l+Ia|0;j=2;h=h+64|0}}}while(0);f=U+1|0;g=(f|0)==(ea|0);aa=(g&1)+aa|0;if(aa>>>0>=(c[ka>>2]|0)>>>0)break;else{U=g?0:f;V=V+216|0}}i=bb;return}function vc(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=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;B=i;l=a+28|0;y=b[a+32>>1]|0;if(!(y<<16>>16))e=(b[l>>1]|0)!=0?2:0;else e=2;c[d+32>>2]=e;z=b[a+34>>1]|0;x=z<<16>>16==0;if(x)e=(b[a+30>>1]|0)!=0?2:0;else e=2;c[d+40>>2]=e;A=b[a+40>>1]|0;v=A<<16>>16==0;if(v)e=(b[a+36>>1]|0)!=0?2:0;else e=2;c[d+48>>2]=e;f=b[a+42>>1]|0;w=f<<16>>16==0;if(w)e=(b[a+38>>1]|0)!=0?2:0;else e=2;c[d+56>>2]=e;s=b[a+44>>1]|0;if(!(s<<16>>16))e=y<<16>>16!=0?2:0;else e=2;c[d+64>>2]=e;t=b[a+46>>1]|0;p=t<<16>>16==0;if(p)e=z<<16>>16!=0?2:0;else e=2;c[d+72>>2]=e;u=b[a+52>>1]|0;q=u<<16>>16==0;if(q)e=A<<16>>16!=0?2:0;else e=2;c[d+80>>2]=e;g=b[a+54>>1]|0;r=g<<16>>16==0;if(r)e=f<<16>>16!=0?2:0;else e=2;c[d+88>>2]=e;m=b[a+48>>1]|0;if(!(m<<16>>16))e=s<<16>>16!=0?2:0;else e=2;c[d+96>>2]=e;n=b[a+50>>1]|0;h=n<<16>>16==0;if(h)e=t<<16>>16!=0?2:0;else e=2;c[d+104>>2]=e;o=b[a+56>>1]|0;j=o<<16>>16==0;if(j)f=u<<16>>16!=0?2:0;else f=2;c[d+112>>2]=f;k=(b[a+58>>1]|0)==0;if(k)f=g<<16>>16!=0?2:0;else f=2;c[d+120>>2]=f;g=b[a+30>>1]|0;if(!(g<<16>>16))f=(b[l>>1]|0)!=0?2:0;else f=2;c[d+12>>2]=f;e=b[a+36>>1]|0;if(!(e<<16>>16))f=g<<16>>16!=0?2:0;else f=2;c[d+20>>2]=f;if(!(b[a+38>>1]|0))e=e<<16>>16!=0?2:0;else e=2;c[d+28>>2]=e;if(x)e=y<<16>>16!=0?2:0;else e=2;c[d+44>>2]=e;if(v)e=z<<16>>16!=0?2:0;else e=2;c[d+52>>2]=e;if(w)e=A<<16>>16!=0?2:0;else e=2;c[d+60>>2]=e;if(p)e=s<<16>>16!=0?2:0;else e=2;c[d+76>>2]=e;if(q)e=t<<16>>16!=0?2:0;else e=2;c[d+84>>2]=e;if(r)e=u<<16>>16!=0?2:0;else e=2;c[d+92>>2]=e;if(h)e=m<<16>>16!=0?2:0;else e=2;c[d+108>>2]=e;if(j)e=n<<16>>16!=0?2:0;else e=2;c[d+116>>2]=e;if(!k){y=2;z=d+124|0;c[z>>2]=y;i=B;return}y=o<<16>>16!=0?2:0;z=d+124|0;c[z>>2]=y;i=B;return}function wc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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;w=i;u=c[f+4>>2]|0;v=c[f+8>>2]|0;if(e>>>0<4){l=d[(c[f>>2]|0)+(e+-1)>>0]|0;n=0-l|0;m=l+1|0;k=4;while(1){f=b+-2|0;s=d[f>>0]|0;t=b+-1|0;r=d[t>>0]|0;q=d[b>>0]|0;j=b+1|0;h=d[j>>0]|0;o=r-q|0;if((((o|0)>-1?o:0-o|0)>>>0>>0?(o=s-r|0,((o|0)>-1?o:0-o|0)>>>0>>0):0)?(o=h-q|0,((o|0)>-1?o:0-o|0)>>>0>>0):0){e=d[b+-3>>0]|0;p=d[b+2>>0]|0;o=e-r|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){a[f>>0]=(Oa(n,l,((r+1+q|0)>>>1)-(s<<1)+e>>1)|0)+s;f=m}else f=l;o=p-q|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){a[j>>0]=(Oa(n,l,((r+1+q|0)>>>1)-(h<<1)+p>>1)|0)+h;f=f+1|0}j=Oa(0-f|0,f,s+4-h+(q-r<<2)>>3)|0;o=a[3472+((q|512)-j)>>0]|0;a[t>>0]=a[3472+((r|512)+j)>>0]|0;a[b>>0]=o}k=k+-1|0;if(!k)break;else b=b+g|0}i=w;return}t=(u>>>2)+2|0;s=4;while(1){k=b+-2|0;q=d[k>>0]|0;l=b+-1|0;r=d[l>>0]|0;m=d[b>>0]|0;e=b+1|0;n=d[e>>0]|0;f=r-m|0;f=(f|0)>-1?f:0-f|0;do if((f>>>0>>0?(o=q-r|0,((o|0)>-1?o:0-o|0)>>>0>>0):0)?(o=n-m|0,((o|0)>-1?o:0-o|0)>>>0>>0):0){h=b+-3|0;o=d[h>>0]|0;j=b+2|0;p=d[j>>0]|0;if(f>>>0>>0){f=o-r|0;if(((f|0)>-1?f:0-f|0)>>>0>>0){f=r+q+m|0;a[l>>0]=(n+4+(f<<1)+o|0)>>>3;a[k>>0]=(f+2+o|0)>>>2;a[h>>0]=(f+4+(o*3|0)+((d[b+-4>>0]|0)<<1)|0)>>>3}else a[l>>0]=(r+2+(q<<1)+n|0)>>>2;o=p-m|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){o=m+r+n|0;a[b>>0]=(q+4+(o<<1)+p|0)>>>3;a[e>>0]=(o+2+p|0)>>>2;a[j>>0]=(o+4+(p*3|0)+((d[b+3>>0]|0)<<1)|0)>>>3;break}}else a[l>>0]=(r+2+(q<<1)+n|0)>>>2;a[b>>0]=(q+2+m+(n<<1)|0)>>>2}while(0);s=s+-1|0;if(!s)break;else b=b+g|0}i=w;return}function xc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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=i;u=d[(c[f>>2]|0)+(e+-1)>>0]|0;w=0-g|0;v=w<<1;t=f+4|0;o=f+8|0;q=Z(g,-3)|0;s=0-u|0;p=u+1|0;r=g<<1;n=4;while(1){e=b+v|0;k=b+w|0;j=b+g|0;f=a[j>>0]|0;l=d[k>>0]|0;m=d[b>>0]|0;h=l-m|0;if((((h|0)>-1?h:0-h|0)>>>0<(c[t>>2]|0)>>>0?(y=d[e>>0]|0,h=y-l|0,x=c[o>>2]|0,((h|0)>-1?h:0-h|0)>>>0>>0):0)?(z=f&255,f=z-m|0,((f|0)>-1?f:0-f|0)>>>0>>0):0){f=d[b+q>>0]|0;h=f-l|0;if(((h|0)>-1?h:0-h|0)>>>0>>0){a[e>>0]=(Oa(s,u,((l+1+m|0)>>>1)-(y<<1)+f>>1)|0)+y;e=c[o>>2]|0;f=p}else{e=x;f=u}h=d[b+r>>0]|0;B=h-m|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[j>>0]=(Oa(s,u,((l+1+m|0)>>>1)-(z<<1)+h>>1)|0)+z;f=f+1|0}f=Oa(0-f|0,f,4-z+(m-l<<2)+y>>3)|0;e=a[3472+((m|512)-f)>>0]|0;a[k>>0]=a[3472+((l|512)+f)>>0]|0;a[b>>0]=e}n=n+-1|0;if(!n)break;else b=b+1|0}i=A;return} +function ya(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+15&-16;return b|0}function za(){return i|0}function Aa(a){a=a|0;i=a}function Ba(a,b){a=a|0;b=b|0;if(!m){m=a;n=b}}function Ca(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Da(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Ea(a){a=a|0;B=a}function Fa(){return B|0}function Ga(a,b,e,f){a=a|0;b=b|0;e=e|0;f=f|0;var g=0,h=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;k=i;g=d[8+b>>0]|0;j=d[64+b>>0]|0;b=c[120+(j*12|0)>>2]<>2]<>2]<>2]=Z(c[a>>2]|0,b)|0;a:do if(!(f&65436)){if(f&98){n=a+4|0;l=Z(c[n>>2]|0,h)|0;j=a+20|0;m=Z(c[j>>2]|0,b)|0;e=a+24|0;g=Z(c[e>>2]|0,h)|0;h=c[a>>2]|0;b=(l>>1)-g|0;g=l+(g>>1)|0;l=m+h+32|0;f=l+g>>6;c[a>>2]=f;m=h-m+32|0;h=m+b>>6;c[n>>2]=h;b=m-b>>6;c[a+8>>2]=b;g=l-g>>6;c[a+12>>2]=g;c[a+48>>2]=f;c[a+32>>2]=f;c[a+16>>2]=f;c[a+52>>2]=h;c[a+36>>2]=h;c[j>>2]=h;c[a+56>>2]=b;c[a+40>>2]=b;c[e>>2]=b;c[a+60>>2]=g;c[a+44>>2]=g;c[a+28>>2]=g;if((f+512|0)>>>0>1023|(h+512|0)>>>0>1023|(b+512|0)>>>0>1023|(g+512|0)>>>0>1023)g=1;else break;i=k;return g|0}g=(c[a>>2]|0)+32>>6;if((g+512|0)>>>0>1023){m=1;i=k;return m|0}else{c[a+60>>2]=g;c[a+56>>2]=g;c[a+52>>2]=g;c[a+48>>2]=g;c[a+44>>2]=g;c[a+40>>2]=g;c[a+36>>2]=g;c[a+32>>2]=g;c[a+28>>2]=g;c[a+24>>2]=g;c[a+20>>2]=g;c[a+16>>2]=g;c[a+12>>2]=g;c[a+8>>2]=g;c[a+4>>2]=g;c[a>>2]=g;break}}else{z=a+4|0;s=a+56|0;w=a+60|0;t=c[w>>2]|0;u=Z(c[z>>2]|0,h)|0;c[s>>2]=Z(c[s>>2]|0,h)|0;c[w>>2]=Z(t,g)|0;w=a+8|0;t=c[w>>2]|0;s=a+16|0;y=Z(c[a+20>>2]|0,b)|0;o=Z(c[s>>2]|0,g)|0;q=a+12|0;p=c[q>>2]|0;f=Z(c[a+32>>2]|0,h)|0;e=Z(c[a+24>>2]|0,h)|0;r=c[a+28>>2]|0;j=Z(c[a+48>>2]|0,g)|0;n=Z(c[a+36>>2]|0,h)|0;l=c[a+44>>2]|0;m=Z(c[a+40>>2]|0,g)|0;g=Z(c[a+52>>2]|0,h)|0;x=c[a>>2]|0;v=y+x|0;y=x-y|0;x=(u>>1)-e|0;u=(e>>1)+u|0;e=u+v|0;c[a>>2]=e;c[z>>2]=x+y;c[w>>2]=y-x;c[q>>2]=v-u;q=Z(h,r+t|0)|0;r=Z(t-r|0,h)|0;h=(o>>1)-j|0;o=(j>>1)+o|0;j=o+q|0;c[s>>2]=j;c[a+20>>2]=h+r;c[a+24>>2]=r-h;c[a+28>>2]=q-o;o=Z(b,l+p|0)|0;b=Z(p-l|0,b)|0;l=(f>>1)-g|0;f=(g>>1)+f|0;h=f+o|0;c[a+32>>2]=h;c[a+36>>2]=l+b;c[a+40>>2]=b-l;c[a+44>>2]=o-f;f=a+56|0;o=c[f>>2]|0;l=o+n|0;o=n-o|0;b=a+60|0;g=c[b>>2]|0;n=(m>>1)-g|0;m=(g>>1)+m|0;g=m+l|0;c[a+48>>2]=g;c[a+52>>2]=n+o;c[f>>2]=o-n;c[b>>2]=l-m;b=j;j=3;while(1){v=(b>>1)-g|0;g=(g>>1)+b|0;w=h+e+32|0;x=w+g>>6;c[a>>2]=x;b=e-h+32|0;y=b+v>>6;c[a+16>>2]=y;b=b-v>>6;c[a+32>>2]=b;g=w-g>>6;c[a+48>>2]=g;if((x+512|0)>>>0>1023|(y+512|0)>>>0>1023){g=1;b=14;break}if((b+512|0)>>>0>1023|(g+512|0)>>>0>1023){g=1;b=14;break}f=a+4|0;if(!j)break a;e=c[f>>2]|0;h=c[a+36>>2]|0;b=c[a+20>>2]|0;g=c[a+52>>2]|0;a=f;j=j+-1|0}if((b|0)==14){i=k;return g|0}}while(0);y=0;i=k;return y|0}function Ha(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=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;B=i;e=a[64+d>>0]|0;s=a[8+d>>0]|0;D=b+8|0;u=c[D>>2]|0;j=c[b+20>>2]|0;q=b+16|0;y=c[q>>2]|0;r=b+32|0;z=c[r>>2]|0;E=b+12|0;v=c[E>>2]|0;f=c[b+24>>2]|0;m=c[b+28>>2]|0;o=b+48|0;g=c[o>>2]|0;C=c[b+36>>2]|0;A=c[b+40>>2]|0;F=c[b+44>>2]|0;h=c[b+52>>2]|0;p=c[b>>2]|0;l=j+p|0;j=p-j|0;p=b+4|0;x=c[p>>2]|0;t=x-f|0;x=f+x|0;f=x+l|0;c[b>>2]=f;k=t+j|0;c[p>>2]=k;t=j-t|0;c[D>>2]=t;x=l-x|0;c[E>>2]=x;E=m+u|0;m=u-m|0;u=y-g|0;y=g+y|0;g=y+E|0;c[q>>2]=g;l=u+m|0;c[b+20>>2]=l;u=m-u|0;c[b+24>>2]=u;y=E-y|0;c[b+28>>2]=y;E=F+v|0;F=v-F|0;v=z-h|0;z=h+z|0;h=z+E|0;c[b+32>>2]=h;m=v+F|0;c[b+36>>2]=m;v=F-v|0;c[b+40>>2]=v;z=E-z|0;c[b+44>>2]=z;E=b+56|0;F=c[E>>2]|0;D=F+C|0;F=C-F|0;C=b+60|0;j=c[C>>2]|0;w=A-j|0;A=j+A|0;j=A+D|0;c[b+48>>2]=j;n=w+F|0;c[b+52>>2]=n;w=F-w|0;c[E>>2]=w;A=D-A|0;c[C>>2]=A;s=s&255;e=c[120+((e&255)*12|0)>>2]|0;if(d>>>0>11){d=e<>2]=Z(e+s|0,d)|0;c[q>>2]=Z(f+h|0,d)|0;c[r>>2]=Z(h-f|0,d)|0;c[o>>2]=Z(s-e|0,d)|0;r=m+k|0;e=k-m|0;q=l-n|0;s=n+l|0;c[p>>2]=Z(s+r|0,d)|0;c[b+20>>2]=Z(q+e|0,d)|0;c[b+36>>2]=Z(e-q|0,d)|0;c[b+52>>2]=Z(r-s|0,d)|0;s=v+t|0;t=t-v|0;v=u-w|0;w=w+u|0;c[b+8>>2]=Z(w+s|0,d)|0;c[b+24>>2]=Z(v+t|0,d)|0;c[b+40>>2]=Z(t-v|0,d)|0;c[b+56>>2]=Z(s-w|0,d)|0;w=z+x|0;v=x-z|0;x=y-A|0;y=A+y|0;c[b+12>>2]=Z(y+w|0,d)|0;c[b+28>>2]=Z(x+v|0,d)|0;c[b+44>>2]=Z(v-x|0,d)|0;c[b+60>>2]=Z(w-y|0,d)|0;i=B;return}else{C=(d+-6|0)>>>0<6?1:2;d=2-s|0;s=h+f|0;D=f-h|0;h=g-j|0;f=j+g|0;c[b>>2]=(Z(f+s|0,e)|0)+C>>d;c[q>>2]=(Z(h+D|0,e)|0)+C>>d;c[r>>2]=(Z(D-h|0,e)|0)+C>>d;c[o>>2]=(Z(s-f|0,e)|0)+C>>d;r=m+k|0;f=k-m|0;q=l-n|0;s=n+l|0;c[p>>2]=(Z(s+r|0,e)|0)+C>>d;c[b+20>>2]=(Z(q+f|0,e)|0)+C>>d;c[b+36>>2]=(Z(f-q|0,e)|0)+C>>d;c[b+52>>2]=(Z(r-s|0,e)|0)+C>>d;s=v+t|0;t=t-v|0;v=u-w|0;w=w+u|0;c[b+8>>2]=(Z(w+s|0,e)|0)+C>>d;c[b+24>>2]=(Z(v+t|0,e)|0)+C>>d;c[b+40>>2]=(Z(t-v|0,e)|0)+C>>d;c[b+56>>2]=(Z(s-w|0,e)|0)+C>>d;w=z+x|0;v=x-z|0;x=y-A|0;y=A+y|0;c[b+12>>2]=(Z(y+w|0,e)|0)+C>>d;c[b+28>>2]=(Z(x+v|0,e)|0)+C>>d;c[b+44>>2]=(Z(v-x|0,e)|0)+C>>d;c[b+60>>2]=(Z(w-y|0,e)|0)+C>>d;i=B;return}}function Ia(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;e=c[120+((d[64+b>>0]|0)*12|0)>>2]|0;if(b>>>0>5){e=e<<(d[8+b>>0]|0)+-1;b=0}else b=1;k=c[a>>2]|0;g=a+8|0;h=c[g>>2]|0;m=h+k|0;h=k-h|0;k=a+4|0;j=c[k>>2]|0;l=a+12|0;f=c[l>>2]|0;i=j-f|0;j=f+j|0;c[a>>2]=(Z(j+m|0,e)|0)>>b;c[k>>2]=(Z(m-j|0,e)|0)>>b;c[g>>2]=(Z(i+h|0,e)|0)>>b;c[l>>2]=(Z(h-i|0,e)|0)>>b;l=a+16|0;i=c[l>>2]|0;h=a+24|0;g=c[h>>2]|0;k=g+i|0;g=i-g|0;i=a+20|0;j=c[i>>2]|0;a=a+28|0;m=c[a>>2]|0;f=j-m|0;j=m+j|0;c[l>>2]=(Z(j+k|0,e)|0)>>b;c[i>>2]=(Z(k-j|0,e)|0)>>b;c[h>>2]=(Z(f+g|0,e)|0)>>b;c[a>>2]=(Z(g-f|0,e)|0)>>b;return}function Ja(a,b){a=a|0;b=b|0;var c=0,d=0;d=i;b=1<>>1}while((c|0)!=0&(c&a|0)==0);i=d;return b|0}function Ka(a){a=a|0;var b=0,d=0;d=i;b=8-(c[a+8>>2]|0)|0;a=jb(a,b)|0;if((a|0)==-1){a=1;i=d;return a|0}a=(a|0)!=(c[400+(b+-1<<2)>>2]|0)&1;i=d;return a|0}function La(a){a=a|0;var b=0,d=0,e=0,f=0;d=i;f=c[a+12>>2]<<3;e=c[a+16>>2]|0;b=f-e|0;if((f|0)==(e|0)){a=0;i=d;return a|0}if(b>>>0>8){a=1;i=d;return a|0}else{a=((kb(a)|0)>>>(32-b|0)|0)!=(1<>2]|0;do{d=d+1|0;if(d>>>0>=b>>>0)break}while((c[a+(d<<2)>>2]|0)!=(e|0));i=f;return ((d|0)==(b|0)?0:d)|0}function Na(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=c[a+4>>2]|0;f=(b>>>0)%(e>>>0)|0;d=b-f|0;b=Z(c[a+8>>2]|0,e)|0;e=c[a>>2]|0;c[a+12>>2]=e+((d<<8)+(f<<4));d=(f<<3)+(b<<8)+(d<<6)|0;c[a+16>>2]=e+d;c[a+20>>2]=e+(d+(b<<6));return}function Oa(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)>=(a|0))a=(c|0)>(b|0)?b:c;return a|0}function Pa(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=i;a:do if(((e>>>0>3?(a[b>>0]|0)==0:0)?(a[b+1>>0]|0)==0:0)?(h=a[b+2>>0]|0,(h&255)<2):0){b:do if((e|0)!=3){p=-3;q=3;k=b+3|0;j=2;while(1){if(h<<24>>24)if(h<<24>>24==1&j>>>0>1){o=q;h=0;m=0;l=0;break}else j=0;else j=j+1|0;l=q+1|0;if((l|0)==(e|0))break b;h=a[k>>0]|0;p=~q;q=l;k=k+1|0}while(1){r=a[k>>0]|0;n=o+1|0;j=r<<24>>24!=0;l=(j&1^1)+l|0;h=r<<24>>24==3&(l|0)==2?1:h;if(r<<24>>24==1&l>>>0>1){r=14;break}if(j){m=l>>>0>2?1:m;l=0}if((n|0)==(e|0)){r=18;break}else{o=n;k=k+1|0}}if((r|0)==14){n=p+o-l|0;c[f+12>>2]=n;j=q;l=l-(l>>>0<3?l:3)|0;break a}else if((r|0)==18){n=p+e-l|0;c[f+12>>2]=n;j=q;break a}}while(0);c[g>>2]=e;q=1;i=s;return q|0}else r=19;while(0);if((r|0)==19){c[f+12>>2]=e;n=e;h=1;j=0;m=0;l=0}k=b+j|0;c[f>>2]=k;c[f+4>>2]=k;c[f+8>>2]=0;c[f+16>>2]=0;o=f+12|0;c[g>>2]=l+j+n;if(m){q=1;i=s;return q|0}if(!h){q=0;i=s;return q|0}l=c[o>>2]|0;h=k;m=k;j=0;c:while(1){while(1){q=l;l=l+-1|0;if(!q){r=31;break c}k=a[h>>0]|0;if((j|0)!=2)break;if(k<<24>>24!=3){r=29;break}if(!l){h=1;r=32;break c}h=h+1|0;if((d[h>>0]|0)>3){h=1;r=32;break c}else j=0}if((r|0)==29){r=0;if((k&255)<3){h=1;r=32;break}else j=2}a[m>>0]=k;h=h+1|0;m=m+1|0;j=k<<24>>24==0?j+1|0:0}if((r|0)==31){c[o>>2]=m-h+(c[o>>2]|0);q=0;i=s;return q|0}else if((r|0)==32){i=s;return h|0}return 0}function Qa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;i=i+16|0;n=o;id(b,0,92);f=jb(a,8)|0;a:do if((((f|0)!=-1?(c[b>>2]=f,jb(a,1)|0,jb(a,1)|0,(jb(a,1)|0)!=-1):0)?(jb(a,5)|0)!=-1:0)?(e=jb(a,8)|0,(e|0)!=-1):0){m=b+4|0;c[m>>2]=e;f=b+8|0;d=nb(a,f)|0;if(!d)if((c[f>>2]|0)>>>0<=31){d=nb(a,n)|0;if(!d){f=c[n>>2]|0;if(f>>>0<=12){c[b+12>>2]=1<>2]|0;if(f>>>0<=2){c[b+16>>2]=f;b:do if(!f){d=nb(a,n)|0;if(d)break a;f=c[n>>2]|0;if(f>>>0>12){d=1;break a}c[b+20>>2]=1<>2]=(f|0)==1&1;d=ob(a,b+28|0)|0;if(d)break a;d=ob(a,b+32|0)|0;if(d)break a;h=b+36|0;d=nb(a,h)|0;if(d)break a;f=c[h>>2]|0;if(f>>>0>255){d=1;break a}if(!f){c[b+40>>2]=0;break}f=fd(f<<2)|0;g=b+40|0;c[g>>2]=f;if(!f){d=65535;break a}if(c[h>>2]|0){e=0;while(1){d=ob(a,f+(e<<2)|0)|0;e=e+1|0;if(d)break a;if(e>>>0>=(c[h>>2]|0)>>>0)break b;f=c[g>>2]|0}}}while(0);l=b+44|0;d=nb(a,l)|0;if(!d)if((c[l>>2]|0)>>>0<=16?(k=jb(a,1)|0,(k|0)!=-1):0){c[b+48>>2]=(k|0)==1&1;d=nb(a,n)|0;if(!d){e=b+52|0;c[e>>2]=(c[n>>2]|0)+1;d=nb(a,n)|0;if(!d){k=b+56|0;c[k>>2]=(c[n>>2]|0)+1;h=jb(a,1)|0;if((!((h|0)==0|(h|0)==-1)?(jb(a,1)|0)!=-1:0)?(j=jb(a,1)|0,(j|0)!=-1):0){j=(j|0)==1;c[b+60>>2]=j&1;if(j){j=b+64|0;d=nb(a,j)|0;if(d)break;f=b+68|0;d=nb(a,f)|0;if(d)break;h=b+72|0;d=nb(a,h)|0;if(d)break;g=b+76|0;d=nb(a,g)|0;if(d)break;e=c[e>>2]|0;if((c[j>>2]|0)>((e<<3)+~c[f>>2]|0)){d=1;break}f=c[k>>2]|0;if((c[h>>2]|0)>((f<<3)+~c[g>>2]|0)){d=1;break}}else{e=c[e>>2]|0;f=c[k>>2]|0}d=Z(f,e)|0;do switch(c[m>>2]|0){case 11:{f=396;e=345600;g=58;break}case 12:{f=396;e=912384;g=58;break}case 13:{f=396;e=912384;g=58;break}case 20:{f=396;e=912384;g=58;break}case 21:{f=792;e=1824768;g=58;break}case 22:{f=1620;e=3110400;g=58;break}case 30:{f=1620;e=3110400;g=58;break}case 31:{f=3600;e=6912e3;g=58;break}case 32:{f=5120;e=7864320;g=58;break}case 40:{f=8192;e=12582912;g=58;break}case 41:{f=8192;e=12582912;g=58;break}case 42:{f=8704;e=13369344;g=58;break}case 50:{f=22080;e=42393600;g=58;break}case 51:{f=36864;e=70778880;g=58;break}case 10:{f=99;e=152064;g=58;break}default:g=60}while(0);do if((g|0)==58){if(f>>>0>>0){g=60;break}e=(e>>>0)/((d*384|0)>>>0)|0;e=e>>>0<16?e:16;c[n>>2]=e;f=c[l>>2]|0;if(f>>>0>e>>>0){e=f;g=61}}while(0);if((g|0)==60){c[n>>2]=2147483647;e=c[l>>2]|0;g=61}if((g|0)==61)c[n>>2]=e;g=b+88|0;c[g>>2]=e;e=jb(a,1)|0;if((e|0)==-1){d=1;break}n=(e|0)==1;c[b+80>>2]=n&1;do if(n){e=fd(952)|0;f=b+84|0;c[f>>2]=e;if(!e){d=65535;break a}d=Ec(a,e)|0;if(d)break a;d=c[f>>2]|0;if(!(c[d+920>>2]|0))break;e=c[d+948>>2]|0;if((c[d+944>>2]|0)>>>0>e>>>0){d=1;break a}if(e>>>0<(c[l>>2]|0)>>>0){d=1;break a}if(e>>>0>(c[g>>2]|0)>>>0){d=1;break a}c[g>>2]=(e|0)==0?1:e}while(0);Ka(a)|0;d=0}else d=1}}}else d=1}else d=1}}else d=1}}else d=1}else d=1;while(0);i=o;return d|0}function Ra(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;j=i;if((c[a>>2]|0)!=(c[b>>2]|0)){d=1;i=j;return d|0}if((c[a+4>>2]|0)!=(c[b+4>>2]|0)){d=1;i=j;return d|0}if((c[a+12>>2]|0)!=(c[b+12>>2]|0)){d=1;i=j;return d|0}d=c[a+16>>2]|0;if((d|0)!=(c[b+16>>2]|0)){d=1;i=j;return d|0}if((c[a+44>>2]|0)!=(c[b+44>>2]|0)){d=1;i=j;return d|0}if((c[a+48>>2]|0)!=(c[b+48>>2]|0)){d=1;i=j;return d|0}if((c[a+52>>2]|0)!=(c[b+52>>2]|0)){d=1;i=j;return d|0}if((c[a+56>>2]|0)!=(c[b+56>>2]|0)){d=1;i=j;return d|0}h=c[a+60>>2]|0;if((h|0)!=(c[b+60>>2]|0)){d=1;i=j;return d|0}if((c[a+80>>2]|0)!=(c[b+80>>2]|0)){d=1;i=j;return d|0}a:do if(!d){if((c[a+20>>2]|0)!=(c[b+20>>2]|0)){d=1;i=j;return d|0}}else if((d|0)==1){if((c[a+24>>2]|0)!=(c[b+24>>2]|0)){d=1;i=j;return d|0}if((c[a+28>>2]|0)!=(c[b+28>>2]|0)){d=1;i=j;return d|0}if((c[a+32>>2]|0)!=(c[b+32>>2]|0)){d=1;i=j;return d|0}d=c[a+36>>2]|0;if((d|0)!=(c[b+36>>2]|0)){d=1;i=j;return d|0}if(d){e=c[a+40>>2]|0;f=c[b+40>>2]|0;g=0;while(1){if((c[e+(g<<2)>>2]|0)!=(c[f+(g<<2)>>2]|0)){d=1;break}g=g+1|0;if(g>>>0>=d>>>0)break a}i=j;return d|0}}while(0);if(h){if((c[a+64>>2]|0)!=(c[b+64>>2]|0)){d=1;i=j;return d|0}if((c[a+68>>2]|0)!=(c[b+68>>2]|0)){d=1;i=j;return d|0}if((c[a+72>>2]|0)!=(c[b+72>>2]|0)){d=1;i=j;return d|0}if((c[a+76>>2]|0)!=(c[b+76>>2]|0)){d=1;i=j;return d|0}}d=0;i=j;return d|0}function Sa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;i=i+16|0;j=l+4|0;k=l;id(b,0,72);d=nb(a,b)|0;if(d){i=l;return d|0}if((c[b>>2]|0)>>>0>255){d=1;i=l;return d|0}e=b+4|0;d=nb(a,e)|0;if(d){i=l;return d|0}if((c[e>>2]|0)>>>0>31){d=1;i=l;return d|0}if(jb(a,1)|0){d=1;i=l;return d|0}d=jb(a,1)|0;if((d|0)==-1){d=1;i=l;return d|0}c[b+8>>2]=(d|0)==1&1;d=nb(a,j)|0;if(d){i=l;return d|0}d=(c[j>>2]|0)+1|0;h=b+12|0;c[h>>2]=d;if(d>>>0>8){d=1;i=l;return d|0}a:do if(d>>>0>1){d=b+16|0;e=nb(a,d)|0;if(e){d=e;i=l;return d|0}d=c[d>>2]|0;if(d>>>0>6){d=1;i=l;return d|0}switch(d|0){case 5:case 4:case 3:{d=jb(a,1)|0;if((d|0)==-1){d=1;i=l;return d|0}c[b+32>>2]=(d|0)==1&1;d=nb(a,j)|0;if(!d){c[b+36>>2]=(c[j>>2]|0)+1;break a}else{i=l;return d|0}}case 0:{d=fd(c[h>>2]<<2)|0;f=b+20|0;c[f>>2]=d;if(!d){d=65535;i=l;return d|0}if(!(c[h>>2]|0))break a;else e=0;while(1){d=nb(a,j)|0;if(d)break;c[(c[f>>2]|0)+(e<<2)>>2]=(c[j>>2]|0)+1;e=e+1|0;if(e>>>0>=(c[h>>2]|0)>>>0)break a}i=l;return d|0}case 2:{e=b+24|0;c[e>>2]=fd((c[h>>2]<<2)+-4|0)|0;d=fd((c[h>>2]<<2)+-4|0)|0;g=b+28|0;c[g>>2]=d;if((c[e>>2]|0)==0|(d|0)==0){d=65535;i=l;return d|0}if((c[h>>2]|0)==1)break a;else f=0;while(1){d=nb(a,j)|0;if(d){e=46;break}c[(c[e>>2]|0)+(f<<2)>>2]=c[j>>2];d=nb(a,j)|0;if(d){e=46;break}c[(c[g>>2]|0)+(f<<2)>>2]=c[j>>2];f=f+1|0;if(f>>>0>=((c[h>>2]|0)+-1|0)>>>0)break a}if((e|0)==46){i=l;return d|0}break}case 6:{d=nb(a,j)|0;if(d){i=l;return d|0}e=(c[j>>2]|0)+1|0;d=b+40|0;c[d>>2]=e;e=fd(e<<2)|0;g=b+44|0;c[g>>2]=e;if(!e){d=65535;i=l;return d|0}f=c[432+((c[h>>2]|0)+-1<<2)>>2]|0;if(!(c[d>>2]|0))break a;else e=0;while(1){m=jb(a,f)|0;c[(c[g>>2]|0)+(e<<2)>>2]=m;e=e+1|0;if(m>>>0>=(c[h>>2]|0)>>>0){d=1;break}if(e>>>0>=(c[d>>2]|0)>>>0)break a}i=l;return d|0}default:break a}}while(0);d=nb(a,j)|0;if(d){a=d;i=l;return a|0}d=c[j>>2]|0;if(d>>>0>31){a=1;i=l;return a|0}c[b+48>>2]=d+1;d=nb(a,j)|0;if(d){a=d;i=l;return a|0}if((c[j>>2]|0)>>>0>31){a=1;i=l;return a|0}if(jb(a,1)|0){a=1;i=l;return a|0}if((jb(a,2)|0)>>>0>2){a=1;i=l;return a|0}d=ob(a,k)|0;if(d){a=d;i=l;return a|0}d=(c[k>>2]|0)+26|0;if(d>>>0>51){a=1;i=l;return a|0}c[b+52>>2]=d;d=ob(a,k)|0;if(d){a=d;i=l;return a|0}if(((c[k>>2]|0)+26|0)>>>0>51){a=1;i=l;return a|0}d=ob(a,k)|0;if(d){a=d;i=l;return a|0}d=c[k>>2]|0;if((d+12|0)>>>0>24){a=1;i=l;return a|0}c[b+56>>2]=d;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+60>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+64>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+68>>2]=(d|0)==1&1;Ka(a)|0;a=0;i=l;return a|0}function Ta(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,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;w=i;i=i+32|0;s=w+20|0;q=w+16|0;o=w+12|0;l=w+8|0;v=w+4|0;t=w;id(b,0,988);u=Z(c[d+56>>2]|0,c[d+52>>2]|0)|0;k=nb(a,v)|0;if(k){f=k;i=w;return f|0}n=c[v>>2]|0;c[b>>2]=n;if(n>>>0>=u>>>0){f=1;i=w;return f|0}k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;m=b+4|0;c[m>>2]=k;if((k|0)==5|(k|0)==0)j=5;else if(!((k|0)==7|(k|0)==2)){f=1;i=w;return f|0}if((j|0)==5){if((c[f>>2]|0)==5){f=1;i=w;return f|0}if(!(c[d+44>>2]|0)){f=1;i=w;return f|0}}k=nb(a,v)|0;if(k){f=k;i=w;return f|0}n=c[v>>2]|0;c[b+8>>2]=n;if((n|0)!=(c[e>>2]|0)){f=1;i=w;return f|0}n=d+12|0;k=c[n>>2]|0;j=0;while(1)if(!(k>>>j))break;else j=j+1|0;k=jb(a,j+-1|0)|0;if((k|0)==-1){f=1;i=w;return f|0}j=(c[f>>2]|0)==5;if(j&(k|0)!=0){f=1;i=w;return f|0}c[b+12>>2]=k;if(j){k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;c[b+16>>2]=k;if(k>>>0>65535){f=1;i=w;return f|0}}g=d+16|0;k=c[g>>2]|0;if(!k){h=d+20|0;k=c[h>>2]|0;j=0;while(1)if(!(k>>>j))break;else j=j+1|0;k=jb(a,j+-1|0)|0;if((k|0)==-1){f=1;i=w;return f|0}j=b+20|0;c[j>>2]=k;do if(c[e+8>>2]|0){k=ob(a,t)|0;if(!k){c[b+24>>2]=c[t>>2];break}else{f=k;i=w;return f|0}}while(0);if((c[f>>2]|0)==5){k=c[j>>2]|0;if(k>>>0>(c[h>>2]|0)>>>1>>>0){f=1;i=w;return f|0}j=c[b+24>>2]|0;if((k|0)!=(((j|0)>0?0:0-j|0)|0)){f=1;i=w;return f|0}}k=c[g>>2]|0}if((k|0)==1?(c[d+24>>2]|0)==0:0){k=ob(a,t)|0;if(k){f=k;i=w;return f|0}k=b+28|0;c[k>>2]=c[t>>2];do if(c[e+8>>2]|0){j=ob(a,t)|0;if(!j){c[b+32>>2]=c[t>>2];break}else{f=j;i=w;return f|0}}while(0);if((c[f>>2]|0)==5?(j=c[k>>2]|0,k=(c[d+32>>2]|0)+j+(c[b+32>>2]|0)|0,(((j|0)<(k|0)?j:k)|0)!=0):0){f=1;i=w;return f|0}}if(c[e+68>>2]|0){k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;c[b+36>>2]=k;if(k>>>0>127){f=1;i=w;return f|0}}k=c[m>>2]|0;if((k|0)==5|(k|0)==0){k=jb(a,1)|0;if((k|0)==-1){f=1;i=w;return f|0}c[b+40>>2]=k;do if(!k){k=c[e+48>>2]|0;if(k>>>0>16){f=1;i=w;return f|0}else{c[b+44>>2]=k;break}}else{k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;if(k>>>0>15){f=1;i=w;return f|0}else{c[b+44>>2]=k+1;break}}while(0);k=c[m>>2]|0}do if((k|0)==5|(k|0)==0){g=c[b+44>>2]|0;j=c[n>>2]|0;k=jb(a,1)|0;if((k|0)==-1){f=1;i=w;return f|0}c[b+68>>2]=k;if(k){h=0;a:while(1){if(h>>>0>g>>>0){r=1;j=110;break}k=nb(a,l)|0;if(k){r=k;j=110;break}k=c[l>>2]|0;if(k>>>0>3){r=1;j=110;break}c[b+(h*12|0)+72>>2]=k;do if(k>>>0<2){k=nb(a,o)|0;if(k){r=k;j=110;break a}k=c[o>>2]|0;if(k>>>0>=j>>>0){r=1;j=110;break a}c[b+(h*12|0)+76>>2]=k+1}else{if((k|0)!=2)break;k=nb(a,o)|0;if(k){r=k;j=110;break a}c[b+(h*12|0)+80>>2]=c[o>>2]}while(0);if((c[l>>2]|0)==3){j=61;break}else h=h+1|0}if((j|0)==61){if(!h)r=1;else break;i=w;return r|0}else if((j|0)==110){i=w;return r|0}}}while(0);do if(c[f+4>>2]|0){n=c[d+44>>2]|0;f=(c[f>>2]|0)==5;k=jb(a,1)|0;j=(k|0)==-1;if(f){if(j){f=1;i=w;return f|0}c[b+276>>2]=k;g=jb(a,1)|0;if((g|0)==-1){f=1;i=w;return f|0}c[b+280>>2]=g;if((n|0)!=0|(g|0)==0)break;else r=1;i=w;return r|0}if(j){f=1;i=w;return f|0}c[b+284>>2]=k;if(k){j=(n<<1)+2|0;h=0;d=0;g=0;l=0;m=0;while(1){if(h>>>0>j>>>0){r=1;j=110;break}k=nb(a,q)|0;if(k){r=k;j=110;break}k=c[q>>2]|0;if(k>>>0>6){r=1;j=110;break}c[b+(h*20|0)+288>>2]=k;if((k&-3|0)==1){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+292>>2]=(c[s>>2]|0)+1;k=c[q>>2]|0}if((k|0)==2){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+296>>2]=c[s>>2];k=c[q>>2]|0}if((k|0)==3|(k|0)==6){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+300>>2]=c[s>>2];k=c[q>>2]|0}if((k|0)==4){k=nb(a,s)|0;if(k){r=k;j=110;break}k=c[s>>2]|0;if(k>>>0>n>>>0){r=1;j=110;break}if(!k)c[b+(h*20|0)+304>>2]=65535;else c[b+(h*20|0)+304>>2]=k+-1;k=c[q>>2]|0;p=g+1|0}else p=g;l=((k|0)==5&1)+l|0;d=((k|0)!=0&k>>>0<4&1)+d|0;m=((k|0)==6&1)+m|0;if(!k){j=90;break}else{h=h+1|0;g=p}}if((j|0)==90){if(p>>>0>1|l>>>0>1|m>>>0>1){f=1;i=w;return f|0}if((d|0)!=0&(l|0)!=0)r=1;else break;i=w;return r|0}else if((j|0)==110){i=w;return r|0}}}while(0);g=ob(a,t)|0;if(g){f=g;i=w;return f|0}f=c[t>>2]|0;c[b+48>>2]=f;f=f+(c[e+52>>2]|0)|0;c[t>>2]=f;if(f>>>0>51){f=1;i=w;return f|0}do if(c[e+60>>2]|0){g=nb(a,v)|0;if(g){f=g;i=w;return f|0}g=c[v>>2]|0;c[b+52>>2]=g;if(g>>>0>2){f=1;i=w;return f|0}if((g|0)==1)break;g=ob(a,t)|0;if(g){f=g;i=w;return f|0}g=c[t>>2]|0;if((g+6|0)>>>0>12){f=1;i=w;return f|0}c[b+56>>2]=g<<1;g=ob(a,t)|0;if(g){f=g;i=w;return f|0}g=c[t>>2]|0;if((g+6|0)>>>0>12){f=1;i=w;return f|0}else{c[b+60>>2]=g<<1;break}}while(0);do if((c[e+12>>2]|0)>>>0>1?((c[e+16>>2]|0)+-3|0)>>>0<3:0){k=e+36|0;j=c[k>>2]|0;j=(((u>>>0)%(j>>>0)|0|0)==0?1:2)+((u>>>0)/(j>>>0)|0)|0;h=0;while(1){g=h+1|0;if(!(-1<>2]=g;if((g|0)==-1){f=1;i=w;return f|0}c[b+64>>2]=g;f=c[k>>2]|0;if(g>>>0>(((u+-1+f|0)>>>0)/(f>>>0)|0)>>>0)r=1;else break;i=w;return r|0}while(0);f=0;i=w;return f|0}function Ua(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;i=i+32|0;e=f+20|0;d=f;c[d+0>>2]=c[a+0>>2];c[d+4>>2]=c[a+4>>2];c[d+8>>2]=c[a+8>>2];c[d+12>>2]=c[a+12>>2];c[d+16>>2]=c[a+16>>2];a=nb(d,e)|0;if(!a){a=nb(d,e)|0;if(!a){a=nb(d,e)|0;if(!a){a=c[e>>2]|0;if(a>>>0>255)a=1;else{c[b>>2]=a;a=0}}}}i=f;return a|0}function Va(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+32|0;e=g+20|0;f=g;c[f+0>>2]=c[a+0>>2];c[f+4>>2]=c[a+4>>2];c[f+8>>2]=c[a+8>>2];c[f+12>>2]=c[a+12>>2];c[f+16>>2]=c[a+16>>2];a=nb(f,e)|0;if(a){i=g;return a|0}a=nb(f,e)|0;if(a){i=g;return a|0}a=nb(f,e)|0;if(!a)a=0;else{i=g;return a|0}while(1)if(!(b>>>a))break;else a=a+1|0;a=jb(f,a+-1|0)|0;if((a|0)==-1){a=1;i=g;return a|0}c[d>>2]=a;a=0;i=g;return a|0}function Wa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;h=i;i=i+32|0;f=h+20|0;g=h;if((d|0)!=5){d=1;i=h;return d|0};c[g+0>>2]=c[a+0>>2];c[g+4>>2]=c[a+4>>2];c[g+8>>2]=c[a+8>>2];c[g+12>>2]=c[a+12>>2];c[g+16>>2]=c[a+16>>2];d=nb(g,f)|0;if(d){i=h;return d|0}d=nb(g,f)|0;if(d){i=h;return d|0}d=nb(g,f)|0;if(!d)d=0;else{i=h;return d|0}while(1)if(!(b>>>d))break;else d=d+1|0;if((jb(g,d+-1|0)|0)==-1){d=1;i=h;return d|0}d=nb(g,e)|0;i=h;return d|0}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,j=0,k=0;k=i;i=i+32|0;h=k+20|0;j=k;c[j+0>>2]=c[a+0>>2];c[j+4>>2]=c[a+4>>2];c[j+8>>2]=c[a+8>>2];c[j+12>>2]=c[a+12>>2];c[j+16>>2]=c[a+16>>2];a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=c[b+12>>2]|0;f=0;while(1)if(!(a>>>f))break;else f=f+1|0;if((jb(j,f+-1|0)|0)==-1){f=1;i=k;return f|0}if((d|0)==5?(g=nb(j,h)|0,(g|0)!=0):0){f=g;i=k;return f|0}f=c[b+20>>2]|0;a=0;while(1)if(!(f>>>a))break;else a=a+1|0;f=jb(j,a+-1|0)|0;if((f|0)==-1){f=1;i=k;return f|0}c[e>>2]=f;f=0;i=k;return f|0}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,j=0,k=0;k=i;i=i+32|0;h=k+20|0;j=k;c[j+0>>2]=c[a+0>>2];c[j+4>>2]=c[a+4>>2];c[j+8>>2]=c[a+8>>2];c[j+12>>2]=c[a+12>>2];c[j+16>>2]=c[a+16>>2];a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=c[b+12>>2]|0;f=0;while(1)if(!(a>>>f))break;else f=f+1|0;if((jb(j,f+-1|0)|0)==-1){f=1;i=k;return f|0}if((d|0)==5?(g=nb(j,h)|0,(g|0)!=0):0){f=g;i=k;return f|0}f=c[b+20>>2]|0;a=0;while(1)if(!(f>>>a))break;else a=a+1|0;if((jb(j,a+-1|0)|0)==-1){f=1;i=k;return f|0}f=ob(j,e)|0;i=k;return f|0}function Za(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,j=0,k=0,l=0,m=0;m=i;i=i+32|0;j=m+20|0;l=m;c[l+0>>2]=c[a+0>>2];c[l+4>>2]=c[a+4>>2];c[l+8>>2]=c[a+8>>2];c[l+12>>2]=c[a+12>>2];c[l+16>>2]=c[a+16>>2];g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=c[b+12>>2]|0;a=0;while(1)if(!(g>>>a))break;else a=a+1|0;if((jb(l,a+-1|0)|0)==-1){l=1;i=m;return l|0}if((d|0)==5?(h=nb(l,j)|0,(h|0)!=0):0){l=h;i=m;return l|0}g=ob(l,f)|0;if(g){l=g;i=m;return l|0}if((e|0)!=0?(k=ob(l,f+4|0)|0,(k|0)!=0):0){l=k;i=m;return l|0}l=0;i=m;return l|0}function _a(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,j=0,k=0,l=0,m=0,n=0,o=0;m=i;i=i+32|0;l=m+24|0;j=m+20|0;k=m;c[k+0>>2]=c[b+0>>2];c[k+4>>2]=c[b+4>>2];c[k+8>>2]=c[b+8>>2];c[k+12>>2]=c[b+12>>2];c[k+16>>2]=c[b+16>>2];f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=c[d+12>>2]|0;b=0;while(1)if(!(f>>>b))break;else b=b+1|0;if((jb(k,b+-1|0)|0)==-1){n=1;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}g=d+16|0;f=c[g>>2]|0;if(!f){b=c[d+20>>2]|0;f=0;while(1)if(!(b>>>f))break;else f=f+1|0;if((jb(k,f+-1|0)|0)==-1){n=1;i=m;return n|0}if((c[e+8>>2]|0)!=0?(h=ob(k,j)|0,(h|0)!=0):0){n=h;i=m;return n|0}f=c[g>>2]|0}if((f|0)==1?(c[d+24>>2]|0)==0:0){f=ob(k,j)|0;if(f){n=f;i=m;return n|0}if((c[e+8>>2]|0)!=0?(n=ob(k,j)|0,(n|0)!=0):0){i=m;return n|0}}if((c[e+68>>2]|0)!=0?(o=nb(k,l)|0,(o|0)!=0):0){n=o;i=m;return n|0}n=jb(k,1)|0;c[a>>2]=n;n=(n|0)==-1&1;i=m;return n|0}function $a(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=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;C=i;i=i+448|0;p=C+8|0;x=C+4|0;v=C;p=p+(0-p&15)|0;n=c[b+3376>>2]|0;j=c[e>>2]|0;c[x>>2]=0;y=b+1192|0;c[y>>2]=(c[y>>2]|0)+1;q=b+1200|0;c[q>>2]=0;o=b+12|0;c[v>>2]=(c[e+48>>2]|0)+(c[(c[o>>2]|0)+52>>2]|0);w=e+36|0;r=b+1212|0;s=e+52|0;t=e+56|0;u=e+60|0;z=e+4|0;l=e+44|0;h=b+1220|0;m=b+1172|0;B=b+1176|0;k=n+12|0;A=0;f=0;while(1){e=c[r>>2]|0;if((c[w>>2]|0)==0?(c[e+(j*216|0)+196>>2]|0)!=0:0){f=1;e=22;break}g=c[(c[o>>2]|0)+56>>2]|0;F=c[s>>2]|0;E=c[t>>2]|0;D=c[u>>2]|0;c[e+(j*216|0)+4>>2]=c[y>>2];c[e+(j*216|0)+8>>2]=F;c[e+(j*216|0)+12>>2]=E;c[e+(j*216|0)+16>>2]=D;c[e+(j*216|0)+24>>2]=g;e=c[z>>2]|0;if((e|0)!=2?!((e|0)==7|(f|0)!=0):0){f=nb(a,x)|0;if(f){e=22;break}e=c[x>>2]|0;if(e>>>0>((c[B>>2]|0)-j|0)>>>0){f=1;e=22;break}if(!e)f=0;else{id(k,0,164);c[n>>2]=0;f=1}}e=c[x>>2]|0;if(!e){f=bb(a,n,(c[r>>2]|0)+(j*216|0)|0,c[z>>2]|0,c[l>>2]|0)|0;if(!f)g=0;else{e=22;break}}else{c[x>>2]=e+-1;g=f}f=gb((c[r>>2]|0)+(j*216|0)|0,n,d,h,v,j,c[(c[o>>2]|0)+64>>2]|0,p)|0;if(f){e=22;break}A=((c[(c[r>>2]|0)+(j*216|0)+196>>2]|0)==1&1)+A|0;if(!(La(a)|0))e=(c[x>>2]|0)!=0;else e=1;f=c[z>>2]|0;if((f|0)==7|(f|0)==2)c[q>>2]=j;j=Ma(c[m>>2]|0,c[B>>2]|0,j)|0;if(!((j|0)!=0|e^1)){f=1;e=22;break}if(!e){e=20;break}else f=g}if((e|0)==20){e=b+1196|0;f=(c[e>>2]|0)+A|0;if(f>>>0>(c[B>>2]|0)>>>0){y=1;i=C;return y|0}c[e>>2]=f;y=0;i=C;return y|0}else if((e|0)==22){i=C;return f|0}return 0}function ab(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;h=c[a+1192>>2]|0;d=c[a+1200>>2]|0;j=a+1212|0;a:do if(!d)d=b;else{e=a+16|0;f=0;do{do{d=d+-1|0;if(d>>>0<=b>>>0)break a}while((c[(c[j>>2]|0)+(d*216|0)+4>>2]|0)!=(h|0));f=f+1|0;g=c[(c[e>>2]|0)+52>>2]|0}while(f>>>0<(g>>>0>10?g:10)>>>0)}while(0);g=a+1172|0;b=a+1176|0;while(1){e=c[j>>2]|0;if((c[e+(d*216|0)+4>>2]|0)!=(h|0)){d=11;break}f=e+(d*216|0)+196|0;e=c[f>>2]|0;if(!e){d=11;break}c[f>>2]=e+-1;d=Ma(c[g>>2]|0,c[b>>2]|0,d)|0;if(!d){d=11;break}}if((d|0)==11){i=k;return}}function bb(a,d,e,f,g){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=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;B=i;i=i+32|0;u=B+20|0;v=B+16|0;q=B+12|0;p=B+8|0;z=B+4|0;y=B;id(d,0,2088);l=nb(a,z)|0;m=c[z>>2]|0;do if((f|0)==2|(f|0)==7){m=m+6|0;if(m>>>0>31|(l|0)!=0){e=1;i=B;return e|0}else{c[d>>2]=m;o=m;break}}else{m=m+1|0;if(m>>>0>31|(l|0)!=0){e=1;i=B;return e|0}else{c[d>>2]=m;o=m;break}}while(0);a:do if((o|0)!=31){b:do if(o>>>0>=6){o=(o|0)!=6;p=o&1;if(!p){c[v>>2]=0;q=0;while(1){f=kb(a)|0;c[u>>2]=f;t=f>>>31;c[d+(q<<2)+12>>2]=t;if(!t){c[d+(q<<2)+76>>2]=f>>>28&7;m=f<<4;n=1}else{m=f<<1;n=0}f=q|1;t=m>>>31;c[d+(f<<2)+12>>2]=t;if(!t){c[d+(f<<2)+76>>2]=m>>>28&7;l=m<<4;n=n+1|0}else l=m<<1;m=f+1|0;t=l>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=l>>>28&7;m=l<<4;n=n+1|0}else m=l<<1;l=q|3;t=m>>>31;c[d+(l<<2)+12>>2]=t;if(!t){c[d+(l<<2)+76>>2]=m>>>28&7;f=m<<4;n=n+1|0}else f=m<<1;m=l+1|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=l+2|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=l+3|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=q|7;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;m=f<<4;n=n+1|0}else m=f<<1;c[u>>2]=m;if((lb(a,(n*3|0)+8|0)|0)==-1){w=1;t=68;break b}t=(c[v>>2]|0)+1|0;c[v>>2]=t;if((t|0)<2)q=q+8|0;else{t=52;break}}}else if((p|0)==1)t=52;if((t|0)==52){v=(nb(a,u)|0)!=0;l=c[u>>2]|0;if(v|l>>>0>3){w=1;t=68;break}c[d+140>>2]=l}if(o){v=c[d>>2]|0;s=v+-7|0;u=s>>>2;c[d+4>>2]=(s>>>0>11?u+268435453|0:u)<<4|(v>>>0>18?15:0)}else{x=p;t=70}}else{if((o|0)==0|(o|0)==1){r=v;s=u}else if(!((o|0)==3|(o|0)==2)){f=0;do{l=(nb(a,q)|0)!=0;m=c[q>>2]|0;if(l|m>>>0>3){n=1;t=96;break}c[d+(f<<2)+176>>2]=m;f=f+1|0}while(f>>>0<4);if((t|0)==96){i=B;return n|0}c:do if(g>>>0>1&(o|0)!=5){m=g>>>0>2&1;f=0;while(1){if(qb(a,q,m)|0){n=1;t=96;break}n=c[q>>2]|0;if(n>>>0>=g>>>0){n=1;t=96;break}c[d+(f<<2)+192>>2]=n;f=f+1|0;if(f>>>0>=4){h=0;break c}}if((t|0)==96){i=B;return n|0}}else h=0;while(0);d:while(1){n=c[d+(h<<2)+176>>2]|0;if(!n)n=0;else if((n|0)==2|(n|0)==1)n=1;else n=3;c[q>>2]=n;m=0;while(1){n=ob(a,p)|0;if(n){t=96;break d}b[d+(h<<4)+(m<<2)+208>>1]=c[p>>2];n=ob(a,p)|0;if(n){t=96;break d}b[d+(h<<4)+(m<<2)+210>>1]=c[p>>2];t=c[q>>2]|0;c[q>>2]=t+-1;if(!t)break;else m=m+1|0}h=h+1|0;if(h>>>0>=4){x=2;t=70;break b}}if((t|0)==96){i=B;return n|0}}else{r=v;s=u}if(g>>>0>1){if((o|0)==0|(o|0)==1)n=0;else if((o|0)==3|(o|0)==2)n=1;else n=3;l=g>>>0>2&1;f=0;while(1){if(qb(a,u,l)|0){w=1;t=68;break b}m=c[u>>2]|0;if(m>>>0>=g>>>0){w=1;t=68;break b}c[d+(f<<2)+144>>2]=m;if(!n)break;else{n=n+-1|0;f=f+1|0}}}if((o|0)==0|(o|0)==1){l=0;m=0}else if((o|0)==3|(o|0)==2){l=1;m=0}else{l=3;m=0}while(1){f=ob(a,v)|0;if(f){w=f;t=68;break b}b[d+(m<<2)+160>>1]=c[v>>2];f=ob(a,v)|0;if(f){w=f;t=68;break b}b[d+(m<<2)+162>>1]=c[v>>2];if(!l){x=2;t=70;break}else{l=l+-1|0;m=m+1|0}}}while(0);if((t|0)==68){e=w;i=B;return e|0}do if((t|0)==70){h=pb(a,z,(x|0)==0&1)|0;if(!h){z=c[z>>2]|0;c[d+4>>2]=z;if(!z)break a;else break}else{e=h;i=B;return e|0}}while(0);z=(ob(a,y)|0)!=0;h=c[y>>2]|0;if(z|(h|0)<-26|(h|0)>25){e=1;i=B;return e|0}c[d+8>>2]=h;l=c[d+4>>2]|0;o=d+272|0;e:do if((c[d>>2]|0)>>>0>=7){h=rb(a,d+1864|0,ib(e,0,o)|0,16)|0;if(!(h&15)){b[d+320>>1]=h>>>4&255;h=0;m=3;while(1){n=l>>>1;if(!(l&1))h=h+4|0;else{f=3;while(1){l=rb(a,d+(h<<6)+332|0,ib(e,h,o)|0,15)|0;c[d+(h<<2)+1992>>2]=l>>>15;if(l&15){j=l;break e}b[d+(h<<1)+272>>1]=l>>>4&255;h=h+1|0;if(!f)break;else f=f+-1|0}}if(!m){k=h;A=n;t=87;break}else{l=n;m=m+-1|0}}}else j=h}else{h=0;m=3;while(1){n=l>>>1;if(!(l&1))h=h+4|0;else{f=3;while(1){l=rb(a,d+(h<<6)+328|0,ib(e,h,o)|0,16)|0;c[d+(h<<2)+1992>>2]=l>>>16;if(l&15){j=l;break e}b[d+(h<<1)+272>>1]=l>>>4&255;h=h+1|0;if(!f)break;else f=f+-1|0}}if(!m){k=h;A=n;t=87;break}else{l=n;m=m+-1|0}}}while(0);f:do if((t|0)==87){if(A&3){j=rb(a,d+1928|0,-1,4)|0;if(j&15)break;b[d+322>>1]=j>>>4&255;j=rb(a,d+1944|0,-1,4)|0;if(j&15)break;b[d+324>>1]=j>>>4&255}if(!(A&2))j=0;else{h=7;while(1){j=rb(a,d+(k<<6)+332|0,ib(e,k,o)|0,15)|0;if(j&15)break f;b[d+(k<<1)+272>>1]=j>>>4&255;c[d+(k<<2)+1992>>2]=j>>>15;if(!h){j=0;break}else{k=k+1|0;h=h+-1|0}}}}while(0);c[a+16>>2]=((c[a+4>>2]|0)-(c[a>>2]|0)<<3)+(c[a+8>>2]|0);if(j){e=j;i=B;return e|0}}else{while(1){if(mb(a)|0)break;if(jb(a,1)|0){n=1;t=96;break}}if((t|0)==96){i=B;return n|0}k=0;j=d+328|0;while(1){h=jb(a,8)|0;c[z>>2]=h;if((h|0)==-1){n=1;break}c[j>>2]=h;k=k+1|0;if(k>>>0>=384)break a;else j=j+4|0}i=B;return n|0}while(0);e=0;i=B;return e|0}function cb(a){a=a|0;if(a>>>0<6)a=2;else a=(a|0)!=6&1;return a|0}function db(a){a=a|0;var b=0;b=i;if((a|0)==0|(a|0)==1)a=1;else if((a|0)==3|(a|0)==2)a=2;else a=4;i=b;return a|0}function eb(a){a=a|0;var b=0;b=i;if(!a)a=1;else if((a|0)==2|(a|0)==1)a=2;else a=4;i=b;return a|0}function fb(a){a=a|0;return a+1&3|0}function gb(d,e,f,g,h,j,k,l){d=d|0;e=e|0;f=f|0;g=g|0;h=h|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;v=i;s=c[e>>2]|0;c[d>>2]=s;o=d+196|0;c[o>>2]=(c[o>>2]|0)+1;Na(f,j);if((s|0)==31){m=d+28|0;c[d+20>>2]=0;if((c[o>>2]|0)>>>0>1){b[m>>1]=16;b[d+30>>1]=16;b[d+32>>1]=16;b[d+34>>1]=16;b[d+36>>1]=16;b[d+38>>1]=16;b[d+40>>1]=16;b[d+42>>1]=16;b[d+44>>1]=16;b[d+46>>1]=16;b[d+48>>1]=16;b[d+50>>1]=16;b[d+52>>1]=16;b[d+54>>1]=16;b[d+56>>1]=16;b[d+58>>1]=16;b[d+60>>1]=16;b[d+62>>1]=16;b[d+64>>1]=16;b[d+66>>1]=16;b[d+68>>1]=16;b[d+70>>1]=16;b[d+72>>1]=16;b[d+74>>1]=16;t=0;i=v;return t|0}o=23;h=e+328|0;n=l;while(1){b[m>>1]=16;a[n>>0]=c[h>>2];a[n+1>>0]=c[h+4>>2];a[n+2>>0]=c[h+8>>2];a[n+3>>0]=c[h+12>>2];a[n+4>>0]=c[h+16>>2];a[n+5>>0]=c[h+20>>2];a[n+6>>0]=c[h+24>>2];a[n+7>>0]=c[h+28>>2];a[n+8>>0]=c[h+32>>2];a[n+9>>0]=c[h+36>>2];a[n+10>>0]=c[h+40>>2];a[n+11>>0]=c[h+44>>2];a[n+12>>0]=c[h+48>>2];a[n+13>>0]=c[h+52>>2];a[n+14>>0]=c[h+56>>2];a[n+15>>0]=c[h+60>>2];if(!o)break;else{o=o+-1|0;h=h+64|0;n=n+16|0;m=m+2|0}}sc(f,l);t=0;i=v;return t|0}m=d+28|0;if(s){hd(m,e+272|0,54);n=c[e+8>>2]|0;o=c[h>>2]|0;do if(n){o=o+n|0;c[h>>2]=o;if((o|0)<0){o=o+52|0;c[h>>2]=o;break}if((o|0)>51){o=o+-52|0;c[h>>2]=o}}while(0);r=d+20|0;c[r>>2]=o;n=e+328|0;h=e+1992|0;a:do if((c[d>>2]|0)>>>0<7){q=15;o=m;while(1){if(b[o>>1]|0){if(Ga(n,c[r>>2]|0,0,c[h>>2]|0)|0){m=1;break}}else c[n>>2]=16777215;n=n+64|0;o=o+2|0;h=h+4|0;if(!q)break a;else q=q+-1|0}i=v;return m|0}else{if(!(b[d+76>>1]|0)){q=464;p=15;o=m}else{Ha(e+1864|0,o);q=464;p=15;o=m}while(1){m=c[e+(c[q>>2]<<2)+1864>>2]|0;q=q+4|0;c[n>>2]=m;if((m|0)==0?(b[o>>1]|0)==0:0)c[n>>2]=16777215;else u=18;if((u|0)==18?(u=0,(Ga(n,c[r>>2]|0,1,c[h>>2]|0)|0)!=0):0){m=1;break}n=n+64|0;o=o+2|0;h=h+4|0;if(!p)break a;else p=p+-1|0}i=v;return m|0}while(0);q=c[192+((Oa(0,51,(c[d+24>>2]|0)+(c[r>>2]|0)|0)|0)<<2)>>2]|0;if((b[d+78>>1]|0)==0?(b[d+80>>1]|0)==0:0){p=e+1928|0;m=7}else{p=e+1928|0;Ia(p,q);m=7}while(1){r=c[p>>2]|0;p=p+4|0;c[n>>2]=r;if((r|0)==0?(b[o>>1]|0)==0:0)c[n>>2]=16777215;else u=31;if((u|0)==31?(u=0,(Ga(n,q,1,c[h>>2]|0)|0)!=0):0){m=1;u=39;break}if(!m)break;else{n=n+64|0;h=h+4|0;m=m+-1|0;o=o+2|0}}if((u|0)==39){i=v;return m|0}if(s>>>0>=6){o=Mb(d,e,f,j,k,l)|0;if(o){t=o;i=v;return t|0}}else u=37}else{id(m,0,54);c[d+20>>2]=c[h>>2];u=37}if((u|0)==37?(t=Sb(d,e,g,j,f,l)|0,(t|0)!=0):0){i=v;return t|0}t=0;i=v;return t|0}function hb(a){a=a|0;return a|0}function ib(d,e,f){d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0;k=i;l=vb(e)|0;g=wb(e)|0;h=a[l+4>>0]|0;j=a[g+4>>0]|0;g=(c[g>>2]|0)==4;if((c[l>>2]|0)==4){e=b[f+((h&255)<<1)>>1]|0;if(g){e=e+1+(b[f+((j&255)<<1)>>1]|0)>>1;i=k;return e|0}g=d+204|0;if(!(zb(d,c[g>>2]|0)|0)){i=k;return e|0}e=e+1+(b[(c[g>>2]|0)+((j&255)<<1)+28>>1]|0)>>1;i=k;return e|0}if(g){e=b[f+((j&255)<<1)>>1]|0;g=d+200|0;if(!(zb(d,c[g>>2]|0)|0)){i=k;return e|0}e=e+1+(b[(c[g>>2]|0)+((h&255)<<1)+28>>1]|0)>>1;i=k;return e|0}g=d+200|0;if(!(zb(d,c[g>>2]|0)|0)){h=0;f=0}else{h=b[(c[g>>2]|0)+((h&255)<<1)+28>>1]|0;f=1}g=d+204|0;if(!(zb(d,c[g>>2]|0)|0)){e=h;i=k;return e|0}e=b[(c[g>>2]|0)+((j&255)<<1)+28>>1]|0;if(!f){i=k;return e|0}e=h+1+e>>1;i=k;return e|0}function jb(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;n=a+4|0;j=c[n>>2]|0;m=c[a+12>>2]<<3;o=a+16|0;l=c[o>>2]|0;g=m-l|0;if((g|0)>31){e=a+8|0;g=c[e>>2]|0;f=(d[j+1>>0]|0)<<16|(d[j>>0]|0)<<24|(d[j+2>>0]|0)<<8|(d[j+3>>0]|0);if(!g)h=e;else{h=e;f=(d[j+4>>0]|0)>>>(8-g|0)|f<0){e=c[h>>2]|0;k=e+24|0;f=(d[j>>0]|0)<0){e=g;g=k;do{j=j+1|0;g=g+-8|0;f=(d[j>>0]|0)<0)}}else f=0}e=l+b|0;c[o>>2]=e;c[h>>2]=e&7;if(e>>>0>m>>>0){n=-1;i=p;return n|0}c[n>>2]=(c[a>>2]|0)+(e>>>3);n=f>>>(32-b|0);i=p;return n|0}function kb(a){a=a|0;var b=0,e=0,f=0,g=0,h=0;g=i;f=c[a+4>>2]|0;e=(c[a+12>>2]<<3)-(c[a+16>>2]|0)|0;if((e|0)>31){b=c[a+8>>2]|0;a=(d[f+1>>0]|0)<<16|(d[f>>0]|0)<<24|(d[f+2>>0]|0)<<8|(d[f+3>>0]|0);if(!b){b=a;i=g;return b|0}b=(d[f+4>>0]|0)>>>(8-b|0)|a<>2]|0;a=h+24|0;b=(d[f>>0]|0)<>0]|0)<0);i=g;return b|0}function lb(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;e=a+16|0;b=(c[e>>2]|0)+b|0;c[e>>2]=b;c[a+8>>2]=b&7;if(b>>>0>c[a+12>>2]<<3>>>0){b=-1;i=d;return b|0}c[a+4>>2]=(c[a>>2]|0)+(b>>>3);b=0;i=d;return b|0}function mb(a){a=a|0;return (c[a+8>>2]|0)==0|0}function nb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=i;d=kb(a)|0;do if((d|0)>=0){if(d>>>0>1073741823){if((lb(a,3)|0)==-1){d=1;break}c[b>>2]=(d>>>29&1)+1;d=0;break}if(d>>>0>536870911){if((lb(a,5)|0)==-1){d=1;break}c[b>>2]=(d>>>27&3)+3;d=0;break}if(d>>>0>268435455){if((lb(a,7)|0)==-1){d=1;break}c[b>>2]=(d>>>25&7)+7;d=0;break}d=Ja(d,28)|0;e=d+4|0;if((e|0)!=32){lb(a,d+5|0)|0;d=jb(a,e)|0;if((d|0)==-1){d=1;break}c[b>>2]=(1<>2]=0;lb(a,32)|0;if((jb(a,1)|0)==1?(f=kb(a)|0,(lb(a,32)|0)!=-1):0)if((f|0)==1){c[b>>2]=-1;d=1;break}else if(!f){c[b>>2]=-1;d=0;break}else{d=1;break}else d=1}else{lb(a,1)|0;c[b>>2]=0;d=0}while(0);i=g;return d|0}function ob(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;f=e;c[f>>2]=0;d=nb(a,f)|0;a=c[f>>2]|0;d=(d|0)==0;if((a|0)==-1)if(d)a=1;else{c[b>>2]=-2147483648;a=0}else if(d){d=(a+1|0)>>>1;c[b>>2]=(a&1|0)!=0?d:0-d|0;a=0}else a=1;i=e;return a|0}function pb(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0;g=i;i=i+16|0;f=g;if(nb(a,f)|0){f=1;i=g;return f|0}f=c[f>>2]|0;if(f>>>0>47){f=1;i=g;return f|0}c[b>>2]=d[((e|0)==0?576:528)+f>>0];f=0;i=g;return f|0}function qb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=i;if(!d){d=jb(a,1)|0;c[b>>2]=d;if((d|0)==-1)d=1;else{c[b>>2]=d^1;d=0}}else d=nb(a,b)|0;i=e;return d|0}function rb(a,b,f,g){a=a|0;b=b|0;f=f|0;g=g|0;var h=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,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0;O=i;i=i+128|0;M=O+64|0;N=O;n=kb(a)|0;p=n>>>16;do if(f>>>0<2)if((n|0)>=0){if(n>>>0>201326591){o=e[1264+(n>>>26<<1)>>1]|0;k=25;break}if(n>>>0>16777215){o=e[1328+(n>>>22<<1)>>1]|0;k=25;break}if(n>>>0>2097151){o=e[1424+((n>>>18)+-8<<1)>>1]|0;k=25;break}else{o=e[1536+(p<<1)>>1]|0;k=25;break}}else q=1;else if(f>>>0<4){if((n|0)<0){q=(p&16384|0)!=0?2:2082;break}if(n>>>0>268435455){o=e[1600+(n>>>26<<1)>>1]|0;k=25;break}if(n>>>0>33554431){o=e[1664+(n>>>23<<1)>>1]|0;k=25;break}else{o=e[1728+(n>>>18<<1)>>1]|0;k=25;break}}else{if(f>>>0<8){f=n>>>26;if((f+-8|0)>>>0<56){o=e[1984+(f<<1)>>1]|0;k=25;break}o=e[2112+(n>>>22<<1)>>1]|0;k=25;break}if(f>>>0<17){o=e[2368+(n>>>26<<1)>>1]|0;k=25;break}f=n>>>29;if(f){o=e[2496+(f<<1)>>1]|0;k=25;break}o=e[2512+(n>>>24<<1)>>1]|0;k=25;break}while(0);if((k|0)==25)if(!o){C=1;i=O;return C|0}else q=o;o=q&31;f=n<>>11&31;if(I>>>0>g>>>0){C=1;i=O;return C|0}v=q>>>5&63;do if(I){if(!v)o=0;else{do if(p>>>0>>0)if((lb(a,o)|0)==-1){C=1;i=O;return C|0}else{p=32;f=kb(a)|0;break}while(0);n=f>>>(32-v|0);f=f<>2]=(o&n|0)!=0?-1:1;o=o>>>1;k=k+1|0}while((o|0)!=0);p=p-v|0;o=k}u=v>>>0<3;a:do if(o>>>0>>0){t=o;s=I>>>0>10&u&1;b:while(1){if(p>>>0<16){if((lb(a,32-p|0)|0)==-1){J=1;k=127;break}r=32;f=kb(a)|0}else r=p;do if((f|0)>=0)if(f>>>0<=1073741823)if(f>>>0<=536870911)if(f>>>0<=268435455)if(f>>>0<=134217727)if(f>>>0<=67108863)if(f>>>0<=33554431)if(f>>>0<=16777215)if(f>>>0<=8388607)if(f>>>0>4194303){H=9;k=59}else{if(f>>>0>2097151){H=10;k=59;break}if(f>>>0>1048575){H=11;k=59;break}if(f>>>0>524287){H=12;k=59;break}if(f>>>0>262143){H=13;k=59;break}if(f>>>0>131071){p=14;o=f<<15;n=r+-15|0;q=s;k=(s|0)!=0?s:4}else{if(f>>>0<65536){J=1;k=127;break b}p=15;o=f<<16;n=r+-16|0;q=(s|0)!=0?s:1;k=12}G=p<>>0>>0){if((lb(a,32-y|0)|0)==-1){J=1;k=127;break}o=32;f=kb(a)|0}else{o=y;f=B}E=o-x|0;F=f<>>(32-x|0))+G|0;C=z;D=w}s=(t|0)==(v|0)&u?A+2|0:A;o=(s+2|0)>>>1;n=D?1:C;c[M+(t<<2)>>2]=(s&1|0)==0?o:0-o|0;t=t+1|0;if(t>>>0>=I>>>0){l=E;m=F;break a}else{p=E;f=F;s=((o|0)>(3<>>0<6&1)+n|0}}if((k|0)==127){i=O;return J|0}}else{l=p;m=f}while(0);if(I>>>0>>0){do if(l>>>0<9)if((lb(a,32-l|0)|0)==-1){C=1;i=O;return C|0}else{l=32;m=kb(a)|0;break}while(0);k=m>>>23;c:do if((g|0)==4)if((m|0)>=0)if((I|0)!=3)if(m>>>0<=1073741823)if((I|0)==2)k=34;else k=m>>>0>536870911?35:51;else k=18;else k=17;else k=1;else{do switch(I|0){case 8:{k=d[1056+(m>>>26)>>0]|0;break}case 9:{k=d[1120+(m>>>26)>>0]|0;break}case 2:{k=d[736+(m>>>26)>>0]|0;break}case 1:{if(m>>>0>268435455)k=d[672+(m>>>27)>>0]|0;else k=d[704+k>>0]|0;break}case 13:{k=d[1248+(m>>>29)>>0]|0;break}case 14:{k=d[1256+(m>>>30)>>0]|0;break}case 3:{k=d[800+(m>>>26)>>0]|0;break}case 4:{k=d[864+(m>>>27)>>0]|0;break}case 5:{k=d[896+(m>>>27)>>0]|0;break}case 10:{k=d[1184+(m>>>27)>>0]|0;break}case 6:{k=d[928+(m>>>26)>>0]|0;break}case 7:{k=d[992+(m>>>26)>>0]|0;break}case 11:{k=d[1216+(m>>>28)>>0]|0;break}case 12:{k=d[1232+(m>>>28)>>0]|0;break}default:{k=m>>31&16|1;break c}}while(0);if(!k){C=1;i=O;return C|0}}while(0);n=k&15;l=l-n|0;m=m<>>4&15}else n=0;p=I+-1|0;f=(p|0)==0;if(f){c[b+(n<<2)>>2]=c[M+(p<<2)>>2];K=l;h=1<>2]=1;L=l;j=0}else{if(l>>>0<11){if((lb(a,32-l|0)|0)==-1){J=1;k=127;break}l=32;k=kb(a)|0}switch(n|0){case 4:{m=d[648+(k>>>29)>>0]|0;break}case 5:{m=d[656+(k>>>29)>>0]|0;break}case 6:{m=d[664+(k>>>29)>>0]|0;break}case 1:{m=d[624+(k>>>31)>>0]|0;break}case 2:{m=d[632+(k>>>30)>>0]|0;break}case 3:{m=d[640+(k>>>30)>>0]|0;break}default:{do if(k>>>0<=536870911)if(k>>>0<=268435455)if(k>>>0<=134217727)if(k>>>0<=67108863)if(k>>>0<=33554431)if(k>>>0>16777215)m=184;else{if(k>>>0>8388607){m=201;break}if(k>>>0>4194303){m=218;break}m=k>>>0<2097152?0:235}else m=167;else m=150;else m=133;else m=116;else m=k>>>29<<4^115;while(0);if((m>>>4&15)>>>0>n>>>0){J=1;k=127;break d}}}if(!m){J=1;k=127;break}C=m&15;j=m>>>4&15;c[N+(o<<2)>>2]=j+1;L=l-C|0;k=k<>>0>=p>>>0){k=122;break}else{l=L;n=j}}if((k|0)==122){c[b+(j<<2)>>2]=c[M+(p<<2)>>2];h=1<>2]|0)+j|0;h=1<>2]=c[M+(k<<2)>>2];if(!k){K=L;break}else k=k+-1|0}}else if((k|0)==127){i=O;return J|0}}else{K=p;h=0}while(0);if(lb(a,32-K|0)|0){C=1;i=O;return C|0}C=h<<16|I<<4;i=O;return C|0}function sb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;a:do if((jb(a,1)|0)!=-1?(e=b+4|0,c[e>>2]=jb(a,2)|0,d=jb(a,5)|0,c[b>>2]=d,(d+-2|0)>>>0>=3):0){switch(d|0){case 6:case 9:case 10:case 11:case 12:{if(c[e>>2]|0){d=1;break a}break}case 5:case 7:case 8:{if(!(c[e>>2]|0)){d=1;break a}switch(d|0){case 6:case 9:case 10:case 11:case 12:{d=1;break a}default:{}}break}default:{}}d=0}else d=1;while(0);i=f;return d|0}function tb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;if(!d){i=o;return}m=b+-1|0;j=1-b|0;k=~b;g=0;h=0;l=0;while(1){f=(g|0)!=0;if(f)c[a+(h*216|0)+200>>2]=a+((h+-1|0)*216|0);else c[a+(h*216|0)+200>>2]=0;e=(l|0)!=0;if(e){c[a+(h*216|0)+204>>2]=a+((h-b|0)*216|0);if(g>>>0>>0)c[a+(h*216|0)+208>>2]=a+((j+h|0)*216|0);else n=10}else{c[a+(h*216|0)+204>>2]=0;n=10}if((n|0)==10){n=0;c[a+(h*216|0)+208>>2]=0}if(e&f)c[a+(h*216|0)+212>>2]=a+((h+k|0)*216|0);else c[a+(h*216|0)+212>>2]=0;e=g+1|0;f=(e|0)==(b|0);h=h+1|0;if((h|0)==(d|0))break;else{g=f?0:e;l=(f&1)+l|0}}i=o;return}function ub(a,b){a=a|0;b=b|0;var d=0;d=i;switch(b|0){case 1:{a=c[a+204>>2]|0;break}case 3:{a=c[a+212>>2]|0;break}case 4:break;case 2:{a=c[a+208>>2]|0;break}case 0:{a=c[a+200>>2]|0;break}default:a=0}i=d;return a|0}function vb(a){a=a|0;return 3152+(a<<3)|0}function wb(a){a=a|0;return 2960+(a<<3)|0}function xb(a){a=a|0;return 2768+(a<<3)|0}function yb(a){a=a|0;return 2576+(a<<3)|0}function zb(a,b){a=a|0;b=b|0;var d=0;d=i;if(!b){i=d;return 0}else{i=d;return (c[a+4>>2]|0)==(c[b+4>>2]|0)|0}return 0}function Ab(a){a=a|0;var b=0;b=i;id(a,0,3388);c[a+8>>2]=32;c[a+4>>2]=256;c[a+1332>>2]=1;i=b;return}function Bb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;f=c[b+8>>2]|0;g=a+(f<<2)+20|0;e=c[g>>2]|0;do if(!e){d=fd(92)|0;c[g>>2]=d;if(!d){d=65535;i=h;return d|0}}else{d=a+8|0;if((f|0)!=(c[d>>2]|0)){gd(c[e+40>>2]|0);c[(c[g>>2]|0)+40>>2]=0;gd(c[(c[g>>2]|0)+84>>2]|0);c[(c[g>>2]|0)+84>>2]=0;break}f=a+16|0;if(Ra(b,c[f>>2]|0)|0){gd(c[(c[g>>2]|0)+40>>2]|0);c[(c[g>>2]|0)+40>>2]=0;gd(c[(c[g>>2]|0)+84>>2]|0);c[(c[g>>2]|0)+84>>2]=0;c[d>>2]=33;c[a+4>>2]=257;c[f>>2]=0;c[a+12>>2]=0;break}d=b+40|0;gd(c[d>>2]|0);c[d>>2]=0;d=b+84|0;gd(c[d>>2]|0);c[d>>2]=0;d=0;i=h;return d|0}while(0);f=(c[g>>2]|0)+0|0;d=b+0|0;e=f+92|0;do{c[f>>2]=c[d>>2];f=f+4|0;d=d+4|0}while((f|0)<(e|0));d=0;i=h;return d|0}function Cb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;f=c[b>>2]|0;g=a+(f<<2)+148|0;d=c[g>>2]|0;do if(!d){d=fd(72)|0;c[g>>2]=d;if(!d){d=65535;i=h;return d|0}}else{e=a+4|0;if((f|0)!=(c[e>>2]|0)){gd(c[d+20>>2]|0);c[(c[g>>2]|0)+20>>2]=0;gd(c[(c[g>>2]|0)+24>>2]|0);c[(c[g>>2]|0)+24>>2]=0;gd(c[(c[g>>2]|0)+28>>2]|0);c[(c[g>>2]|0)+28>>2]=0;gd(c[(c[g>>2]|0)+44>>2]|0);c[(c[g>>2]|0)+44>>2]=0;break}if((c[b+4>>2]|0)!=(c[a+8>>2]|0)){c[e>>2]=257;d=c[g>>2]|0}gd(c[d+20>>2]|0);c[(c[g>>2]|0)+20>>2]=0;gd(c[(c[g>>2]|0)+24>>2]|0);c[(c[g>>2]|0)+24>>2]=0;gd(c[(c[g>>2]|0)+28>>2]|0);c[(c[g>>2]|0)+28>>2]=0;gd(c[(c[g>>2]|0)+44>>2]|0);c[(c[g>>2]|0)+44>>2]=0}while(0);f=(c[g>>2]|0)+0|0;d=b+0|0;e=f+72|0;do{c[f>>2]=c[d>>2];f=f+4|0;d=d+4|0}while((f|0)<(e|0));d=0;i=h;return d|0}function Db(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;o=a+(b<<2)+148|0;f=c[o>>2]|0;if(!f){o=1;i=q;return o|0}n=c[f+4>>2]|0;g=c[a+(n<<2)+20>>2]|0;if(!g){o=1;i=q;return o|0}l=c[g+52>>2]|0;m=Z(c[g+56>>2]|0,l)|0;h=c[f+12>>2]|0;a:do if(h>>>0>1){g=c[f+16>>2]|0;if((g|0)==2){k=c[f+24>>2]|0;j=c[f+28>>2]|0;h=h+-1|0;e=0;while(1){f=c[k+(e<<2)>>2]|0;g=c[j+(e<<2)>>2]|0;if(!(f>>>0<=g>>>0&g>>>0>>0)){e=1;g=33;break}e=e+1|0;if(((f>>>0)%(l>>>0)|0)>>>0>((g>>>0)%(l>>>0)|0)>>>0){e=1;g=33;break}if(e>>>0>=h>>>0)break a}if((g|0)==33){i=q;return e|0}}else if(!g){g=c[f+20>>2]|0;f=0;while(1){if((c[g+(f<<2)>>2]|0)>>>0>m>>>0){e=1;break}f=f+1|0;if(f>>>0>=h>>>0)break a}i=q;return e|0}else{if((g+-3|0)>>>0<3){if((c[f+36>>2]|0)>>>0>m>>>0)e=1;else break;i=q;return e|0}if((g|0)!=6)break;if((c[f+40>>2]|0)>>>0>>0)e=1;else break;i=q;return e|0}}while(0);f=a+4|0;g=c[f>>2]|0;do if((g|0)!=256){e=a+3380|0;if(!(c[e>>2]|0)){if((g|0)==(b|0))break;g=a+8|0;if((n|0)==(c[g>>2]|0)){c[f>>2]=b;c[a+12>>2]=c[o>>2];break}if(!d){o=1;i=q;return o|0}else{c[f>>2]=b;o=c[o>>2]|0;c[a+12>>2]=o;o=c[o+4>>2]|0;c[g>>2]=o;o=c[a+(o<<2)+20>>2]|0;c[a+16>>2]=o;n=c[o+52>>2]|0;o=c[o+56>>2]|0;c[a+1176>>2]=Z(o,n)|0;c[a+1340>>2]=n;c[a+1344>>2]=o;c[e>>2]=1;break}}c[e>>2]=0;e=a+1212|0;gd(c[e>>2]|0);c[e>>2]=0;f=a+1172|0;gd(c[f>>2]|0);c[f>>2]=0;g=a+1176|0;c[e>>2]=fd((c[g>>2]|0)*216|0)|0;o=fd(c[g>>2]<<2)|0;c[f>>2]=o;f=c[e>>2]|0;if((f|0)==0|(o|0)==0){o=65535;i=q;return o|0}id(f,0,(c[g>>2]|0)*216|0);f=a+16|0;tb(c[e>>2]|0,c[(c[f>>2]|0)+52>>2]|0,c[g>>2]|0);f=c[f>>2]|0;do if((c[a+1216>>2]|0)==0?(c[f+16>>2]|0)!=2:0){if(((c[f+80>>2]|0)!=0?(p=c[f+84>>2]|0,(c[p+920>>2]|0)!=0):0)?(c[p+944>>2]|0)==0:0){e=1;break}e=0}else e=1;while(0);o=Z(c[f+56>>2]|0,c[f+52>>2]|0)|0;e=lc(a+1220|0,o,c[f+88>>2]|0,c[f+44>>2]|0,c[f+12>>2]|0,e)|0;if(e){o=e;i=q;return o|0}}else{c[f>>2]=b;o=c[o>>2]|0;c[a+12>>2]=o;o=c[o+4>>2]|0;c[a+8>>2]=o;o=c[a+(o<<2)+20>>2]|0;c[a+16>>2]=o;n=c[o+52>>2]|0;o=c[o+56>>2]|0;c[a+1176>>2]=Z(o,n)|0;c[a+1340>>2]=n;c[a+1344>>2]=o;c[a+3380>>2]=1}while(0);o=0;i=q;return o|0}function Eb(a){a=a|0;var b=0,d=0,e=0;e=i;c[a+1196>>2]=0;c[a+1192>>2]=0;d=c[a+1176>>2]|0;if(!d){i=e;return}a=c[a+1212>>2]|0;b=0;do{c[a+(b*216|0)+4>>2]=0;c[a+(b*216|0)+196>>2]=0;b=b+1|0}while(b>>>0>>0);i=e;return}function Fb(a){a=a|0;return (c[a+1188>>2]|0)==0|0}function Gb(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;if(!(c[a+1404>>2]|0)){if((c[a+1196>>2]|0)==(c[a+1176>>2]|0)){a=1;i=f;return a|0}}else{e=c[a+1176>>2]|0;if(!e){a=1;i=f;return a|0}a=c[a+1212>>2]|0;b=0;d=0;do{d=((c[a+(b*216|0)+196>>2]|0)!=0&1)+d|0;b=b+1|0}while(b>>>0>>0);if((d|0)==(e|0)){a=1;i=f;return a|0}}a=0;i=f;return a|0}function Hb(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;e=c[a+16>>2]|0;Kb(c[a+1172>>2]|0,c[a+12>>2]|0,b,c[e+52>>2]|0,c[e+56>>2]|0);i=d;return}function Ib(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;i=i+32|0;g=t+24|0;j=t+20|0;k=t+16|0;n=t+12|0;r=t+8|0;q=t;c[e>>2]=0;switch(c[b>>2]|0){case 5:case 1:{s=d+1300|0;h=d+1332|0;if(c[h>>2]|0){c[e>>2]=1;c[h>>2]=0}h=Ua(a,g)|0;if(h){o=h;i=t;return o|0}l=c[d+(c[g>>2]<<2)+148>>2]|0;if(!l){o=65520;i=t;return o|0}h=c[l+4>>2]|0;m=c[d+(h<<2)+20>>2]|0;if(!m){o=65520;i=t;return o|0}g=c[d+8>>2]|0;if(!((g|0)==32|(h|0)==(g|0))?(c[b>>2]|0)!=5:0){o=65520;i=t;return o|0}g=c[d+1304>>2]|0;h=c[b+4>>2]|0;if((g|0)!=(h|0)?(g|0)==0|(h|0)==0:0)c[e>>2]=1;h=(c[b>>2]|0)==5;if((c[s>>2]|0)==5){if(!h)f=16}else if(h)f=16;if((f|0)==16)c[e>>2]=1;g=m+12|0;if(Va(a,c[g>>2]|0,j)|0){o=1;i=t;return o|0}f=d+1308|0;h=c[j>>2]|0;if((c[f>>2]|0)!=(h|0)){c[f>>2]=h;c[e>>2]=1}if((c[b>>2]|0)==5){if(Wa(a,c[g>>2]|0,5,k)|0){o=1;i=t;return o|0}if((c[s>>2]|0)==5){h=d+1312|0;f=c[h>>2]|0;g=c[k>>2]|0;if((f|0)==(g|0))g=f;else c[e>>2]=1}else{g=c[k>>2]|0;h=d+1312|0}c[h>>2]=g}g=c[m+16>>2]|0;if((g|0)==1){if(!(c[m+24>>2]|0)){h=l+8|0;g=Za(a,m,c[b>>2]|0,c[h>>2]|0,q)|0;if(g){o=g;i=t;return o|0}f=d+1324|0;g=c[q>>2]|0;if((c[f>>2]|0)!=(g|0)){c[f>>2]=g;c[e>>2]=1}if((c[h>>2]|0)!=0?(p=d+1328|0,o=c[q+4>>2]|0,(c[p>>2]|0)!=(o|0)):0){c[p>>2]=o;c[e>>2]=1}}}else if(!g){if(Xa(a,m,c[b>>2]|0,n)|0){o=1;i=t;return o|0}f=d+1316|0;g=c[n>>2]|0;if((c[f>>2]|0)!=(g|0)){c[f>>2]=g;c[e>>2]=1}if(c[l+8>>2]|0){f=Ya(a,m,c[b>>2]|0,r)|0;if(f){o=f;i=t;return o|0}g=d+1320|0;f=c[r>>2]|0;if((c[g>>2]|0)!=(f|0)){c[g>>2]=f;c[e>>2]=1}}}n=b;a=c[n+4>>2]|0;o=s;c[o>>2]=c[n>>2];c[o+4>>2]=a;o=0;i=t;return o|0}case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 16:case 17:case 18:{c[e>>2]=1;o=0;i=t;return o|0}default:{o=0;i=t;return o|0}}return 0}function Jb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;n=i;l=0;a:while(1){b=c[a+(l<<2)+148>>2]|0;b:do if((b|0)!=0?(k=c[a+(c[b+4>>2]<<2)+20>>2]|0,(k|0)!=0):0){j=c[k+52>>2]|0;m=Z(c[k+56>>2]|0,j)|0;f=c[b+12>>2]|0;if(f>>>0<=1){b=0;d=18;break a}d=c[b+16>>2]|0;if((d|0)==2){h=c[b+24>>2]|0;g=c[b+28>>2]|0;f=f+-1|0;e=0;while(1){b=c[h+(e<<2)>>2]|0;d=c[g+(e<<2)>>2]|0;if(!(b>>>0<=d>>>0&d>>>0>>0))break b;e=e+1|0;if(((b>>>0)%(j>>>0)|0)>>>0>((d>>>0)%(j>>>0)|0)>>>0)break b;if(e>>>0>=f>>>0){b=0;d=18;break a}}}else if(d){if((d+-3|0)>>>0<3)if((c[b+36>>2]|0)>>>0>m>>>0)break;else{b=0;d=18;break a}if((d|0)!=6){b=0;d=18;break a}if((c[b+40>>2]|0)>>>0>>0)break;else{b=0;d=18;break a}}else{d=c[b+20>>2]|0;b=0;while(1){if((c[d+(b<<2)>>2]|0)>>>0>m>>>0)break b;b=b+1|0;if(b>>>0>=f>>>0){b=0;d=18;break a}}}}while(0);l=l+1|0;if(l>>>0>=256){b=1;d=18;break}}if((d|0)==18){i=n;return b|0}return 0}function Kb(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,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;v=i;t=Z(f,e)|0;o=c[b+12>>2]|0;if((o|0)==1){id(a,0,t<<2);i=v;return}k=c[b+16>>2]|0;if((k+-3|0)>>>0<3){d=Z(c[b+36>>2]|0,d)|0;d=d>>>0>>0?d:t;if((k&-2|0)==4){n=(c[b+32>>2]|0)==0?d:t-d|0;u=d}else{n=0;u=d}}else{n=0;u=0}switch(k|0){case 0:{l=c[b+20>>2]|0;if(!t){i=v;return}else{h=0;j=0}while(1){while(1)if(h>>>0>>0)break;else h=0;b=l+(h<<2)|0;d=c[b>>2]|0;a:do if(!d)d=0;else{k=0;do{g=k+j|0;if(g>>>0>=t>>>0)break a;c[a+(g<<2)>>2]=h;k=k+1|0;d=c[b>>2]|0}while(k>>>0>>0)}while(0);j=d+j|0;if(j>>>0>=t>>>0)break;else h=h+1|0}i=v;return}case 4:{h=c[b+32>>2]|0;if(!t){i=v;return}d=1-h|0;g=0;do{c[a+(g<<2)>>2]=g>>>0>>0?h:d;g=g+1|0}while((g|0)!=(t|0));i=v;return}case 1:{if(!t){i=v;return}else h=0;do{c[a+(h<<2)>>2]=((((Z((h>>>0)/(e>>>0)|0,o)|0)>>>1)+((h>>>0)%(e>>>0)|0)|0)>>>0)%(o>>>0)|0;h=h+1|0}while((h|0)!=(t|0));i=v;return}case 2:{n=c[b+24>>2]|0;m=c[b+28>>2]|0;h=o+-1|0;if(t){d=0;do{c[a+(d<<2)>>2]=h;d=d+1|0}while((d|0)!=(t|0))}if(!h){i=v;return}g=o+-2|0;while(1){j=c[n+(g<<2)>>2]|0;d=(j>>>0)/(e>>>0)|0;j=(j>>>0)%(e>>>0)|0;h=c[m+(g<<2)>>2]|0;l=(h>>>0)/(e>>>0)|0;h=(h>>>0)%(e>>>0)|0;b:do if(d>>>0<=l>>>0){if(j>>>0>h>>>0)while(1){d=d+1|0;if(d>>>0>l>>>0)break b}do{k=Z(d,e)|0;b=j;do{c[a+(b+k<<2)>>2]=g;b=b+1|0}while(b>>>0<=h>>>0);d=d+1|0}while(d>>>0<=l>>>0)}while(0);if(!g)break;else g=g+-1|0}i=v;return}case 5:{d=c[b+32>>2]|0;if(!e){i=v;return}k=1-d|0;if(!f){i=v;return}else{g=0;j=0}while(1){h=0;b=j;while(1){m=a+((Z(h,e)|0)+g<<2)|0;c[m>>2]=b>>>0>>0?d:k;h=h+1|0;if((h|0)==(f|0))break;else b=b+1|0}g=g+1|0;if((g|0)==(e|0))break;else j=j+f|0}i=v;return}case 3:{m=c[b+32>>2]|0;if(t){d=0;do{c[a+(d<<2)>>2]=1;d=d+1|0}while((d|0)!=(t|0))}l=(e-m|0)>>>1;n=(f-m|0)>>>1;if(!u){i=v;return}t=m<<1;r=t+-1|0;s=e+-1|0;t=1-t|0;q=f+-1|0;o=n;p=0;g=l;f=l;k=n;b=l;j=m+-1|0;d=n;while(1){n=a+((Z(d,e)|0)+b<<2)|0;l=(c[n>>2]|0)==1;h=l&1;if(l)c[n>>2]=0;do if(!((j|0)==-1&(b|0)==(g|0))){if((j|0)==1&(b|0)==(f|0)){b=f+1|0;b=(b|0)<(s|0)?b:s;n=o;l=g;f=b;j=0;m=t;break}if((m|0)==-1&(d|0)==(k|0)){d=k+-1|0;d=(d|0)>0?d:0;n=o;l=g;k=d;j=t;m=0;break}if((m|0)==1&(d|0)==(o|0)){d=o+1|0;d=(d|0)<(q|0)?d:q;n=d;l=g;j=r;m=0;break}else{n=o;l=g;b=b+j|0;d=d+m|0;break}}else{b=g+-1|0;b=(b|0)>0?b:0;n=o;l=b;j=0;m=r}while(0);p=h+p|0;if(p>>>0>=u>>>0)break;else{o=n;g=l}}i=v;return}default:{if(!t){i=v;return}g=c[b+44>>2]|0;h=0;do{c[a+(h<<2)>>2]=c[g+(h<<2)>>2];h=h+1|0}while((h|0)!=(t|0));i=v;return}}}function Lb(){return 3472}function Mb(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,j=0,k=0;k=i;i=i+80|0;h=k+32|0;j=k;Nb(d,h,j,e);if((cb(c[a>>2]|0)|0)==1){e=Ob(a,g,b+328|0,h,j,f)|0;if(e){i=k;return e|0}}else{e=Pb(a,g,b,h,j,f)|0;if(e){i=k;return e|0}}e=Qb(a,g+256|0,b+1352|0,h+21|0,j+16|0,c[b+140>>2]|0,f)|0;if(e){i=k;return e|0}if((c[a+196>>2]|0)>>>0>1){e=0;i=k;return e|0}sc(d,g);e=0;i=k;return e|0}function Nb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=i;if(!f){i=s;return}p=c[b+4>>2]|0;q=Z(c[b+8>>2]|0,p)|0;n=(f>>>0)/(p>>>0)|0;g=Z(n,p)|0;o=f-g|0;k=p<<4;h=c[b>>2]|0;j=(o<<4)+(Z(p<<8,n)|0)|0;r=(n|0)!=0;if(r){m=j-(k|1)|0;a[d>>0]=a[h+m>>0]|0;a[d+1>>0]=a[h+(m+1)>>0]|0;a[d+2>>0]=a[h+(m+2)>>0]|0;a[d+3>>0]=a[h+(m+3)>>0]|0;a[d+4>>0]=a[h+(m+4)>>0]|0;a[d+5>>0]=a[h+(m+5)>>0]|0;a[d+6>>0]=a[h+(m+6)>>0]|0;a[d+7>>0]=a[h+(m+7)>>0]|0;a[d+8>>0]=a[h+(m+8)>>0]|0;a[d+9>>0]=a[h+(m+9)>>0]|0;a[d+10>>0]=a[h+(m+10)>>0]|0;a[d+11>>0]=a[h+(m+11)>>0]|0;a[d+12>>0]=a[h+(m+12)>>0]|0;a[d+13>>0]=a[h+(m+13)>>0]|0;a[d+14>>0]=a[h+(m+14)>>0]|0;a[d+15>>0]=a[h+(m+15)>>0]|0;a[d+16>>0]=a[h+(m+16)>>0]|0;a[d+17>>0]=a[h+(m+17)>>0]|0;a[d+18>>0]=a[h+(m+18)>>0]|0;a[d+19>>0]=a[h+(m+19)>>0]|0;a[d+20>>0]=a[h+(m+20)>>0]|0;m=d+21|0}else m=d;l=(g|0)!=(f|0);if(l){j=j+-1|0;a[e>>0]=a[h+j>>0]|0;j=j+k|0;a[e+1>>0]=a[h+j>>0]|0;j=j+k|0;a[e+2>>0]=a[h+j>>0]|0;j=j+k|0;a[e+3>>0]=a[h+j>>0]|0;j=j+k|0;a[e+4>>0]=a[h+j>>0]|0;j=j+k|0;a[e+5>>0]=a[h+j>>0]|0;j=j+k|0;a[e+6>>0]=a[h+j>>0]|0;j=j+k|0;a[e+7>>0]=a[h+j>>0]|0;j=j+k|0;a[e+8>>0]=a[h+j>>0]|0;j=j+k|0;a[e+9>>0]=a[h+j>>0]|0;j=j+k|0;a[e+10>>0]=a[h+j>>0]|0;j=j+k|0;a[e+11>>0]=a[h+j>>0]|0;j=j+k|0;a[e+12>>0]=a[h+j>>0]|0;j=j+k|0;a[e+13>>0]=a[h+j>>0]|0;j=j+k|0;a[e+14>>0]=a[h+j>>0]|0;a[e+15>>0]=a[h+(j+k)>>0]|0;e=e+16|0}d=p<<3&2147483640;f=c[b>>2]|0;g=(Z(n<<3,d)|0)+(q<<8)+(o<<3)|0;if(r){b=g-(d|1)|0;a[m>>0]=a[f+b>>0]|0;a[m+1>>0]=a[f+(b+1)>>0]|0;a[m+2>>0]=a[f+(b+2)>>0]|0;a[m+3>>0]=a[f+(b+3)>>0]|0;a[m+4>>0]=a[f+(b+4)>>0]|0;a[m+5>>0]=a[f+(b+5)>>0]|0;a[m+6>>0]=a[f+(b+6)>>0]|0;a[m+7>>0]=a[f+(b+7)>>0]|0;a[m+8>>0]=a[f+(b+8)>>0]|0;b=b+(q<<6)|0;a[m+9>>0]=a[f+b>>0]|0;a[m+10>>0]=a[f+(b+1)>>0]|0;a[m+11>>0]=a[f+(b+2)>>0]|0;a[m+12>>0]=a[f+(b+3)>>0]|0;a[m+13>>0]=a[f+(b+4)>>0]|0;a[m+14>>0]=a[f+(b+5)>>0]|0;a[m+15>>0]=a[f+(b+6)>>0]|0;a[m+16>>0]=a[f+(b+7)>>0]|0;a[m+17>>0]=a[f+(b+8)>>0]|0}if(!l){i=s;return}m=g+-1|0;a[e>>0]=a[f+m>>0]|0;m=m+d|0;a[e+1>>0]=a[f+m>>0]|0;m=m+d|0;a[e+2>>0]=a[f+m>>0]|0;m=m+d|0;a[e+3>>0]=a[f+m>>0]|0;m=m+d|0;a[e+4>>0]=a[f+m>>0]|0;m=m+d|0;a[e+5>>0]=a[f+m>>0]|0;m=m+d|0;a[e+6>>0]=a[f+m>>0]|0;m=m+d|0;a[e+7>>0]=a[f+m>>0]|0;m=m+(d+((q<<6)-(p<<6)))|0;a[e+8>>0]=a[f+m>>0]|0;m=m+d|0;a[e+9>>0]=a[f+m>>0]|0;m=m+d|0;a[e+10>>0]=a[f+m>>0]|0;m=m+d|0;a[e+11>>0]=a[f+m>>0]|0;m=m+d|0;a[e+12>>0]=a[f+m>>0]|0;m=m+d|0;a[e+13>>0]=a[f+m>>0]|0;m=m+d|0;a[e+14>>0]=a[f+m>>0]|0;a[e+15>>0]=a[f+(m+d)>>0]|0;i=s;return}function Ob(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var 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;z=i;k=b+200|0;l=zb(b,c[k>>2]|0)|0;o=(j|0)!=0;if((l|0)!=0&o){n=(cb(c[c[k>>2]>>2]|0)|0)==2;n=n?0:l}else n=l;j=b+204|0;l=zb(b,c[j>>2]|0)|0;if((l|0)!=0&o){p=(cb(c[c[j>>2]>>2]|0)|0)==2;p=p?0:l}else p=l;j=b+212|0;l=zb(b,c[j>>2]|0)|0;if((l|0)!=0&o){r=(cb(c[c[j>>2]>>2]|0)|0)==2;l=r?0:l}j=fb(c[b>>2]|0)|0;if(!j){if(!p){r=1;i=z;return r|0}b=g+1|0;m=g+2|0;s=g+3|0;t=g+4|0;u=g+5|0;v=g+6|0;w=g+7|0;x=g+8|0;y=g+9|0;h=g+10|0;l=g+11|0;j=g+12|0;k=g+13|0;q=g+14|0;r=g+15|0;p=g+16|0;o=e;n=0;while(1){a[o>>0]=a[b>>0]|0;a[o+1>>0]=a[m>>0]|0;a[o+2>>0]=a[s>>0]|0;a[o+3>>0]=a[t>>0]|0;a[o+4>>0]=a[u>>0]|0;a[o+5>>0]=a[v>>0]|0;a[o+6>>0]=a[w>>0]|0;a[o+7>>0]=a[x>>0]|0;a[o+8>>0]=a[y>>0]|0;a[o+9>>0]=a[h>>0]|0;a[o+10>>0]=a[l>>0]|0;a[o+11>>0]=a[j>>0]|0;a[o+12>>0]=a[k>>0]|0;a[o+13>>0]=a[q>>0]|0;a[o+14>>0]=a[r>>0]|0;a[o+15>>0]=a[p>>0]|0;n=n+1|0;if((n|0)==16)break;else o=o+16|0}}else if((j|0)==2){l=g+1|0;k=(n|0)!=0;j=(p|0)!=0;do if(!(k&j)){if(k){k=((d[h>>0]|0)+8+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)+(d[h+4>>0]|0)+(d[h+5>>0]|0)+(d[h+6>>0]|0)+(d[h+7>>0]|0)+(d[h+8>>0]|0)+(d[h+9>>0]|0)+(d[h+10>>0]|0)+(d[h+11>>0]|0)+(d[h+12>>0]|0)+(d[h+13>>0]|0)+(d[h+14>>0]|0)+(d[h+15>>0]|0)|0)>>>4;break}if(j)k=((d[l>>0]|0)+8+(d[g+2>>0]|0)+(d[g+3>>0]|0)+(d[g+4>>0]|0)+(d[g+5>>0]|0)+(d[g+6>>0]|0)+(d[g+7>>0]|0)+(d[g+8>>0]|0)+(d[g+9>>0]|0)+(d[g+10>>0]|0)+(d[g+11>>0]|0)+(d[g+12>>0]|0)+(d[g+13>>0]|0)+(d[g+14>>0]|0)+(d[g+15>>0]|0)+(d[g+16>>0]|0)|0)>>>4;else k=128}else{j=0;k=0;do{r=j;j=j+1|0;k=(d[g+j>>0]|0)+k+(d[h+r>>0]|0)|0}while((j|0)!=16);k=(k+16|0)>>>5}while(0);nd(e|0,k&255|0,256)|0}else if((j|0)==1)if(!n){r=1;i=z;return r|0}else{k=e;j=0;while(1){r=h+j|0;a[k>>0]=a[r>>0]|0;a[k+1>>0]=a[r>>0]|0;a[k+2>>0]=a[r>>0]|0;a[k+3>>0]=a[r>>0]|0;a[k+4>>0]=a[r>>0]|0;a[k+5>>0]=a[r>>0]|0;a[k+6>>0]=a[r>>0]|0;a[k+7>>0]=a[r>>0]|0;a[k+8>>0]=a[r>>0]|0;a[k+9>>0]=a[r>>0]|0;a[k+10>>0]=a[r>>0]|0;a[k+11>>0]=a[r>>0]|0;a[k+12>>0]=a[r>>0]|0;a[k+13>>0]=a[r>>0]|0;a[k+14>>0]=a[r>>0]|0;a[k+15>>0]=a[r>>0]|0;j=j+1|0;if((j|0)==16)break;else k=k+16|0}}else{if(!((n|0)!=0&(p|0)!=0&(l|0)!=0)){r=1;i=z;return r|0}j=d[g+16>>0]|0;m=d[h+15>>0]|0;o=d[g>>0]|0;p=(((d[g+9>>0]|0)-(d[g+7>>0]|0)+((d[g+10>>0]|0)-(d[g+6>>0]|0)<<1)+(((d[g+11>>0]|0)-(d[g+5>>0]|0)|0)*3|0)+((d[g+12>>0]|0)-(d[g+4>>0]|0)<<2)+(((d[g+13>>0]|0)-(d[g+3>>0]|0)|0)*5|0)+(((d[g+14>>0]|0)-(d[g+2>>0]|0)|0)*6|0)+(((d[g+15>>0]|0)-(d[g+1>>0]|0)|0)*7|0)+(j-o<<3)|0)*5|0)+32>>6;o=(((d[h+8>>0]|0)-(d[h+6>>0]|0)+(m-o<<3)+((d[h+9>>0]|0)-(d[h+5>>0]|0)<<1)+(((d[h+10>>0]|0)-(d[h+4>>0]|0)|0)*3|0)+((d[h+11>>0]|0)-(d[h+3>>0]|0)<<2)+(((d[h+12>>0]|0)-(d[h+2>>0]|0)|0)*5|0)+(((d[h+13>>0]|0)-(d[h+1>>0]|0)|0)*6|0)+(((d[h+14>>0]|0)-(d[h>>0]|0)|0)*7|0)|0)*5|0)+32>>6;j=(m+j<<4)+16|0;m=0;do{k=j+(Z(m+-7|0,o)|0)|0;n=m<<4;b=0;do{l=k+(Z(b+-7|0,p)|0)>>5;if((l|0)<0)l=0;else l=(l|0)>255?-1:l&255;a[e+(b+n)>>0]=l;b=b+1|0}while((b|0)!=16);m=m+1|0}while((m|0)!=16)}Rb(e,f,0);Rb(e,f+64|0,1);Rb(e,f+128|0,2);Rb(e,f+192|0,3);Rb(e,f+256|0,4);Rb(e,f+320|0,5);Rb(e,f+384|0,6);Rb(e,f+448|0,7);Rb(e,f+512|0,8);Rb(e,f+576|0,9);Rb(e,f+640|0,10);Rb(e,f+704|0,11);Rb(e,f+768|0,12);Rb(e,f+832|0,13);Rb(e,f+896|0,14);Rb(e,f+960|0,15);r=0;i=z;return r|0}function Pb(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var 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,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0;N=i;M=(j|0)!=0;L=0;a:while(1){l=vb(L)|0;n=c[l+4>>2]|0;l=ub(b,c[l>>2]|0)|0;j=zb(b,l)|0;if((j|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;j=E?0:j}o=wb(L)|0;m=c[o+4>>2]|0;o=ub(b,c[o>>2]|0)|0;k=zb(b,o)|0;if((k|0)!=0&M){E=(cb(c[o>>2]|0)|0)==2;k=E?0:k}G=(j|0)!=0;H=(k|0)!=0;I=G&H;if(I){if(!(cb(c[l>>2]|0)|0))n=d[l+(n&255)+82>>0]|0;else n=2;if(!(cb(c[o>>2]|0)|0))j=d[o+(m&255)+82>>0]|0;else j=2;j=n>>>0>>0?n:j}else j=2;if(!(c[f+(L<<2)+12>>2]|0)){E=c[f+(L<<2)+76>>2]|0;j=(E>>>0>=j>>>0&1)+E|0}a[b+L+82>>0]=j;l=c[(xb(L)|0)>>2]|0;l=ub(b,l)|0;m=zb(b,l)|0;if((m|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;m=E?0:m}l=c[(yb(L)|0)>>2]|0;l=ub(b,l)|0;n=zb(b,l)|0;if((n|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;n=E?0:n}J=c[3344+(L<<2)>>2]|0;K=c[3408+(L<<2)>>2]|0;r=(1285>>>L&1|0)!=0;if(r){o=h+K|0;l=h+(K+1)|0;p=h+(K+2)|0;q=h+(K+3)|0}else{q=(K<<4)+J|0;o=e+(q+-1)|0;l=e+(q+15)|0;p=e+(q+31)|0;q=e+(q+47)|0}A=a[o>>0]|0;y=a[l>>0]|0;F=a[p>>0]|0;E=a[q>>0]|0;do if(!(51>>>L&1)){x=K+-1|0;w=(x<<4)+J|0;o=a[e+w>>0]|0;q=a[e+(w+1)>>0]|0;s=a[e+(w+2)>>0]|0;u=a[e+(w+3)>>0]|0;t=a[e+(w+4)>>0]|0;l=a[e+(w+5)>>0]|0;v=a[e+(w+6)>>0]|0;p=a[e+(w+7)>>0]|0;if(r){D=v;C=u;u=p;B=q;z=s;v=h+x|0;break}else{D=v;C=u;u=p;B=q;z=s;v=e+(w+-1)|0;break}}else{D=a[g+(J+7)>>0]|0;C=a[g+(J+4)>>0]|0;t=a[g+(J+5)>>0]|0;l=a[g+(J+6)>>0]|0;o=a[g+(J+1)>>0]|0;u=a[g+(J+8)>>0]|0;B=a[g+(J+2)>>0]|0;z=a[g+(J+3)>>0]|0;v=g+J|0}while(0);v=a[v>>0]|0;switch(j|0){case 4:{if(!(I&(n|0)!=0)){k=1;j=51;break a}j=o&255;o=v&255;q=A&255;s=j+2|0;D=(s+q+(o<<1)|0)>>>2;u=D&255;k=B&255;o=o+2|0;v=((j<<1)+k+o|0)>>>2&255;j=z&255;s=((k<<1)+j+s|0)>>>2&255;z=y&255;o=(z+(q<<1)+o|0)>>>2;t=o&255;A=F&255;B=(q+2+(z<<1)+A|0)>>>2;q=u;p=t;n=B&255;m=v;l=s;j=((C&255)+2+k+(j<<1)|0)>>>2&255;k=u;r=v;o=(z+2+(A<<1)+(E&255)|0)>>>2&255|B<<8&65280|D<<24|o<<16&16711680;break}case 6:{if(!(I&(n|0)!=0)){k=1;j=51;break a}l=v&255;s=A&255;u=s+1|0;r=(u+l|0)>>>1&255;C=y&255;v=((s<<1)+2+C+l|0)>>>2&255;u=(u+C|0)>>>1&255;D=F&255;s=s+2|0;y=(s+(C<<1)+D|0)>>>2;A=(C+1+D|0)>>>1;E=E&255;j=o&255;s=(s+j+(l<<1)|0)>>>2&255;k=B&255;q=r;p=u;n=A&255;m=s;l=(k+2+(j<<1)+l|0)>>>2&255;j=((z&255)+2+(k<<1)+j|0)>>>2&255;k=v;t=y&255;o=y<<24|A<<16&16711680|(D+1+E|0)>>>1&255|C+2+(D<<1)+E<<6&65280;break}case 2:{do if(!I){if(G){j=((A&255)+2+(y&255)+(F&255)+(E&255)|0)>>>2;break}if(H)j=((C&255)+2+(z&255)+(B&255)+(o&255)|0)>>>2;else j=128}else j=((A&255)+4+(y&255)+(F&255)+(E&255)+(C&255)+(z&255)+(B&255)+(o&255)|0)>>>3;while(0);o=Z(j&255,16843009)|0;n=o&255;t=o>>>8&255;u=o>>>16&255;v=o>>>24&255;q=n;p=n;m=t;l=u;j=v;k=t;r=u;s=v;break}case 0:{if(!k){k=1;j=51;break a}q=o;p=o;n=o;m=B;l=z;j=C;k=B;r=z;s=C;t=B;u=z;v=C;o=(z&255)<<16|(C&255)<<24|(B&255)<<8|o&255;break}case 1:{if(!G){k=1;j=51;break a}j=Z(A&255,16843009)|0;s=Z(y&255,16843009)|0;v=Z(F&255,16843009)|0;q=j&255;p=s&255;n=v&255;m=j>>>8&255;l=j>>>16&255;j=j>>>24&255;k=s>>>8&255;r=s>>>16&255;s=s>>>24&255;t=v>>>8&255;u=v>>>16&255;v=v>>>24&255;o=Z(E&255,16843009)|0;break}case 7:{if(!k){k=1;j=51;break a}A=(m|0)==0;n=o&255;p=B&255;z=z&255;m=(z+1+p|0)>>>1&255;o=C&255;u=o+1|0;v=(u+z|0)>>>1&255;B=(A?C:t)&255;u=(u+B|0)>>>1&255;j=z+2|0;y=o+2|0;z=(y+p+(z<<1)|0)>>>2;o=(j+(o<<1)+B|0)>>>2;E=(A?C:l)&255;y=(y+E+(B<<1)|0)>>>2;q=(p+1+n|0)>>>1&255;p=(j+n+(p<<1)|0)>>>2&255;n=m;l=v;j=u;k=z&255;r=o&255;s=y&255;t=v;v=(B+1+E|0)>>>1&255;o=y<<16&16711680|z&255|(B+2+((A?C:D)&255)+(E<<1)|0)>>>2<<24|o<<8&65280;break}case 3:{if(!k){k=1;j=51;break a}n=(m|0)==0;q=B&255;m=z&255;p=m+2|0;k=C&255;B=k+2|0;m=(B+q+(m<<1)|0)>>>2&255;v=(n?C:t)&255;k=(p+(k<<1)+v|0)>>>2&255;E=(n?C:l)&255;B=(B+E+(v<<1)|0)>>>2;t=B&255;A=(n?C:D)&255;D=(v+2+A+(E<<1)|0)>>>2;v=D&255;C=(n?C:u)&255;E=(E+2+C+(A<<1)|0)>>>2;q=(p+(o&255)+(q<<1)|0)>>>2&255;p=m;n=k;l=k;j=t;r=t;s=v;u=v;v=E&255;o=(A+2+(C*3|0)|0)>>>2<<24|B&255|D<<8&65280|E<<16&16711680;break}case 5:{if(!(I&(n|0)!=0)){k=1;j=51;break a}n=v&255;u=o&255;t=(u+1+n|0)>>>1&255;x=B&255;E=(x+2+(u<<1)+n|0)>>>2;B=A&255;A=u+2|0;o=(A+B+(n<<1)|0)>>>2;u=(x+1+u|0)>>>1&255;s=z&255;A=((x<<1)+s+A|0)>>>2;v=(s+1+x|0)>>>1&255;C=C&255;D=y&255;q=t;p=o&255;n=(D+2+(B<<1)+n|0)>>>2&255;m=u;l=v;j=(C+1+s|0)>>>1&255;k=E&255;r=A&255;s=(C+2+x+(s<<1)|0)>>>2&255;o=A<<24|(B+2+(F&255)+(D<<1)|0)>>>2&255|E<<16&16711680|o<<8&65280;break}default:{if(!G){k=1;j=51;break a}s=A&255;j=y&255;m=F&255;l=(j+1+m|0)>>>1&255;o=E&255;k=(j+2+(m<<1)+o|0)>>>2&255;r=(m+1+o|0)>>>1&255;t=(m+2+(o*3|0)|0)>>>2&255;q=(s+1+j|0)>>>1&255;p=l;n=r;m=(s+2+(j<<1)+m|0)>>>2&255;j=k;s=t;u=E;v=E;o=o<<8|o|o<<16|o<<24}}E=(K<<4)+J|0;c[e+E>>2]=(l&255)<<16|(j&255)<<24|(m&255)<<8|q&255;c[e+(E+16)>>2]=(r&255)<<16|(s&255)<<24|(k&255)<<8|p&255;c[e+(E+32)>>2]=(u&255)<<16|(v&255)<<24|(t&255)<<8|n&255;c[e+(E+48)>>2]=o;Rb(e,f+(L<<6)+328|0,L);L=L+1|0;if(L>>>0>=16){k=0;j=51;break}}if((j|0)==51){i=N;return k|0}return 0}function Qb(b,e,f,g,h,j,k){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var 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;y=i;m=b+200|0;l=zb(b,c[m>>2]|0)|0;n=(k|0)!=0;if((l|0)!=0&n){o=(cb(c[c[m>>2]>>2]|0)|0)==2;l=o?0:l}m=b+204|0;k=zb(b,c[m>>2]|0)|0;if((k|0)!=0&n){o=(cb(c[c[m>>2]>>2]|0)|0)==2;o=o?0:k}else o=k;m=b+212|0;k=zb(b,c[m>>2]|0)|0;if((k|0)!=0&n){n=(cb(c[c[m>>2]>>2]|0)|0)==2;k=n?0:k}w=(l|0)!=0;x=(o|0)!=0;v=w&x;u=v&(k|0)!=0;t=(l|0)==0;s=(o|0)==0;p=g;q=16;r=0;while(1){if((j|0)==1){if(t){l=1;k=29;break}else{n=e;b=8;m=h}while(1){b=b+-1|0;a[n>>0]=a[m>>0]|0;a[n+1>>0]=a[m>>0]|0;a[n+2>>0]=a[m>>0]|0;a[n+3>>0]=a[m>>0]|0;a[n+4>>0]=a[m>>0]|0;a[n+5>>0]=a[m>>0]|0;a[n+6>>0]=a[m>>0]|0;a[n+7>>0]=a[m>>0]|0;if(!b)break;else{n=n+8|0;m=m+1|0}}}else if((j|0)==2){if(s){l=1;k=29;break}else{n=p;b=e;m=8}while(1){n=n+1|0;m=m+-1|0;a[b>>0]=a[n>>0]|0;a[b+8>>0]=a[n>>0]|0;a[b+16>>0]=a[n>>0]|0;a[b+24>>0]=a[n>>0]|0;a[b+32>>0]=a[n>>0]|0;a[b+40>>0]=a[n>>0]|0;a[b+48>>0]=a[n>>0]|0;a[b+56>>0]=a[n>>0]|0;if(!m)break;else b=b+1|0}}else if(!j){m=p+1|0;do if(!v){if(x){n=((d[m>>0]|0)+2+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)|0)>>>2;b=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2;break}if(w){b=((d[h>>0]|0)+2+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)|0)>>>2;n=b}else{n=128;b=128}}else{n=((d[m>>0]|0)+4+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)+(d[h>>0]|0)+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)|0)>>>3;b=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2}while(0);n=n&255;o=b&255;nd(e|0,n|0,4)|0;nd(e+4|0,o|0,4)|0;nd(e+8|0,n|0,4)|0;nd(e+12|0,o|0,4)|0;nd(e+16|0,n|0,4)|0;nd(e+20|0,o|0,4)|0;g=e+32|0;nd(e+24|0,n|0,4)|0;nd(e+28|0,o|0,4)|0;if(w){o=d[h+4>>0]|0;n=d[h+5>>0]|0;b=d[h+6>>0]|0;m=d[h+7>>0]|0;k=(o+2+n+b+m|0)>>>2;if(x){l=k;n=(o+4+n+b+m+(d[p+5>>0]|0)+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>3}else{l=k;n=k}}else if(x){l=((d[m>>0]|0)+2+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)|0)>>>2;n=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2}else{l=128;n=128}b=l&255;o=n&255;nd(g|0,b|0,4)|0;nd(e+36|0,o|0,4)|0;nd(e+40|0,b|0,4)|0;nd(e+44|0,o|0,4)|0;nd(e+48|0,b|0,4)|0;nd(e+52|0,o|0,4)|0;nd(e+56|0,b|0,4)|0;nd(e+60|0,o|0,4)|0}else{if(!u){l=1;k=29;break}n=d[p+8>>0]|0;b=d[h+7>>0]|0;l=d[p>>0]|0;k=(((d[p+5>>0]|0)-(d[p+3>>0]|0)+((d[p+6>>0]|0)-(d[p+2>>0]|0)<<1)+(((d[p+7>>0]|0)-(d[p+1>>0]|0)|0)*3|0)+(n-l<<2)|0)*17|0)+16>>5;l=(((d[h+4>>0]|0)-(d[h+2>>0]|0)+(b-l<<2)+((d[h+5>>0]|0)-(d[h+1>>0]|0)<<1)+(((d[h+6>>0]|0)-(d[h>>0]|0)|0)*3|0)|0)*17|0)+16>>5;o=Z(k,-3)|0;n=(b+n<<4)+16+(Z(l,-3)|0)|0;b=e;m=8;while(1){m=m+-1|0;g=n+o|0;a[b>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+1>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+2>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+3>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+4>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+5>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+6>>0]=a[(g>>5)+3984>>0]|0;a[b+7>>0]=a[(g+k>>5)+3984>>0]|0;if(!m)break;else{n=n+l|0;b=b+8|0}}}Rb(e,f,q);g=q|1;Rb(e,f+64|0,g);Rb(e,f+128|0,g+1|0);Rb(e,f+192|0,q|3);r=r+1|0;if(r>>>0>=2){l=0;k=29;break}else{p=p+9|0;q=q+4|0;e=e+64|0;h=h+8|0;f=f+256|0}}if((k|0)==29){i=y;return l|0}return 0}function Rb(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;h=i;g=c[e>>2]|0;if((g|0)==16777215){i=h;return}m=f>>>0<16;l=m?16:8;m=m?f:f&3;m=(Z(c[3408+(m<<2)>>2]|0,l)|0)+(c[3344+(m<<2)>>2]|0)|0;n=b+m|0;p=c[e+4>>2]|0;j=b+(m+1)|0;f=d[j>>0]|0;a[n>>0]=a[3472+(g+512+(d[n>>0]|0))>>0]|0;n=c[e+8>>2]|0;k=b+(m+2)|0;o=d[k>>0]|0;a[j>>0]=a[3472+(p+512+f)>>0]|0;g=b+(m+3)|0;j=a[3472+((c[e+12>>2]|0)+512+(d[g>>0]|0))>>0]|0;a[k>>0]=a[3472+(n+512+o)>>0]|0;a[g>>0]=j;g=m+l|0;m=b+g|0;j=c[e+20>>2]|0;k=b+(g+1)|0;o=d[k>>0]|0;a[m>>0]=a[3472+((c[e+16>>2]|0)+512+(d[m>>0]|0))>>0]|0;m=c[e+24>>2]|0;n=b+(g+2)|0;f=d[n>>0]|0;a[k>>0]=a[3472+(j+512+o)>>0]|0;k=b+(g+3)|0;o=a[3472+((c[e+28>>2]|0)+512+(d[k>>0]|0))>>0]|0;a[n>>0]=a[3472+(m+512+f)>>0]|0;a[k>>0]=o;g=g+l|0;k=b+g|0;o=c[e+36>>2]|0;n=b+(g+1)|0;f=d[n>>0]|0;a[k>>0]=a[3472+((c[e+32>>2]|0)+512+(d[k>>0]|0))>>0]|0;k=c[e+40>>2]|0;m=b+(g+2)|0;j=d[m>>0]|0;a[n>>0]=a[3472+(o+512+f)>>0]|0;n=b+(g+3)|0;f=a[3472+((c[e+44>>2]|0)+512+(d[n>>0]|0))>>0]|0;a[m>>0]=a[3472+(k+512+j)>>0]|0;a[n>>0]=f;g=g+l|0;l=b+g|0;n=c[e+52>>2]|0;f=b+(g+1)|0;m=d[f>>0]|0;a[l>>0]=a[3472+((c[e+48>>2]|0)+512+(d[l>>0]|0))>>0]|0;l=c[e+56>>2]|0;j=b+(g+2)|0;k=d[j>>0]|0;a[f>>0]=a[3472+(n+512+m)>>0]|0;g=b+(g+3)|0;f=a[3472+((c[e+60>>2]|0)+512+(d[g>>0]|0))>>0]|0;a[j>>0]=a[3472+(l+512+k)>>0]|0;a[g>>0]=f;i=h;return} +function yc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;q=i;l=b+-1|0;k=a[b+1>>0]|0;m=d[l>>0]|0;n=d[b>>0]|0;r=m-n|0;p=f+4|0;do if((((r|0)>-1?r:0-r|0)>>>0<(c[p>>2]|0)>>>0?(o=d[b+-2>>0]|0,r=o-m|0,j=c[f+8>>2]|0,((r|0)>-1?r:0-r|0)>>>0>>0):0)?(h=k&255,k=h-n|0,((k|0)>-1?k:0-k|0)>>>0>>0):0)if(e>>>0<4){k=d[(c[f>>2]|0)+(e+-1)>>0]|0;k=Oa(~k,k+1|0,4-h+(n-m<<2)+o>>3)|0;o=a[3472+((n|512)-k)>>0]|0;a[l>>0]=a[3472+((m|512)+k)>>0]|0;a[b>>0]=o;break}else{a[l>>0]=(m+2+h+(o<<1)|0)>>>2;a[b>>0]=(n+2+(h<<1)+o|0)>>>2;break}while(0);l=b+g|0;m=b+(g+-1)|0;o=d[m>>0]|0;n=d[l>>0]|0;k=o-n|0;if(((k|0)>-1?k:0-k|0)>>>0>=(c[p>>2]|0)>>>0){i=q;return}k=d[b+(g+-2)>>0]|0;p=k-o|0;j=c[f+8>>2]|0;if(((p|0)>-1?p:0-p|0)>>>0>=j>>>0){i=q;return}h=d[b+(g+1)>>0]|0;g=h-n|0;if(((g|0)>-1?g:0-g|0)>>>0>=j>>>0){i=q;return}if(e>>>0<4){b=d[(c[f>>2]|0)+(e+-1)>>0]|0;b=Oa(~b,b+1|0,4-h+(n-o<<2)+k>>3)|0;g=a[3472+((n|512)-b)>>0]|0;a[m>>0]=a[3472+((o|512)+b)>>0]|0;a[l>>0]=g;i=q;return}else{a[m>>0]=(o+2+h+(k<<1)|0)>>>2;a[l>>0]=(n+2+(h<<1)+k|0)>>>2;i=q;return}}function zc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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;v=i;if(e>>>0<4){n=d[(c[f>>2]|0)+(e+-1)>>0]|0;h=n+1|0;q=0-g|0;e=f+4|0;p=q<<1;o=f+8|0;n=~n;j=8;while(1){m=b+q|0;f=a[b+g>>0]|0;l=d[m>>0]|0;k=d[b>>0]|0;r=l-k|0;if((((r|0)>-1?r:0-r|0)>>>0<(c[e>>2]|0)>>>0?(t=d[b+p>>0]|0,r=t-l|0,s=c[o>>2]|0,((r|0)>-1?r:0-r|0)>>>0>>0):0)?(u=f&255,f=u-k|0,((f|0)>-1?f:0-f|0)>>>0>>0):0){r=Oa(n,h,4-u+(k-l<<2)+t>>3)|0;f=a[3472+((k|512)-r)>>0]|0;a[m>>0]=a[3472+((l|512)+r)>>0]|0;a[b>>0]=f}j=j+-1|0;if(!j)break;else b=b+1|0}i=v;return}else{o=0-g|0;m=f+4|0;n=o<<1;f=f+8|0;l=8;while(1){h=b+o|0;e=a[b+g>>0]|0;j=d[h>>0]|0;k=d[b>>0]|0;s=j-k|0;if((((s|0)>-1?s:0-s|0)>>>0<(c[m>>2]|0)>>>0?(p=d[b+n>>0]|0,s=p-j|0,q=c[f>>2]|0,((s|0)>-1?s:0-s|0)>>>0>>0):0)?(r=e&255,e=r-k|0,((e|0)>-1?e:0-e|0)>>>0>>0):0){a[h>>0]=(j+2+r+(p<<1)|0)>>>2;a[b>>0]=(k+2+(r<<1)+p|0)>>>2}l=l+-1|0;if(!l)break;else b=b+1|0}i=v;return}}function Ac(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=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=i;r=d[(c[f>>2]|0)+(e+-1)>>0]|0;s=r+1|0;l=0-g|0;h=f+4|0;q=l<<1;e=f+8|0;r=~r;l=b+l|0;m=a[b+g>>0]|0;k=d[l>>0]|0;j=d[b>>0]|0;u=k-j|0;f=c[h>>2]|0;if((((u|0)>-1?u:0-u|0)>>>0>>0?(o=d[b+q>>0]|0,u=o-k|0,n=c[e>>2]|0,((u|0)>-1?u:0-u|0)>>>0>>0):0)?(p=m&255,m=p-j|0,((m|0)>-1?m:0-m|0)>>>0>>0):0){p=Oa(r,s,4-p+(j-k<<2)+o>>3)|0;f=a[3472+((j|512)-p)>>0]|0;a[l>>0]=a[3472+((k|512)+p)>>0]|0;a[b>>0]=f;f=c[h>>2]|0}m=b+1|0;j=b+(1-g)|0;k=d[j>>0]|0;l=d[m>>0]|0;p=k-l|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}h=d[b+(q|1)>>0]|0;p=h-k|0;f=c[e>>2]|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}e=d[b+(g+1)>>0]|0;p=e-l|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}o=Oa(r,s,4-e+(l-k<<2)+h>>3)|0;p=a[3472+((l|512)-o)>>0]|0;a[j>>0]=a[3472+((k|512)+o)>>0]|0;a[m>>0]=p;i=t;return}function Bc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;p=c[b+4>>2]|0;q=c[b+8>>2]|0;if(!((d|0)==0|(d|0)==5)?(c[a+3384>>2]|0)==0:0)f=0;else{g=a+1220|0;e=0;do{f=ic(g,e)|0;e=e+1|0}while(e>>>0<16&(f|0)==0)}l=a+1176|0;n=c[l>>2]|0;if(n){m=c[a+1212>>2]|0;e=0;j=0;g=0;do{if(c[m+(j*216|0)+196>>2]|0)break;j=j+1|0;e=e+1|0;o=(e|0)==(p|0);g=(o&1)+g|0;e=o?0:e}while(j>>>0>>0);if((j|0)!=(n|0)){o=a+1212|0;n=c[o>>2]|0;j=Z(g,p)|0;if(e){l=a+1204|0;h=e;do{h=h+-1|0;m=h+j|0;Cc(n+(m*216|0)|0,b,g,h,d,f);c[n+(m*216|0)+196>>2]=1;c[l>>2]=(c[l>>2]|0)+1}while((h|0)!=0)}e=e+1|0;if(e>>>0

>>0){m=a+1204|0;do{l=e+j|0;k=n+(l*216|0)+196|0;if(!(c[k>>2]|0)){Cc(n+(l*216|0)|0,b,g,e,d,f);c[k>>2]=1;c[m>>2]=(c[m>>2]|0)+1}e=e+1|0}while((e|0)!=(p|0))}if(g){if(p){n=g+-1|0;h=Z(n,p)|0;e=a+1204|0;l=0-p|0;k=0;do{m=n;j=(c[o>>2]|0)+((k+h|0)*216|0)|0;while(1){Cc(j,b,m,k,d,f);c[j+196>>2]=1;c[e>>2]=(c[e>>2]|0)+1;if(!m)break;else{m=m+-1|0;j=j+(l*216|0)|0}}k=k+1|0}while((k|0)!=(p|0))}}else g=0;g=g+1|0;if(g>>>0>=q>>>0){i=r;return 0}m=a+1204|0;if(!p){i=r;return 0}do{e=c[o>>2]|0;l=Z(g,p)|0;k=0;do{h=k+l|0;j=e+(h*216|0)+196|0;if(!(c[j>>2]|0)){Cc(e+(h*216|0)|0,b,g,k,d,f);c[j>>2]=1;c[m>>2]=(c[m>>2]|0)+1}k=k+1|0}while((k|0)!=(p|0));g=g+1|0}while((g|0)!=(q|0));i=r;return 0}}if((d|0)==2|(d|0)==7)if((c[a+3384>>2]|0)==0|(f|0)==0)g=13;else g=14;else if(!f)g=13;else g=14;if((g|0)==13)id(c[b>>2]|0,128,Z(p*384|0,q)|0);else if((g|0)==14)hd(c[b>>2]|0,f,Z(p*384|0,q)|0);g=c[l>>2]|0;c[a+1204>>2]=g;if(!g){i=r;return 0}e=c[a+1212>>2]|0;f=0;do{c[e+(f*216|0)+8>>2]=1;f=f+1|0}while(f>>>0>>0);i=r;return 0}function Cc(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var 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,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,_=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;sa=i;i=i+480|0;qa=sa+96|0;ra=sa+32|0;m=sa+24|0;n=sa;na=c[e+4>>2]|0;u=c[e+8>>2]|0;Na(e,(Z(na,f)|0)+g|0);p=c[e>>2]|0;k=f<<4;l=g<<4;o=(Z(f<<8,na)|0)+l|0;c[b+20>>2]=40;c[b+8>>2]=0;c[b>>2]=6;c[b+12>>2]=0;c[b+16>>2]=0;c[b+24>>2]=0;do if((h|0)==2|(h|0)==7)id(qa,0,384);else{c[m>>2]=0;c[n+4>>2]=na;c[n+8>>2]=u;c[n>>2]=j;if(!j){id(qa,0,384);break}dc(qa,m,n,l,k,0,0,16,16);sc(e,qa);i=sa;return}while(0);id(ra,0,64);if((f|0)!=0?(c[b+((0-na|0)*216|0)+196>>2]|0)!=0:0){v=o-(na<<4)|0;E=v|1;D=v|3;E=(d[p+E>>0]|0)+(d[p+v>>0]|0)+(d[p+(E+1)>>0]|0)+(d[p+D>>0]|0)|0;$=v|7;D=(d[p+(D+2)>>0]|0)+(d[p+(D+1)>>0]|0)+(d[p+(D+3)>>0]|0)+(d[p+$>>0]|0)|0;F=(d[p+($+2)>>0]|0)+(d[p+($+1)>>0]|0)+(d[p+($+3)>>0]|0)+(d[p+($+4)>>0]|0)|0;v=(d[p+($+6)>>0]|0)+(d[p+($+5)>>0]|0)+(d[p+($+7)>>0]|0)+(d[p+(v|15)>>0]|0)|0;$=D+E|0;c[ra>>2]=F+$+(c[ra>>2]|0)+v;s=ra+4|0;c[s>>2]=$-F-v+(c[s>>2]|0);s=1}else{E=0;D=0;F=0;v=0;s=0}if((u+-1|0)!=(f|0)?(c[b+(na*216|0)+196>>2]|0)!=0:0){z=o+(na<<8)|0;w=z|1;x=z|3;w=(d[p+w>>0]|0)+(d[p+z>>0]|0)+(d[p+(w+1)>>0]|0)+(d[p+x>>0]|0)|0;r=z|7;x=(d[p+(x+2)>>0]|0)+(d[p+(x+1)>>0]|0)+(d[p+(x+3)>>0]|0)+(d[p+r>>0]|0)|0;y=(d[p+(r+2)>>0]|0)+(d[p+(r+1)>>0]|0)+(d[p+(r+3)>>0]|0)+(d[p+(r+4)>>0]|0)|0;z=(d[p+(r+6)>>0]|0)+(d[p+(r+5)>>0]|0)+(d[p+(r+7)>>0]|0)+(d[p+(z|15)>>0]|0)|0;r=x+w|0;c[ra>>2]=y+r+(c[ra>>2]|0)+z;t=ra+4|0;c[t>>2]=r-y-z+(c[t>>2]|0);t=1;r=s+1|0}else{t=0;w=0;x=0;y=0;z=0;r=s}if((g|0)!=0?(c[b+-20>>2]|0)!=0:0){_=o+-1|0;$=na<<4;j=na<<5;ma=na*48|0;C=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;h=na<<6;_=_+h|0;B=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;_=_+h|0;A=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;h=_+h|0;ma=(d[p+(h+$)>>0]|0)+(d[p+h>>0]|0)+(d[p+(h+j)>>0]|0)+(d[p+(h+ma)>>0]|0)|0;h=B+C|0;c[ra>>2]=A+h+(c[ra>>2]|0)+ma;j=ra+16|0;c[j>>2]=h-A-ma+(c[j>>2]|0);j=r+1|0;h=1}else{j=r;C=0;B=0;A=0;ma=0;h=0}do if((na+-1|0)!=(g|0)?(c[b+412>>2]|0)!=0:0){$=o+16|0;n=na<<4;m=na<<5;o=na*48|0;b=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;q=na<<6;$=$+q|0;l=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;$=$+q|0;k=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;q=$+q|0;o=(d[p+(q+n)>>0]|0)+(d[p+q>>0]|0)+(d[p+(q+m)>>0]|0)+(d[p+(q+o)>>0]|0)|0;p=j+1|0;q=h+1|0;j=l+b|0;c[ra>>2]=k+j+(c[ra>>2]|0)+o;m=ra+16|0;j=j-k-o+(c[m>>2]|0)|0;c[m>>2]=j;m=(r|0)==0;n=(h|0)!=0;if(!(m&n)){if(!m){m=1;j=p;h=q;l=21;break}}else c[ra+4>>2]=A+ma+B+C-b-l-k-o>>5;m=1;o=(s|0)!=0;b=(t|0)!=0;h=q;l=27}else l=17;while(0);if((l|0)==17){n=(h|0)!=0;if(!r){m=0;p=j;l=23}else{m=0;l=21}}if((l|0)==21){p=ra+4|0;c[p>>2]=c[p>>2]>>r+3;p=j;l=23}do if((l|0)==23){j=(h|0)==0;o=(s|0)!=0;b=(t|0)!=0;if(j&o&b){c[ra+16>>2]=F+v+D+E-z-y-x-w>>5;pa=m;h=p;oa=n;o=1;b=1;break}if(j){pa=m;h=p;oa=n}else{j=c[ra+16>>2]|0;l=27}}while(0);if((l|0)==27){c[ra+16>>2]=j>>h+3;pa=m;h=p;oa=n}if((h|0)==1)c[ra>>2]=c[ra>>2]>>4;else if((h|0)==2)c[ra>>2]=c[ra>>2]>>5;else if((h|0)==3)c[ra>>2]=(c[ra>>2]|0)*21>>10;else c[ra>>2]=c[ra>>2]>>6;Dc(ra);n=0;j=qa;m=ra;while(1){h=c[m+((n>>>2&3)<<2)>>2]|0;if((h|0)<0)h=0;else h=(h|0)>255?-1:h&255;a[j>>0]=h;h=n+1|0;if((h|0)==256)break;else{n=h;j=j+1|0;m=(h&63|0)==0?m+16|0:m}}ta=Z(u,na)|0;V=na<<3;Y=0-V|0;G=Y|1;_=G+1|0;$=Y|3;aa=$+1|0;ba=$+2|0;ca=$+3|0;da=Y|7;W=ra+4|0;ka=na<<6;H=ka|1;ea=H+1|0;fa=ka|3;ga=fa+1|0;ha=fa+2|0;ia=fa+3|0;ja=ka|7;I=V+-1|0;U=na<<4;J=U+-1|0;K=J+V|0;L=J+U|0;M=L+V|0;N=L+U|0;O=N+V|0;X=ra+16|0;P=V+8|0;Q=U|8;R=Q+V|0;S=Q+U|0;T=S+V|0;U=S+U|0;V=U+V|0;la=ta<<6;q=E;p=D;h=F;t=v;n=w;j=x;l=y;u=z;F=0;m=C;k=B;r=A;s=ma;E=(c[e>>2]|0)+((Z(f<<6,na)|0)+(g<<3)+(ta<<8))|0;while(1){id(ra,0,64);if(o){q=(d[E+G>>0]|0)+(d[E+Y>>0]|0)|0;p=(d[E+$>>0]|0)+(d[E+_>>0]|0)|0;z=(d[E+ba>>0]|0)+(d[E+aa>>0]|0)|0;A=(d[E+da>>0]|0)+(d[E+ca>>0]|0)|0;t=p+q|0;c[ra>>2]=z+t+(c[ra>>2]|0)+A;c[W>>2]=t-z-A+(c[W>>2]|0);t=1}else{z=h;A=t;t=0}if(b){B=(d[E+H>>0]|0)+(d[E+ka>>0]|0)|0;C=(d[E+fa>>0]|0)+(d[E+ea>>0]|0)|0;D=(d[E+ha>>0]|0)+(d[E+ga>>0]|0)|0;u=(d[E+ja>>0]|0)+(d[E+ia>>0]|0)|0;h=C+B|0;c[ra>>2]=D+h+(c[ra>>2]|0)+u;c[W>>2]=h-D-u+(c[W>>2]|0);h=t+1|0}else{B=n;C=j;D=l;h=t}if(oa){v=(d[E+I>>0]|0)+(d[E+-1>>0]|0)|0;w=(d[E+K>>0]|0)+(d[E+J>>0]|0)|0;x=(d[E+M>>0]|0)+(d[E+L>>0]|0)|0;y=(d[E+O>>0]|0)+(d[E+N>>0]|0)|0;t=w+v|0;c[ra>>2]=x+t+(c[ra>>2]|0)+y;c[X>>2]=t-x-y+(c[X>>2]|0);t=h+1|0;s=1}else{t=h;v=m;w=k;x=r;y=s;s=0}do if(pa){l=(d[E+P>>0]|0)+(d[E+8>>0]|0)|0;m=(d[E+R>>0]|0)+(d[E+Q>>0]|0)|0;j=(d[E+T>>0]|0)+(d[E+S>>0]|0)|0;n=(d[E+V>>0]|0)+(d[E+U>>0]|0)|0;t=t+1|0;s=s+1|0;k=m+l|0;c[ra>>2]=j+k+(c[ra>>2]|0)+n;k=k-j-n+(c[X>>2]|0)|0;c[X>>2]=k;r=(h|0)==0;if(!(r&oa))if(r){l=54;break}else{l=49;break}else{c[W>>2]=x+y+w+v-l-m-j-n>>4;l=54;break}}else if(!h){r=s;l=50}else l=49;while(0);if((l|0)==49){c[W>>2]=c[W>>2]>>h+2;r=s;l=50}do if((l|0)==50){l=0;s=(r|0)==0;if(s&o&b){c[X>>2]=z+A+p+q-u-D-C-B>>4;break}if(!s){k=c[X>>2]|0;s=r;l=54}}while(0);if((l|0)==54)c[X>>2]=k>>s+2;if((t|0)==1)c[ra>>2]=c[ra>>2]>>3;else if((t|0)==2)c[ra>>2]=c[ra>>2]>>4;else if((t|0)==3)c[ra>>2]=(c[ra>>2]|0)*21>>9;else c[ra>>2]=c[ra>>2]>>5;Dc(ra);s=0;r=qa+((F<<6)+256)|0;k=ra;while(1){t=c[k+((s>>>1&3)<<2)>>2]|0;if((t|0)<0)t=0;else t=(t|0)>255?-1:t&255;a[r>>0]=t;t=s+1|0;if((t|0)==64)break;else{s=t;r=r+1|0;k=(t&15|0)==0?k+16|0:k}}F=F+1|0;if((F|0)==2)break;else{h=z;t=A;n=B;j=C;l=D;m=v;k=w;r=x;s=y;E=E+la|0}}sc(e,qa);i=sa;return}function Dc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;h=i;f=a+4|0;b=c[f>>2]|0;g=a+16|0;d=c[g>>2]|0;e=c[a>>2]|0;if(!(b|d)){c[a+60>>2]=e;c[a+56>>2]=e;c[a+52>>2]=e;c[a+48>>2]=e;c[a+44>>2]=e;c[a+40>>2]=e;c[a+36>>2]=e;c[a+32>>2]=e;c[a+28>>2]=e;c[a+24>>2]=e;c[a+20>>2]=e;c[g>>2]=e;c[a+12>>2]=e;c[a+8>>2]=e;c[f>>2]=e;i=h;return}else{k=b+e|0;g=b>>1;j=g+e|0;g=e-g|0;b=e-b|0;c[a>>2]=d+k;e=d>>1;c[a+16>>2]=e+k;c[a+32>>2]=k-e;c[a+48>>2]=k-d;c[f>>2]=d+j;c[a+20>>2]=e+j;c[a+36>>2]=j-e;c[a+52>>2]=j-d;c[a+8>>2]=d+g;c[a+24>>2]=e+g;c[a+40>>2]=g-e;c[a+56>>2]=g-d;c[a+12>>2]=d+b;c[a+28>>2]=e+b;c[a+44>>2]=b-e;c[a+60>>2]=b-d;i=h;return}}function Ec(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;id(b,0,952);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b>>2]=d&1;do if(d){d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+4>>2]=d;if((d|0)==255){d=jb(a,16)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+8>>2]=d;d=jb(a,16)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+12>>2]=d;break}}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+16>>2]=d&1;do if(d){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+20>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+24>>2]=d&1;do if(d){d=jb(a,3)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+28>>2]=d;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+32>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+36>>2]=d&1;if(!d){c[b+40>>2]=2;c[b+44>>2]=2;c[b+48>>2]=2;break}d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+40>>2]=d;d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+44>>2]=d;d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+48>>2]=d;break}}else{c[b+28>>2]=5;c[b+40>>2]=2;c[b+44>>2]=2;c[b+48>>2]=2}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+52>>2]=d&1;if(d){d=b+56|0;e=nb(a,d)|0;if(e){d=e;i=h;return d|0}if((c[d>>2]|0)>>>0>5){d=1;i=h;return d|0}d=b+60|0;e=nb(a,d)|0;if(e){d=e;i=h;return d|0}if((c[d>>2]|0)>>>0>5){d=1;i=h;return d|0}}d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+64>>2]=d&1;do if(d){d=kb(a)|0;if((lb(a,32)|0)==-1|(d|0)==0){d=1;i=h;return d|0}c[b+68>>2]=d;d=kb(a)|0;if((lb(a,32)|0)==-1|(d|0)==0){d=1;i=h;return d|0}c[b+72>>2]=d;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+76>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;f=b+80|0;c[f>>2]=d&1;if(d){e=Fc(a,b+84|0)|0;if(e){d=e;i=h;return d|0}}else{c[b+84>>2]=1;c[b+96>>2]=288000001;c[b+224>>2]=288000001;c[b+480>>2]=24;c[b+484>>2]=24;c[b+488>>2]=24;c[b+492>>2]=24}e=jb(a,1)|0;if((e|0)==-1){d=1;i=h;return d|0}e=(e|0)==1;d=b+496|0;c[d>>2]=e&1;if(e){e=Fc(a,b+500|0)|0;if(e){d=e;i=h;return d|0}}else{c[b+500>>2]=1;c[b+512>>2]=240000001;c[b+640>>2]=240000001;c[b+896>>2]=24;c[b+900>>2]=24;c[b+904>>2]=24;c[b+908>>2]=24}if(!((c[f>>2]|0)==0?(c[d>>2]|0)==0:0))g=46;do if((g|0)==46){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+912>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+916>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+920>>2]=d&1;do if(d){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+924>>2]=(d|0)==1&1;e=b+928|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+932|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+936|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+940|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}d=nb(a,b+944|0)|0;if(d){i=h;return d|0}d=nb(a,b+948|0)|0;if(!d)break;i=h;return d|0}else{c[b+924>>2]=1;c[b+928>>2]=2;c[b+932>>2]=1;c[b+936>>2]=16;c[b+940>>2]=16;c[b+944>>2]=16;c[b+948>>2]=16}while(0);d=0;i=h;return d|0}function Fc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;d=nb(a,b)|0;if(d){i=k;return d|0}d=(c[b>>2]|0)+1|0;c[b>>2]=d;if(d>>>0>32){d=1;i=k;return d|0}d=jb(a,4)|0;if((d|0)==-1){d=1;i=k;return d|0}j=b+4|0;c[j>>2]=d;e=jb(a,4)|0;if((e|0)==-1){d=1;i=k;return d|0}h=b+8|0;c[h>>2]=e;a:do if(c[b>>2]|0){g=0;while(1){f=b+(g<<2)+12|0;d=nb(a,f)|0;if(d){e=17;break}e=c[f>>2]|0;if((e|0)==-1){d=1;e=17;break}d=e+1|0;c[f>>2]=d;c[f>>2]=d<<(c[j>>2]|0)+6;f=b+(g<<2)+140|0;d=nb(a,f)|0;if(d){e=17;break}e=c[f>>2]|0;if((e|0)==-1){d=1;e=17;break}e=e+1|0;c[f>>2]=e;c[f>>2]=e<<(c[h>>2]|0)+4;e=jb(a,1)|0;if((e|0)==-1){d=1;e=17;break}c[b+(g<<2)+268>>2]=(e|0)==1&1;g=g+1|0;if(g>>>0>=(c[b>>2]|0)>>>0)break a}if((e|0)==17){i=k;return d|0}}while(0);d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+396>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+400>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+404>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+408>>2]=d;d=0;i=k;return d|0}function Gc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;a:do if(!(c[d+284>>2]|0))o=0;else{h=0;while(1){j=c[d+(h*20|0)+288>>2]|0;if((j|0)==5){o=1;break a}else if(!j)break;h=h+1|0}o=0}while(0);j=c[b+16>>2]|0;if((j|0)==1){if((c[e>>2]|0)!=5){f=c[a+12>>2]|0;if((c[a+8>>2]|0)>>>0>(c[d+12>>2]|0)>>>0)f=(c[b+12>>2]|0)+f|0}else f=0;m=c[b+36>>2]|0;h=(m|0)==0;if(h)j=0;else j=(c[d+12>>2]|0)+f|0;e=(c[e+4>>2]|0)==0;k=((e&(j|0)!=0)<<31>>31)+j|0;l=(k|0)!=0;if(l){g=k+-1|0;n=(g>>>0)%(m>>>0)|0;g=(g>>>0)/(m>>>0)|0}else{n=0;g=0}if(h)j=0;else{k=c[b+40>>2]|0;j=0;h=0;do{j=(c[k+(h<<2)>>2]|0)+j|0;h=h+1|0}while(h>>>0>>0)}if(l){g=Z(j,g)|0;k=c[b+40>>2]|0;j=0;do{g=(c[k+(j<<2)>>2]|0)+g|0;j=j+1|0}while(j>>>0<=n>>>0)}else g=0;if(e)j=(c[b+28>>2]|0)+g|0;else j=g;g=(c[d+32>>2]|0)+(c[b+32>>2]|0)|0;h=a+12|0;if(!o){b=((g|0)<0?g:0)+j+(c[d+28>>2]|0)|0;c[h>>2]=f;c[a+8>>2]=c[d+12>>2];i=p;return b|0}else{c[h>>2]=0;c[a+8>>2]=0;b=0;i=p;return b|0}}else if(!j){if((c[e>>2]|0)!=5){h=c[a>>2]|0;j=c[d+20>>2]|0;if(h>>>0>j>>>0?(k=c[b+20>>2]|0,(h-j|0)>>>0>=k>>>1>>>0):0){h=(c[a+4>>2]|0)+k|0;k=a}else{k=a;m=11}}else{c[a+4>>2]=0;c[a>>2]=0;j=c[d+20>>2]|0;h=0;k=a;m=11}do if((m|0)==11){if(j>>>0>h>>>0?(g=c[b+20>>2]|0,(j-h|0)>>>0>g>>>1>>>0):0){h=(c[a+4>>2]|0)-g|0;break}h=c[a+4>>2]|0}while(0);if(!(c[e+4>>2]|0)){b=c[d+24>>2]|0;b=j+h+((b|0)<0?b:0)|0;i=p;return b|0}c[a+4>>2]=h;f=c[d+24>>2]|0;g=(f|0)<0;if(!o){c[k>>2]=j;b=j+h+(g?f:0)|0;i=p;return b|0}else{c[a+4>>2]=0;c[k>>2]=g?0-f|0:0;b=0;i=p;return b|0}}else{if((c[e>>2]|0)==5){k=0;g=0;f=a+12|0}else{j=c[d+12>>2]|0;f=a+12|0;h=c[f>>2]|0;if((c[a+8>>2]|0)>>>0>j>>>0)h=(c[b+12>>2]|0)+h|0;k=h;g=(j+h<<1)+(((c[e+4>>2]|0)==0)<<31>>31)|0}if(!o){c[f>>2]=k;c[a+8>>2]=c[d+12>>2];b=g;i=p;return b|0}else{c[f>>2]=0;c[a+8>>2]=0;b=0;i=p;return b|0}}return 0}function Hc(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;Ab(a);e=fd(2112)|0;c[a+3376>>2]=e;if(e)if(!b)b=0;else{c[a+1216>>2]=1;b=0}else b=1;i=d;return b|0}function Ic(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,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;i=i+208|0;l=r+204|0;p=r;g=r+112|0;h=r+40|0;q=r+16|0;j=r+12|0;n=r+8|0;c[j>>2]=0;o=a+3344|0;if((c[o>>2]|0)!=0?(c[a+3348>>2]|0)==(b|0):0){b=a+3356|0;c[q+0>>2]=c[b+0>>2];c[q+4>>2]=c[b+4>>2];c[q+8>>2]=c[b+8>>2];c[q+12>>2]=c[b+12>>2];c[q+4>>2]=c[q>>2];c[q+8>>2]=0;c[q+16>>2]=0;c[f>>2]=c[a+3352>>2]}else k=4;do if((k|0)==4)if(!(Pa(b,d,q,f)|0)){d=a+3356|0;c[d+0>>2]=c[q+0>>2];c[d+4>>2]=c[q+4>>2];c[d+8>>2]=c[q+8>>2];c[d+12>>2]=c[q+12>>2];c[d+16>>2]=c[q+16>>2];c[a+3352>>2]=c[f>>2];c[a+3348>>2]=b;break}else{n=3;i=r;return n|0}while(0);c[o>>2]=0;if(sb(q,p)|0){n=3;i=r;return n|0}if(((c[p>>2]|0)+-1|0)>>>0>11){n=0;i=r;return n|0}b=Ib(q,p,a,j)|0;if(!b){do if(!(c[j>>2]|0))k=19;else{if((c[a+1184>>2]|0)!=0?(c[a+16>>2]|0)!=0:0){if(c[a+3380>>2]|0){n=3;i=r;return n|0}if(!(c[a+1188>>2]|0)){m=a+1220|0;n=a+1336|0;c[n>>2]=jc(m)|0;nc(m);Bc(a,n,0)|0}else Bc(a,a+1336|0,c[a+1372>>2]|0)|0;c[f>>2]=0;c[o>>2]=1;c[a+1180>>2]=0;g=a+1336|0;b=a+1360|0;break}c[a+1188>>2]=0;c[a+1180>>2]=0;k=19}while(0);do if((k|0)==19){b=c[p>>2]|0;if((b|0)==7)if(!(Qa(q,g)|0)){Bb(a,g)|0;n=0;i=r;return n|0}else{n=g+40|0;gd(c[n>>2]|0);c[n>>2]=0;n=g+84|0;gd(c[n>>2]|0);c[n>>2]=0;n=3;i=r;return n|0}else if((b|0)==1|(b|0)==5){k=a+1180|0;if(c[a+1180>>2]|0){n=0;i=r;return n|0}c[a+1184>>2]=1;if(Fb(a)|0){c[a+1204>>2]=0;c[a+1208>>2]=e;Ua(q,l)|0;j=a+8|0;d=c[j>>2]|0;b=Db(a,c[l>>2]|0,(c[p>>2]|0)==5&1)|0;if(b){c[a+4>>2]=256;c[a+12>>2]=0;c[j>>2]=32;c[a+16>>2]=0;c[a+3380>>2]=0;n=(b|0)==65535?5:4;i=r;return n|0}if((d|0)!=(c[j>>2]|0)){d=c[a+16>>2]|0;c[n>>2]=1;b=c[a>>2]|0;if(b>>>0<32)b=c[a+(b<<2)+20>>2]|0;else b=0;c[f>>2]=0;c[o>>2]=1;if((((((c[p>>2]|0)==5?(l=_a(n,q,d,c[a+12>>2]|0,5)|0,(c[n>>2]|l|0)==0):0)?(m=a+1220|0,!((c[a+1276>>2]|0)!=0|(b|0)==0)):0)?(c[b+52>>2]|0)==(c[d+52>>2]|0):0)?(c[b+56>>2]|0)==(c[d+56>>2]|0):0)?(c[b+88>>2]|0)==(c[d+88>>2]|0):0)qc(m);else c[a+1280>>2]=0;c[a>>2]=c[j>>2];n=2;i=r;return n|0}}if(c[a+3380>>2]|0){n=3;i=r;return n|0}h=a+1368|0;j=a+2356|0;b=a+16|0;if(Ta(q,j,c[b>>2]|0,c[a+12>>2]|0,p)|0){n=3;i=r;return n|0}if(!(Fb(a)|0))d=a+1220|0;else{d=a+1220|0;if((c[p>>2]|0)!=5?(oc(d,c[a+2368>>2]|0,(c[p+4>>2]|0)!=0&1,c[(c[b>>2]|0)+48>>2]|0)|0)!=0:0){n=3;i=r;return n|0}c[a+1336>>2]=jc(d)|0}od(h|0,j|0,988)|0;c[a+1188>>2]=1;b=a+1360|0;l=p;m=c[l+4>>2]|0;n=b;c[n>>2]=c[l>>2];c[n+4>>2]=m;Hb(a,c[a+1432>>2]|0);nc(d);if(gc(d,a+1436|0,c[a+1380>>2]|0,c[a+1412>>2]|0)|0){n=3;i=r;return n|0}g=a+1336|0;if($a(q,a,g,h)|0){ab(a,c[h>>2]|0);n=3;i=r;return n|0}if(!(Gb(a)|0)){n=0;i=r;return n|0}else{c[k>>2]=1;break}}else if((b|0)==8)if(!(Sa(q,h)|0)){Cb(a,h)|0;n=0;i=r;return n|0}else{n=h+20|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+24|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+28|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+44|0;gd(c[n>>2]|0);c[n>>2]=0;n=3;i=r;return n|0}else{n=0;i=r;return n|0}}while(0);uc(g,c[a+1212>>2]|0);Eb(a);j=Gc(a+1284|0,c[a+16>>2]|0,a+1368|0,b)|0;d=a+1188|0;do if(c[d>>2]|0){h=a+1220|0;if(!(c[a+1364>>2]|0)){hc(h,0,g,c[a+1380>>2]|0,j,(c[b>>2]|0)==5&1,c[a+1208>>2]|0,c[a+1204>>2]|0)|0;break}else{hc(h,a+1644|0,g,c[a+1380>>2]|0,j,(c[b>>2]|0)==5&1,c[a+1208>>2]|0,c[a+1204>>2]|0)|0;break}}while(0);c[a+1184>>2]=0;c[d>>2]=0;n=1;i=r;return n|0}else if((b|0)==65520){n=4;i=r;return n|0}else{n=3;i=r;return n|0}return 0}function Jc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;e=0;do{d=a+(e<<2)+20|0;b=c[d>>2]|0;if(b){gd(c[b+40>>2]|0);c[(c[d>>2]|0)+40>>2]=0;gd(c[(c[d>>2]|0)+84>>2]|0);c[(c[d>>2]|0)+84>>2]=0;gd(c[d>>2]|0);c[d>>2]=0}e=e+1|0}while((e|0)!=32);e=0;do{d=a+(e<<2)+148|0;b=c[d>>2]|0;if(b){gd(c[b+20>>2]|0);c[(c[d>>2]|0)+20>>2]=0;gd(c[(c[d>>2]|0)+24>>2]|0);c[(c[d>>2]|0)+24>>2]=0;gd(c[(c[d>>2]|0)+28>>2]|0);c[(c[d>>2]|0)+28>>2]=0;gd(c[(c[d>>2]|0)+44>>2]|0);c[(c[d>>2]|0)+44>>2]=0;gd(c[d>>2]|0);c[d>>2]=0}e=e+1|0}while((e|0)!=256);b=a+3376|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+1212|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+1172|0;gd(c[b>>2]|0);c[b>>2]=0;mc(a+1220|0);i=f;return}function Kc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=i;a=pc(a+1220|0)|0;if(!a){a=0;i=f;return a|0}c[b>>2]=c[a+4>>2];c[d>>2]=c[a+12>>2];c[e>>2]=c[a+8>>2];a=c[a>>2]|0;i=f;return a|0}function Lc(a){a=a|0;var b=0;b=i;a=c[a+16>>2]|0;if(!a){a=0;i=b;return a|0}a=c[a+52>>2]|0;i=b;return a|0}function Mc(a){a=a|0;var b=0;b=i;a=c[a+16>>2]|0;if(!a){a=0;i=b;return a|0}a=c[a+56>>2]|0;i=b;return a|0}function Nc(a){a=a|0;var b=0;b=i;qc(a+1220|0);i=b;return}function Oc(a){a=a|0;var b=0;b=i;a=(Jb(a)|0)==0&1;i=b;return a|0}function Pc(a){a=a|0;var b=0,d=0;d=i;a=c[a+16>>2]|0;if(((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(b=c[a+84>>2]|0,(b|0)!=0):0)?(c[b+24>>2]|0)!=0:0)?(c[b+32>>2]|0)!=0:0){a=1;i=d;return a|0}a=0;i=d;return a|0}function Qc(a){a=a|0;var b=0,d=0;d=i;a=c[a+16>>2]|0;if(((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(b=c[a+84>>2]|0,(b|0)!=0):0)?(c[b+24>>2]|0)!=0:0)?(c[b+36>>2]|0)!=0:0)a=c[b+48>>2]|0;else a=2;i=d;return a|0}function Rc(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;h=i;a=c[a+16>>2]|0;if((a|0)!=0?(c[a+60>>2]|0)!=0:0){c[b>>2]=1;b=a+64|0;c[d>>2]=c[b>>2]<<1;c[e>>2]=(c[a+52>>2]<<4)-((c[a+68>>2]|0)+(c[b>>2]|0)<<1);b=a+72|0;c[f>>2]=c[b>>2]<<1;a=(c[a+56>>2]<<4)-((c[a+76>>2]|0)+(c[b>>2]|0)<<1)|0;c[g>>2]=a;i=h;return}c[b>>2]=0;c[d>>2]=0;c[e>>2]=0;c[f>>2]=0;a=0;c[g>>2]=a;i=h;return}function Sc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;f=i;a=c[a+16>>2]|0;a:do if((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(e=c[a+84>>2]|0,(e|0)!=0):0)?(c[e>>2]|0)!=0:0){a=c[e+4>>2]|0;do switch(a|0){case 8:{e=11;a=32;break a}case 13:{e=99;a=160;break a}case 12:{e=33;a=64;break a}case 6:{e=11;a=24;break a}case 7:{e=11;a=20;break a}case 255:{a=c[e+8>>2]|0;e=c[e+12>>2]|0;g=(a|0)==0|(e|0)==0;e=g?0:e;a=g?0:a;break a}case 5:{e=33;a=40;break a}case 4:{e=11;a=16;break a}case 3:{e=11;a=10;break a}case 1:case 0:{e=a;break a}case 2:{e=11;a=12;break a}case 10:{e=11;a=18;break a}case 9:{e=33;a=80;break a}case 11:{e=11;a=15;break a}default:{e=0;a=0;break a}}while(0)}else{e=1;a=1}while(0);c[b>>2]=a;c[d>>2]=e;i=f;return}function Tc(a){a=a|0;a=c[a+16>>2]|0;if(!a)a=0;else a=c[a>>2]|0;return a|0}function Uc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;do if(a){d=fd(3396)|0;if(d){e=d+8|0;if(!(Hc(e,b)|0)){c[d>>2]=1;c[d+4>>2]=0;c[a>>2]=d;d=0;break}else{Jc(e);gd(d);d=-4;break}}else d=-4}else d=-1;while(0);i=f;return d|0}function Vc(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;if((a|0)==0|(b|0)==0){a=-1;i=e;return a|0}d=a+8|0;if(!(c[a+24>>2]|0)){a=-6;i=e;return a|0}if(!(c[a+20>>2]|0)){a=-6;i=e;return a|0}c[b+4>>2]=(Lc(d)|0)<<4;c[b+8>>2]=(Mc(d)|0)<<4;c[b+12>>2]=Pc(d)|0;c[b+16>>2]=Qc(d)|0;Rc(d,b+28|0,b+32|0,b+36|0,b+40|0,b+44|0);Sc(d,b+20|0,b+24|0);c[b>>2]=Tc(d)|0;a=0;i=e;return a|0}function Wc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;m=i;i=i+16|0;j=m;a:do if((!((b|0)==0|(d|0)==0)?(f=c[b>>2]|0,(f|0)!=0):0)?(g=c[b+4>>2]|0,(g|0)!=0):0)if((a|0)!=0?(e=c[a>>2]|0,(e|0)!=0):0){c[d>>2]=0;c[j>>2]=0;k=a+8|0;c[a+3392>>2]=c[b+12>>2];h=b+8|0;b=1;while(1){if((e|0)==2){l=8;break}e=Ic(k,f,g,c[h>>2]|0,j)|0;n=c[j>>2]|0;f=f+n|0;g=g-n|0;g=(g|0)<0?0:g;c[d>>2]=f;if((e|0)==5){b=-4;break a}else if((e|0)==4){e=(Oc(k)|0|g|0)==0;b=e?-2:b}else if((e|0)==2)break;else if((e|0)==1){l=13;break}if(!g)break a;e=c[a>>2]|0}if((l|0)==8){c[a>>2]=1;c[d>>2]=f+(c[j>>2]|0)}else if((l|0)==13){b=a+4|0;c[b>>2]=(c[b>>2]|0)+1;b=(g|0)==0?2:3;break}b=a+1288|0;if((c[b>>2]|0)!=0?(c[a+1244>>2]|0)!=(c[a+1248>>2]|0):0){c[b>>2]=0;c[a>>2]=2;b=3}else b=4}else b=-3;else b=-1;while(0);i=m;return b|0}function Xc(a){a=a|0;c[a>>2]=2;c[a+4>>2]=3;return}function Yc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;h=i;i=i+16|0;f=h+8|0;e=h+4|0;g=h;if((a|0)==0|(b|0)==0){a=-1;i=h;return a|0}a=a+8|0;if(d)Nc(a);a=Kc(a,g,e,f)|0;if(!a){a=0;i=h;return a|0}c[b>>2]=a;c[b+4>>2]=c[g>>2];c[b+8>>2]=c[e>>2];c[b+12>>2]=c[f>>2];a=2;i=h;return a|0}function Zc(a){a=a|0;var b=0,d=0;d=i;b=jd(a)|0;c[1792]=b;c[1791]=b;c[1790]=a;c[1793]=b+a;i=d;return b|0}function _c(a){a=a|0;c[1790]=a;return}function $c(){var a=0;a=i;c[1786]=c[1791];c[1787]=c[1790];do bd()|0;while((c[1787]|0)!=0);i=a;return}function ad(){var a=0,b=0;b=i;if(Uc(7176,0)|0){da(7280)|0;a=c[1784]|0;if(a)kd(a)}else{c[1796]=1;c[1798]=1}i=b;return -1}function bd(){var a=0,b=0,d=0;b=i;c[1788]=c[1798];a=Wc(c[1794]|0,7144,7200)|0;switch(a|0){case 1:case -2:{c[1787]=0;i=b;return a|0}case 4:{if(Vc(c[1794]|0,7208)|0){a=-1;i=b;return a|0}c[1814]=(Z((c[1803]|0)*3|0,c[1804]|0)|0)>>>1;ra();a=c[1800]|0;c[1787]=(c[1786]|0)-a+(c[1787]|0);c[1786]=a;a=0;i=b;return a|0}case 2:{c[1787]=0;break}case 3:{d=c[1800]|0;c[1787]=(c[1786]|0)-d+(c[1787]|0);c[1786]=d;break}default:{i=b;return a|0}}c[1798]=(c[1798]|0)+1;if((Yc(c[1794]|0,7264,0)|0)!=2){i=b;return a|0}do{c[1796]=(c[1796]|0)+1;ca(c[1816]|0,c[1803]|0,c[1804]|0)}while((Yc(c[1794]|0,7264,0)|0)==2);i=b;return a|0}function cd(){var a=0,b=0;b=i;a=c[1784]|0;if(a)kd(a);i=b;return}function dd(){var a=0,b=0;b=i;i=i+16|0;a=b;Xc(a);i=b;return c[a>>2]|0}function ed(){var a=0,b=0;b=i;i=i+16|0;a=b;Xc(a);i=b;return c[a+4>>2]|0}function fd(a){a=a|0;var b=0;b=i;a=jd(a)|0;i=b;return a|0}function gd(a){a=a|0;var b=0;b=i;kd(a);i=b;return}function hd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=i;od(a|0,b|0,c|0)|0;i=d;return}function id(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=i;nd(a|0,b&255|0,c|0)|0;i=d;return}function jd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=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,G=0,H=0,I=0,J=0,K=0,L=0;L=i;do if(a>>>0<245){if(a>>>0<11)p=16;else p=a+11&-8;a=p>>>3;l=c[1828]|0;k=l>>>a;if(k&3){g=(k&1^1)+a|0;b=g<<1;h=7352+(b<<2)|0;b=7352+(b+2<<2)|0;e=c[b>>2]|0;j=e+8|0;f=c[j>>2]|0;do if((h|0)!=(f|0)){if(f>>>0<(c[1832]|0)>>>0)ka();d=f+12|0;if((c[d>>2]|0)==(e|0)){c[d>>2]=h;c[b>>2]=f;break}else ka()}else c[1828]=l&~(1<>2]=x|3;x=e+(x|4)|0;c[x>>2]=c[x>>2]|1;x=j;i=L;return x|0}j=c[1830]|0;if(p>>>0>j>>>0){if(k){g=2<>>12&16;g=g>>>a;h=g>>>5&8;g=g>>>h;d=g>>>2&4;g=g>>>d;e=g>>>1&2;g=g>>>e;f=g>>>1&1;f=(h|a|d|e|f)+(g>>>f)|0;g=f<<1;e=7352+(g<<2)|0;g=7352+(g+2<<2)|0;d=c[g>>2]|0;a=d+8|0;h=c[a>>2]|0;do if((e|0)!=(h|0)){if(h>>>0<(c[1832]|0)>>>0)ka();j=h+12|0;if((c[j>>2]|0)==(d|0)){c[j>>2]=e;c[g>>2]=h;m=c[1830]|0;break}else ka()}else{c[1828]=l&~(1<>2]=p|3;b=d+p|0;c[d+(p|4)>>2]=k|1;c[d+x>>2]=k;if(m){e=c[1833]|0;g=m>>>3;h=g<<1;f=7352+(h<<2)|0;j=c[1828]|0;g=1<>2]|0;if(h>>>0<(c[1832]|0)>>>0)ka();else{n=j;o=h}}else{c[1828]=j|g;n=7352+(h+2<<2)|0;o=f}c[n>>2]=e;c[o+12>>2]=e;c[e+8>>2]=o;c[e+12>>2]=f}c[1830]=k;c[1833]=b;x=a;i=L;return x|0}k=c[1829]|0;if(k){l=(k&0-k)+-1|0;w=l>>>12&16;l=l>>>w;v=l>>>5&8;l=l>>>v;x=l>>>2&4;l=l>>>x;j=l>>>1&2;l=l>>>j;m=l>>>1&1;m=c[7616+((v|w|x|j|m)+(l>>>m)<<2)>>2]|0;l=(c[m+4>>2]&-8)-p|0;j=m;while(1){d=c[j+16>>2]|0;if(!d){d=c[j+20>>2]|0;if(!d)break}j=(c[d+4>>2]&-8)-p|0;x=j>>>0>>0;l=x?j:l;j=d;m=x?d:m}k=c[1832]|0;if(m>>>0>>0)ka();b=m+p|0;if(m>>>0>=b>>>0)ka();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){e=0;break}}while(1){f=j+20|0;g=c[f>>2]|0;if(g){j=g;h=f;continue}f=j+16|0;g=c[f>>2]|0;if(!g)break;else{j=g;h=f}}if(h>>>0>>0)ka();else{c[h>>2]=0;e=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ka();j=f+12|0;if((c[j>>2]|0)!=(m|0))ka();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;e=g;break}else ka()}while(0);do if(a){j=c[m+28>>2]|0;h=7616+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=e;if(!e){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=e;else c[a+20>>2]=e;if(!e)break}h=c[1832]|0;if(e>>>0>>0)ka();c[e+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ka();else{c[e+16>>2]=j;c[j+24>>2]=e;break}while(0);f=c[m+20>>2]|0;if(f)if(f>>>0<(c[1832]|0)>>>0)ka();else{c[e+20>>2]=f;c[f+24>>2]=e;break}}while(0);if(l>>>0<16){x=l+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}else{c[m+4>>2]=p|3;c[m+(p|4)>>2]=l|1;c[m+(l+p)>>2]=l;d=c[1830]|0;if(d){e=c[1833]|0;g=d>>>3;h=g<<1;f=7352+(h<<2)|0;j=c[1828]|0;g=1<>2]|0;if(h>>>0<(c[1832]|0)>>>0)ka();else{r=j;q=h}}else{c[1828]=j|g;r=7352+(h+2<<2)|0;q=f}c[r>>2]=e;c[q+12>>2]=e;c[e+8>>2]=q;c[e+12>>2]=f}c[1830]=l;c[1833]=b}x=m+8|0;i=L;return x|0}}}else if(a>>>0<=4294967231){a=a+11|0;p=a&-8;m=c[1829]|0;if(m){h=0-p|0;a=a>>>8;if(a)if(p>>>0>16777215)l=31;else{q=(a+1048320|0)>>>16&8;r=a<>>16&4;r=r<>>16&2;l=14-(o|q|l)+(r<>>15)|0;l=p>>>(l+7|0)&1|l<<1}else l=0;j=c[7616+(l<<2)>>2]|0;a:do if(!j){a=0;k=0}else{if((l|0)==31)k=0;else k=25-(l>>>1)|0;f=h;a=0;e=p<>2]&-8;h=g-p|0;if(h>>>0>>0)if((g|0)==(p|0)){a=j;k=j;break a}else k=j;else h=f;r=c[j+20>>2]|0;j=c[j+(e>>>31<<2)+16>>2]|0;a=(r|0)==0|(r|0)==(j|0)?a:r;if(!j)break;else{f=h;e=e<<1}}}while(0);if((a|0)==0&(k|0)==0){a=2<>>12&16;r=r>>>n;m=r>>>5&8;r=r>>>m;o=r>>>2&4;r=r>>>o;q=r>>>1&2;r=r>>>q;a=r>>>1&1;a=c[7616+((m|n|o|q|a)+(r>>>a)<<2)>>2]|0}if(!a){n=h;m=k}else while(1){r=(c[a+4>>2]&-8)-p|0;j=r>>>0>>0;h=j?r:h;k=j?a:k;j=c[a+16>>2]|0;if(j){a=j;continue}a=c[a+20>>2]|0;if(!a){n=h;m=k;break}}if((m|0)!=0?n>>>0<((c[1830]|0)-p|0)>>>0:0){k=c[1832]|0;if(m>>>0>>0)ka();o=m+p|0;if(m>>>0>=o>>>0)ka();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){b=0;break}}while(1){f=j+20|0;g=c[f>>2]|0;if(g){j=g;h=f;continue}f=j+16|0;g=c[f>>2]|0;if(!g)break;else{j=g;h=f}}if(h>>>0>>0)ka();else{c[h>>2]=0;b=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ka();j=f+12|0;if((c[j>>2]|0)!=(m|0))ka();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;b=g;break}else ka()}while(0);do if(a){j=c[m+28>>2]|0;h=7616+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=b;if(!b){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=b;else c[a+20>>2]=b;if(!b)break}h=c[1832]|0;if(b>>>0>>0)ka();c[b+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ka();else{c[b+16>>2]=j;c[j+24>>2]=b;break}while(0);j=c[m+20>>2]|0;if(j)if(j>>>0<(c[1832]|0)>>>0)ka();else{c[b+20>>2]=j;c[j+24>>2]=b;break}}while(0);b:do if(n>>>0>=16){c[m+4>>2]=p|3;c[m+(p|4)>>2]=n|1;c[m+(n+p)>>2]=n;j=n>>>3;if(n>>>0<256){g=j<<1;d=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(e>>>0>=(c[1832]|0)>>>0){t=f;u=e;break}ka()}while(0);c[t>>2]=o;c[u+12>>2]=o;c[m+(p+8)>>2]=u;c[m+(p+12)>>2]=d;break}d=n>>>8;if(d)if(n>>>0>16777215)f=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|w|f)+(x<>>15)|0;f=n>>>(f+7|0)&1|f<<1}else f=0;h=7616+(f<<2)|0;c[m+(p+28)>>2]=f;c[m+(p+20)>>2]=0;c[m+(p+16)>>2]=0;j=c[1829]|0;g=1<>2]=o;c[m+(p+24)>>2]=h;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break}j=c[h>>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;c:do if((c[j+4>>2]&-8|0)!=(n|0)){f=n<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(n|0)){v=h;break c}else{f=f<<1;j=h}}if(g>>>0<(c[1832]|0)>>>0)ka();else{c[g>>2]=o;c[m+(p+24)>>2]=j;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break b}}else v=j;while(0);b=v+8|0;d=c[b>>2]|0;x=c[1832]|0;if(v>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=o;c[b>>2]=o;c[m+(p+8)>>2]=d;c[m+(p+12)>>2]=v;c[m+(p+24)>>2]=0;break}else ka()}else{x=n+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}while(0);x=m+8|0;i=L;return x|0}}}else p=-1;while(0);k=c[1830]|0;if(k>>>0>=p>>>0){d=k-p|0;b=c[1833]|0;if(d>>>0>15){c[1833]=b+p;c[1830]=d;c[b+(p+4)>>2]=d|1;c[b+k>>2]=d;c[b+4>>2]=p|3}else{c[1830]=0;c[1833]=0;c[b+4>>2]=k|3;x=b+(k+4)|0;c[x>>2]=c[x>>2]|1}x=b+8|0;i=L;return x|0}k=c[1831]|0;if(k>>>0>p>>>0){w=k-p|0;c[1831]=w;x=c[1834]|0;c[1834]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}do if(!(c[1946]|0)){k=ua(30)|0;if(!(k+-1&k)){c[1948]=k;c[1947]=k;c[1949]=-1;c[1950]=-1;c[1951]=0;c[1939]=0;c[1946]=(ta(0)|0)&-16^1431655768;break}else ka()}while(0);l=p+48|0;g=c[1948]|0;f=p+47|0;h=g+f|0;g=0-g|0;m=h&g;if(m>>>0<=p>>>0){x=0;i=L;return x|0}a=c[1938]|0;if((a|0)!=0?(u=c[1936]|0,v=u+m|0,v>>>0<=u>>>0|v>>>0>a>>>0):0){x=0;i=L;return x|0}d:do if(!(c[1939]&4)){j=c[1834]|0;e:do if(j){a=7760|0;while(1){k=c[a>>2]|0;if(k>>>0<=j>>>0?(s=a+4|0,(k+(c[s>>2]|0)|0)>>>0>j>>>0):0)break;a=c[a+8>>2]|0;if(!a){A=181;break e}}if(a){k=h-(c[1831]|0)&g;if(k>>>0<2147483647){j=ma(k|0)|0;if((j|0)==((c[a>>2]|0)+(c[s>>2]|0)|0))A=190;else A=191}else k=0}else A=181}else A=181;while(0);do if((A|0)==181){j=ma(0)|0;if((j|0)!=(-1|0)){a=j;k=c[1947]|0;h=k+-1|0;if(!(h&a))k=m;else k=m-a+(h+a&0-k)|0;a=c[1936]|0;h=a+k|0;if(k>>>0>p>>>0&k>>>0<2147483647){v=c[1938]|0;if((v|0)!=0?h>>>0<=a>>>0|h>>>0>v>>>0:0){k=0;break}h=ma(k|0)|0;if((h|0)==(j|0))A=190;else{j=h;A=191}}else k=0}else k=0}while(0);f:do if((A|0)==190){if((j|0)!=(-1|0)){w=j;s=k;A=201;break d}}else if((A|0)==191){a=0-k|0;do if((j|0)!=(-1|0)&k>>>0<2147483647&l>>>0>k>>>0?(d=c[1948]|0,d=f-k+d&0-d,d>>>0<2147483647):0)if((ma(d|0)|0)==(-1|0)){ma(a|0)|0;k=0;break f}else{k=d+k|0;break}while(0);if((j|0)==(-1|0))k=0;else{w=j;s=k;A=201;break d}}while(0);c[1939]=c[1939]|4;A=198}else{k=0;A=198}while(0);if((((A|0)==198?m>>>0<2147483647:0)?(w=ma(m|0)|0,x=ma(0)|0,(w|0)!=(-1|0)&(x|0)!=(-1|0)&w>>>0>>0):0)?(z=x-w|0,y=z>>>0>(p+40|0)>>>0,y):0){s=y?z:k;A=201}if((A|0)==201){j=(c[1936]|0)+s|0;c[1936]=j;if(j>>>0>(c[1937]|0)>>>0)c[1937]=j;o=c[1834]|0;g:do if(o){f=7760|0;while(1){k=c[f>>2]|0;g=f+4|0;j=c[g>>2]|0;if((w|0)==(k+j|0)){A=213;break}h=c[f+8>>2]|0;if(!h)break;else f=h}if(((A|0)==213?(c[f+12>>2]&8|0)==0:0)?o>>>0>=k>>>0&o>>>0>>0:0){c[g>>2]=j+s;d=(c[1831]|0)+s|0;b=o+8|0;if(!(b&7))b=0;else b=0-b&7;x=d-b|0;c[1834]=o+b;c[1831]=x;c[o+(b+4)>>2]=x|1;c[o+(d+4)>>2]=40;c[1835]=c[1950];break}k=c[1832]|0;if(w>>>0>>0){c[1832]=w;k=w}h=w+s|0;g=7760|0;while(1){if((c[g>>2]|0)==(h|0)){A=223;break}j=c[g+8>>2]|0;if(!j)break;else g=j}if((A|0)==223?(c[g+12>>2]&8|0)==0:0){c[g>>2]=w;j=g+4|0;c[j>>2]=(c[j>>2]|0)+s;j=w+8|0;if(!(j&7))r=0;else r=0-j&7;j=w+(s+8)|0;if(!(j&7))b=0;else b=0-j&7;j=w+(b+s)|0;q=r+p|0;n=w+q|0;d=j-(w+r)-p|0;c[w+(r+4)>>2]=p|3;h:do if((j|0)!=(o|0)){if((j|0)==(c[1833]|0)){x=(c[1830]|0)+d|0;c[1830]=x;c[1833]=n;c[w+(q+4)>>2]=x|1;c[w+(x+q)>>2]=x;break}l=s+4|0;h=c[w+(l+b)>>2]|0;if((h&3|0)==1){m=h&-8;e=h>>>3;i:do if(h>>>0>=256){a=c[w+((b|24)+s)>>2]|0;g=c[w+(s+12+b)>>2]|0;do if((g|0)==(j|0)){g=b|16;f=w+(l+g)|0;h=c[f>>2]|0;if(!h){g=w+(g+s)|0;h=c[g>>2]|0;if(!h){H=0;break}}else g=f;while(1){e=h+20|0;f=c[e>>2]|0;if(f){h=f;g=e;continue}e=h+16|0;f=c[e>>2]|0;if(!f)break;else{h=f;g=e}}if(g>>>0>>0)ka();else{c[g>>2]=0;H=h;break}}else{f=c[w+((b|8)+s)>>2]|0;if(f>>>0>>0)ka();k=f+12|0;if((c[k>>2]|0)!=(j|0))ka();h=g+8|0;if((c[h>>2]|0)==(j|0)){c[k>>2]=g;c[h>>2]=f;H=g;break}else ka()}while(0);if(!a)break;k=c[w+(s+28+b)>>2]|0;h=7616+(k<<2)|0;do if((j|0)!=(c[h>>2]|0)){if(a>>>0<(c[1832]|0)>>>0)ka();k=a+16|0;if((c[k>>2]|0)==(j|0))c[k>>2]=H;else c[a+20>>2]=H;if(!H)break i}else{c[h>>2]=H;if(H)break;c[1829]=c[1829]&~(1<>>0>>0)ka();c[H+24>>2]=a;j=b|16;k=c[w+(j+s)>>2]|0;do if(k)if(k>>>0>>0)ka();else{c[H+16>>2]=k;c[k+24>>2]=H;break}while(0);j=c[w+(l+j)>>2]|0;if(!j)break;if(j>>>0<(c[1832]|0)>>>0)ka();else{c[H+20>>2]=j;c[j+24>>2]=H;break}}else{g=c[w+((b|8)+s)>>2]|0;f=c[w+(s+12+b)>>2]|0;h=7352+(e<<1<<2)|0;do if((g|0)!=(h|0)){if(g>>>0>>0)ka();if((c[g+12>>2]|0)==(j|0))break;ka()}while(0);if((f|0)==(g|0)){c[1828]=c[1828]&~(1<>>0>>0)ka();k=f+8|0;if((c[k>>2]|0)==(j|0)){D=k;break}ka()}while(0);c[g+12>>2]=f;c[D>>2]=g}while(0);j=w+((m|b)+s)|0;k=m+d|0}else k=d;j=j+4|0;c[j>>2]=c[j>>2]&-2;c[w+(q+4)>>2]=k|1;c[w+(k+q)>>2]=k;j=k>>>3;if(k>>>0<256){g=j<<1;f=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(h>>>0>=(c[1832]|0)>>>0){I=j;J=h;break}ka()}while(0);c[I>>2]=n;c[J+12>>2]=n;c[w+(q+8)>>2]=J;c[w+(q+12)>>2]=f;break}d=k>>>8;do if(!d)f=0;else{if(k>>>0>16777215){f=31;break}v=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|v|f)+(x<>>15)|0;f=k>>>(f+7|0)&1|f<<1}while(0);h=7616+(f<<2)|0;c[w+(q+28)>>2]=f;c[w+(q+20)>>2]=0;c[w+(q+16)>>2]=0;j=c[1829]|0;g=1<>2]=n;c[w+(q+24)>>2]=h;c[w+(q+12)>>2]=n;c[w+(q+8)>>2]=n;break}j=c[h>>2]|0;if((f|0)==31)h=0;else h=25-(f>>>1)|0;j:do if((c[j+4>>2]&-8|0)!=(k|0)){f=k<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(k|0)){K=h;break j}else{f=f<<1;j=h}}if(g>>>0<(c[1832]|0)>>>0)ka();else{c[g>>2]=n;c[w+(q+24)>>2]=j;c[w+(q+12)>>2]=n;c[w+(q+8)>>2]=n;break h}}else K=j;while(0);b=K+8|0;d=c[b>>2]|0;x=c[1832]|0;if(K>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=n;c[b>>2]=n;c[w+(q+8)>>2]=d;c[w+(q+12)>>2]=K;c[w+(q+24)>>2]=0;break}else ka()}else{x=(c[1831]|0)+d|0;c[1831]=x;c[1834]=n;c[w+(q+4)>>2]=x|1}while(0);x=w+(r|8)|0;i=L;return x|0}j=7760|0;while(1){h=c[j>>2]|0;if(h>>>0<=o>>>0?(B=c[j+4>>2]|0,C=h+B|0,C>>>0>o>>>0):0)break;j=c[j+8>>2]|0}j=h+(B+-39)|0;if(!(j&7))j=0;else j=0-j&7;g=h+(B+-47+j)|0;g=g>>>0<(o+16|0)>>>0?o:g;h=g+8|0;j=w+8|0;if(!(j&7))j=0;else j=0-j&7;f=s+-40-j|0;c[1834]=w+j;c[1831]=f;c[w+(j+4)>>2]=f|1;c[w+(s+-36)>>2]=40;c[1835]=c[1950];c[g+4>>2]=27;c[h+0>>2]=c[1940];c[h+4>>2]=c[1941];c[h+8>>2]=c[1942];c[h+12>>2]=c[1943];c[1940]=w;c[1941]=s;c[1943]=0;c[1942]=h;f=g+28|0;c[f>>2]=7;if((g+32|0)>>>0>>0)do{x=f;f=f+4|0;c[f>>2]=7}while((x+8|0)>>>0>>0);if((g|0)!=(o|0)){k=g-o|0;j=o+(k+4)|0;c[j>>2]=c[j>>2]&-2;c[o+4>>2]=k|1;c[o+k>>2]=k;j=k>>>3;if(k>>>0<256){g=j<<1;f=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(b>>>0>=(c[1832]|0)>>>0){E=d;F=b;break}ka()}while(0);c[E>>2]=o;c[F+12>>2]=o;c[o+8>>2]=F;c[o+12>>2]=f;break}d=k>>>8;if(d)if(k>>>0>16777215)g=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;g=14-(v|w|g)+(x<>>15)|0;g=k>>>(g+7|0)&1|g<<1}else g=0;h=7616+(g<<2)|0;c[o+28>>2]=g;c[o+20>>2]=0;c[o+16>>2]=0;e=c[1829]|0;j=1<>2]=o;c[o+24>>2]=h;c[o+12>>2]=o;c[o+8>>2]=o;break}e=c[h>>2]|0;if((g|0)==31)d=0;else d=25-(g>>>1)|0;k:do if((c[e+4>>2]&-8|0)!=(k|0)){j=k<>>31<<2)+16|0;d=c[h>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(k|0)){G=d;break k}else{j=j<<1;e=d}}if(h>>>0<(c[1832]|0)>>>0)ka();else{c[h>>2]=o;c[o+24>>2]=e;c[o+12>>2]=o;c[o+8>>2]=o;break g}}else G=e;while(0);b=G+8|0;d=c[b>>2]|0;x=c[1832]|0;if(G>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=o;c[b>>2]=o;c[o+8>>2]=d;c[o+12>>2]=G;c[o+24>>2]=0;break}else ka()}}else{x=c[1832]|0;if((x|0)==0|w>>>0>>0)c[1832]=w;c[1940]=w;c[1941]=s;c[1943]=0;c[1837]=c[1946];c[1836]=-1;b=0;do{x=b<<1;v=7352+(x<<2)|0;c[7352+(x+3<<2)>>2]=v;c[7352+(x+2<<2)>>2]=v;b=b+1|0}while((b|0)!=32);b=w+8|0;if(!(b&7))b=0;else b=0-b&7;x=s+-40-b|0;c[1834]=w+b;c[1831]=x;c[w+(b+4)>>2]=x|1;c[w+(s+-36)>>2]=40;c[1835]=c[1950]}while(0);b=c[1831]|0;if(b>>>0>p>>>0){w=b-p|0;c[1831]=w;x=c[1834]|0;c[1834]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}}c[(va()|0)>>2]=12;x=0;i=L;return x|0}function kd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=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;w=i;if(!a){i=w;return}f=a+-8|0;h=c[1832]|0;if(f>>>0>>0)ka();g=c[a+-4>>2]|0;e=g&3;if((e|0)==1)ka();q=g&-8;r=a+(q+-8)|0;do if(!(g&1)){g=c[f>>2]|0;if(!e){i=w;return}j=-8-g|0;m=a+j|0;n=g+q|0;if(m>>>0>>0)ka();if((m|0)==(c[1833]|0)){f=a+(q+-4)|0;g=c[f>>2]|0;if((g&3|0)!=3){v=m;l=n;break}c[1830]=n;c[f>>2]=g&-2;c[a+(j+4)>>2]=n|1;c[r>>2]=n;i=w;return}d=g>>>3;if(g>>>0<256){e=c[a+(j+8)>>2]|0;f=c[a+(j+12)>>2]|0;g=7352+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0>>0)ka();if((c[e+12>>2]|0)!=(m|0))ka()}if((f|0)==(e|0)){c[1828]=c[1828]&~(1<>>0>>0)ka();g=f+8|0;if((c[g>>2]|0)==(m|0))b=g;else ka()}else b=f+8|0;c[e+12>>2]=f;c[b>>2]=e;v=m;l=n;break}b=c[a+(j+24)>>2]|0;e=c[a+(j+12)>>2]|0;do if((e|0)==(m|0)){f=a+(j+20)|0;g=c[f>>2]|0;if(!g){f=a+(j+16)|0;g=c[f>>2]|0;if(!g){k=0;break}}while(1){d=g+20|0;e=c[d>>2]|0;if(e){g=e;f=d;continue}d=g+16|0;e=c[d>>2]|0;if(!e)break;else{g=e;f=d}}if(f>>>0>>0)ka();else{c[f>>2]=0;k=g;break}}else{d=c[a+(j+8)>>2]|0;if(d>>>0>>0)ka();g=d+12|0;if((c[g>>2]|0)!=(m|0))ka();f=e+8|0;if((c[f>>2]|0)==(m|0)){c[g>>2]=e;c[f>>2]=d;k=e;break}else ka()}while(0);if(b){g=c[a+(j+28)>>2]|0;f=7616+(g<<2)|0;if((m|0)==(c[f>>2]|0)){c[f>>2]=k;if(!k){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();g=b+16|0;if((c[g>>2]|0)==(m|0))c[g>>2]=k;else c[b+20>>2]=k;if(!k){v=m;l=n;break}}f=c[1832]|0;if(k>>>0>>0)ka();c[k+24>>2]=b;g=c[a+(j+16)>>2]|0;do if(g)if(g>>>0>>0)ka();else{c[k+16>>2]=g;c[g+24>>2]=k;break}while(0);g=c[a+(j+20)>>2]|0;if(g)if(g>>>0<(c[1832]|0)>>>0)ka();else{c[k+20>>2]=g;c[g+24>>2]=k;v=m;l=n;break}else{v=m;l=n}}else{v=m;l=n}}else{v=f;l=q}while(0);if(v>>>0>=r>>>0)ka();g=a+(q+-4)|0;f=c[g>>2]|0;if(!(f&1))ka();if(!(f&2)){if((r|0)==(c[1834]|0)){m=(c[1831]|0)+l|0;c[1831]=m;c[1834]=v;c[v+4>>2]=m|1;if((v|0)!=(c[1833]|0)){i=w;return}c[1833]=0;c[1830]=0;i=w;return}if((r|0)==(c[1833]|0)){m=(c[1830]|0)+l|0;c[1830]=m;c[1833]=v;c[v+4>>2]=m|1;c[v+m>>2]=m;i=w;return}h=(f&-8)+l|0;d=f>>>3;do if(f>>>0>=256){b=c[a+(q+16)>>2]|0;g=c[a+(q|4)>>2]|0;do if((g|0)==(r|0)){f=a+(q+12)|0;g=c[f>>2]|0;if(!g){f=a+(q+8)|0;g=c[f>>2]|0;if(!g){p=0;break}}while(1){d=g+20|0;e=c[d>>2]|0;if(e){g=e;f=d;continue}d=g+16|0;e=c[d>>2]|0;if(!e)break;else{g=e;f=d}}if(f>>>0<(c[1832]|0)>>>0)ka();else{c[f>>2]=0;p=g;break}}else{f=c[a+q>>2]|0;if(f>>>0<(c[1832]|0)>>>0)ka();e=f+12|0;if((c[e>>2]|0)!=(r|0))ka();d=g+8|0;if((c[d>>2]|0)==(r|0)){c[e>>2]=g;c[d>>2]=f;p=g;break}else ka()}while(0);if(b){g=c[a+(q+20)>>2]|0;f=7616+(g<<2)|0;if((r|0)==(c[f>>2]|0)){c[f>>2]=p;if(!p){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();g=b+16|0;if((c[g>>2]|0)==(r|0))c[g>>2]=p;else c[b+20>>2]=p;if(!p)break}g=c[1832]|0;if(p>>>0>>0)ka();c[p+24>>2]=b;f=c[a+(q+8)>>2]|0;do if(f)if(f>>>0>>0)ka();else{c[p+16>>2]=f;c[f+24>>2]=p;break}while(0);d=c[a+(q+12)>>2]|0;if(d)if(d>>>0<(c[1832]|0)>>>0)ka();else{c[p+20>>2]=d;c[d+24>>2]=p;break}}}else{e=c[a+q>>2]|0;f=c[a+(q|4)>>2]|0;g=7352+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0<(c[1832]|0)>>>0)ka();if((c[e+12>>2]|0)!=(r|0))ka()}if((f|0)==(e|0)){c[1828]=c[1828]&~(1<>>0<(c[1832]|0)>>>0)ka();g=f+8|0;if((c[g>>2]|0)==(r|0))o=g;else ka()}else o=f+8|0;c[e+12>>2]=f;c[o>>2]=e}while(0);c[v+4>>2]=h|1;c[v+h>>2]=h;if((v|0)==(c[1833]|0)){c[1830]=h;i=w;return}else g=h}else{c[g>>2]=f&-2;c[v+4>>2]=l|1;c[v+l>>2]=l;g=l}e=g>>>3;if(g>>>0<256){f=e<<1;g=7352+(f<<2)|0;d=c[1828]|0;e=1<>2]|0;if(b>>>0<(c[1832]|0)>>>0)ka();else{s=d;t=b}}else{c[1828]=d|e;s=7352+(f+2<<2)|0;t=g}c[s>>2]=v;c[t+12>>2]=v;c[v+8>>2]=t;c[v+12>>2]=g;i=w;return}d=g>>>8;if(d)if(g>>>0>16777215)f=31;else{l=(d+1048320|0)>>>16&8;m=d<>>16&4;m=m<>>16&2;f=14-(k|l|f)+(m<>>15)|0;f=g>>>(f+7|0)&1|f<<1}else f=0;b=7616+(f<<2)|0;c[v+28>>2]=f;c[v+20>>2]=0;c[v+16>>2]=0;d=c[1829]|0;e=1<>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;b:do if((c[b+4>>2]&-8|0)!=(g|0)){f=g<>>31<<2)+16|0;d=c[e>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(g|0)){u=d;break b}else{f=f<<1;b=d}}if(e>>>0<(c[1832]|0)>>>0)ka();else{c[e>>2]=v;c[v+24>>2]=b;c[v+12>>2]=v;c[v+8>>2]=v;break a}}else u=b;while(0);d=u+8|0;b=c[d>>2]|0;m=c[1832]|0;if(u>>>0>=m>>>0&b>>>0>=m>>>0){c[b+12>>2]=v;c[d>>2]=v;c[v+8>>2]=b;c[v+12>>2]=u;c[v+24>>2]=0;break}else ka()}else{c[1829]=d|e;c[b>>2]=v;c[v+24>>2]=b;c[v+12>>2]=v;c[v+8>>2]=v}while(0);m=(c[1836]|0)+-1|0;c[1836]=m;if(!m)b=7768|0;else{i=w;return}while(1){b=c[b>>2]|0;if(!b)break;else b=b+8|0}c[1836]=-1;i=w;return}function ld(){}function md(b){b=b|0;var c=0;c=b;while(a[c>>0]|0)c=c+1|0;return c-b|0}function nd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;h=b&3;i=d|d<<8|d<<16|d<<24;g=f&~3;if(h){h=b+4-h|0;while((b|0)<(h|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(g|0)){c[b>>2]=i;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function od(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return pa(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function pd(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;xa[a&3](b|0,c|0,d|0,e|0,f|0)}function qd(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;_(0)} + +// EMSCRIPTEN_END_FUNCS +var xa=[qd,fc,ec,qd];return{_strlen:md,_free:kd,_broadwayGetMajorVersion:dd,_get_h264bsdClip:Lb,_broadwayExit:cd,_memset:nd,_broadwayCreateStream:Zc,_malloc:jd,_memcpy:od,_broadwayGetMinorVersion:ed,_broadwayPlayStream:$c,_broadwaySetStreamLength:_c,_broadwayInit:ad,runPostSets:ld,stackAlloc:ya,stackSave:za,stackRestore:Aa,setThrew:Ba,setTempRet0:Ea,getTempRet0:Fa,dynCall_viiiii:pd}}) + + +// EMSCRIPTEN_END_ASM +(p.Xc,p.Yc,Q),Bb=p._strlen=$._strlen,Ea=p._free=$._free;p._broadwayGetMajorVersion=$._broadwayGetMajorVersion;p._get_h264bsdClip=$._get_h264bsdClip;p._broadwayExit=$._broadwayExit;var Gb=p._memset=$._memset;p._broadwayCreateStream=$._broadwayCreateStream;var Ca=p._malloc=$._malloc,gc=p._memcpy=$._memcpy; +p._broadwayGetMinorVersion=$._broadwayGetMinorVersion;p._broadwayPlayStream=$._broadwayPlayStream;p._broadwaySetStreamLength=$._broadwaySetStreamLength;p._broadwayInit=$._broadwayInit;p.runPostSets=$.runPostSets;p.dynCall_viiiii=$.dynCall_viiiii;z.pb=$.stackAlloc;z.Tb=$.stackSave;z.Sb=$.stackRestore;z.Yd=$.setTempRet0;z.xd=$.getTempRet0; +if(T)if("function"===typeof p.locateFile?T=p.locateFile(T):p.memoryInitializerPrefixURL&&(T=p.memoryInitializerPrefixURL+T),t||da){var hc=p.readBinary(T);N.set(hc,Ia)}else Ya(),yb(T,function(a){N.set(a,Ia);Za()},function(){d("could not load memory initializer "+T)});function ia(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}ia.prototype=Error();var ic,jc=k,Xa=function kc(){!p.calledRun&&lc&&mc();p.calledRun||(Xa=kc)}; +p.callMain=p.ag=function(a){function b(){for(var a=0;3>a;a++)e.push(0)}w(0==S,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");w(0==Oa.length,"cannot call main when preRun functions remain to be called");a=a||[];Sa||(Sa=i,Na(R));var c=a.length+1,e=[M(Va(p.thisProgram),"i8",0)];b();for(var f=0;f y ? y : z); + } + + function OptimizedGetBoundaryStrengthsA($mb, $bS) { + var $totalCoeff = $mb + 28; + + var tc0 = HEAP16[$totalCoeff + 0 >> 1]; + var tc1 = HEAP16[$totalCoeff + 2 >> 1]; + var tc2 = HEAP16[$totalCoeff + 4 >> 1]; + var tc3 = HEAP16[$totalCoeff + 6 >> 1]; + var tc4 = HEAP16[$totalCoeff + 8 >> 1]; + var tc5 = HEAP16[$totalCoeff + 10 >> 1]; + var tc6 = HEAP16[$totalCoeff + 12 >> 1]; + var tc7 = HEAP16[$totalCoeff + 14 >> 1]; + var tc8 = HEAP16[$totalCoeff + 16 >> 1]; + var tc9 = HEAP16[$totalCoeff + 18 >> 1]; + var tc10 = HEAP16[$totalCoeff + 20 >> 1]; + var tc11 = HEAP16[$totalCoeff + 22 >> 1]; + var tc12 = HEAP16[$totalCoeff + 24 >> 1]; + var tc13 = HEAP16[$totalCoeff + 26 >> 1]; + var tc14 = HEAP16[$totalCoeff + 28 >> 1]; + var tc15 = HEAP16[$totalCoeff + 30 >> 1]; + + HEAP32[$bS + 32 >> 2] = tc2 || tc0 ? 2 : 0; + HEAP32[$bS + 40 >> 2] = tc3 || tc1 ? 2 : 0; + HEAP32[$bS + 48 >> 2] = tc6 || tc4 ? 2 : 0; + HEAP32[$bS + 56 >> 2] = tc7 || tc5 ? 2 : 0; + HEAP32[$bS + 64 >> 2] = tc8 || tc2 ? 2 : 0; + HEAP32[$bS + 72 >> 2] = tc9 || tc3 ? 2 : 0; + HEAP32[$bS + 80 >> 2] = tc12 || tc6 ? 2 : 0; + HEAP32[$bS + 88 >> 2] = tc13 || tc7 ? 2 : 0; + HEAP32[$bS + 96 >> 2] = tc10 || tc8 ? 2 : 0; + HEAP32[$bS + 104 >> 2] = tc11 || tc9 ? 2 : 0; + HEAP32[$bS + 112 >> 2] = tc14 || tc12 ? 2 : 0; + HEAP32[$bS + 120 >> 2] = tc15 || tc13 ? 2 : 0; + + HEAP32[$bS + 12 >> 2] = tc1 || tc0 ? 2 : 0; + HEAP32[$bS + 20 >> 2] = tc4 || tc1 ? 2 : 0; + HEAP32[$bS + 28 >> 2] = tc5 || tc4 ? 2 : 0; + HEAP32[$bS + 44 >> 2] = tc3 || tc2 ? 2 : 0; + HEAP32[$bS + 52 >> 2] = tc6 || tc3 ? 2 : 0; + HEAP32[$bS + 60 >> 2] = tc7 || tc6 ? 2 : 0; + HEAP32[$bS + 76 >> 2] = tc9 || tc8 ? 2 : 0; + HEAP32[$bS + 84 >> 2] = tc12 || tc9 ? 2 : 0; + HEAP32[$bS + 92 >> 2] = tc13 || tc12 ? 2 : 0; + HEAP32[$bS + 108 >> 2] = tc11 || tc10 ? 2 : 0; + HEAP32[$bS + 116 >> 2] = tc14 || tc11 ? 2 : 0; + HEAP32[$bS + 124 >> 2] = tc15 || tc14 ? 2 : 0; + } + + function OptimizedFilterVerLumaEdge ($data, bS, $thresholds, imageWidth) { + var delta, tc, tmp; + var p0, q0, p1, q1, p2, q2; + var tmpFlag; + var $clp = _h264bsdClip + 512; + var alpha = HEAP32[$thresholds + 4 >> 2]; + var beta = HEAP32[$thresholds + 8 >> 2]; + var val; + + if (bS < 4) { + tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255; + for (var i = 4; i > 0; i--) { + p1 = HEAPU8[$data + -2] & 255; + p0 = HEAPU8[$data + -1] & 255; + q0 = HEAPU8[$data] & 255; + q1 = HEAPU8[$data + 1] & 255; + if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) { + p2 = HEAPU8[$data - 3] & 255; + if (Math.abs(p2 - p0) < beta) { + val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; + HEAP8[$data - 2] = p1 + clip(-tc, tc, val); + tmp++; + } + + q2 = HEAPU8[$data + 2] & 255; + if (Math.abs(q2 - q0) < beta) { + val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; + HEAP8[$data + 1] = (q1 + clip(-tc, tc, val)); + tmp++; + } + + val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); + delta = clip(-tmp, tmp, val); + + p0 = HEAPU8[$clp + (p0 + delta)] & 255; + q0 = HEAPU8[$clp + (q0 - delta)] & 255; + tmp = tc; + HEAP8[$data - 1] = p0; + HEAP8[$data] = q0; + + $data += imageWidth; + } + } + } else { + OriginalFilterVerLumaEdge($data, bS, $thresholds, imageWidth); + } + } + + /** + * Filter all four successive horizontal 4-pixel luma edges. This can be done when bS is equal to all four edges. + */ + function OptimizedFilterHorLuma ($data, bS, $thresholds, imageWidth) { + var delta, tc, tmp; + var p0, q0, p1, q1, p2, q2; + var tmpFlag; + var $clp = _h264bsdClip + 512; + var alpha = HEAP32[$thresholds + 4 >> 2]; + var beta = HEAP32[$thresholds + 8 >> 2]; + var val; + + if (bS < 4) { + tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255; + for (var i = 16; i > 0; i--) { + p1 = HEAPU8[$data + (-imageWidth << 1)] & 255; + p0 = HEAPU8[$data + -imageWidth] & 255; + q0 = HEAPU8[$data] & 255; + q1 = HEAPU8[$data + imageWidth] & 255; + + if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) { + p2 = HEAPU8[$data + (-imageWidth * 3)] & 255; + if (Math.abs(p2 - p0) < beta) { + val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; + HEAP8[$data + (-imageWidth << 1)] = p1 + clip(-tc, tc, val); + tmp++; + } + + q2 = HEAPU8[$data + (imageWidth << 2)] & 255; + if (Math.abs(q2 - q0) < beta) { + val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; + HEAP8[$data + imageWidth] = (q1 + clip(-tc, tc, val)); + tmp++; + } + + val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); + delta = clip(-tmp, tmp, val); + + p0 = HEAPU8[$clp + (p0 + delta)] & 255; + q0 = HEAPU8[$clp + (q0 - delta)] & 255; + tmp = tc; + HEAP8[$data - imageWidth] = p0; + HEAP8[$data] = q0; + + $data ++; + } + } + } else { + OriginalFilterHorLuma($data, bS, $thresholds, imageWidth); + } + } + }; + + + Broadway.prototype = { + configure: function (config) { + // patchOptimizations(config, patches); + console.info("Broadway Configured: " + JSON.stringify(config)); + } + + }; + + + + + /* + + asm.js implementation of a yuv to rgb convertor + provided by @soliton4 + + based on + http://www.wordsaretoys.com/2013/10/18/making-yuv-conversion-a-little-faster/ + + */ + + + // factory to create asm.js yuv -> rgb convertor for a given resolution + var asmInstances = {}; + var getAsm = function(parWidth, parHeight){ + var idStr = "" + parWidth + "x" + parHeight; + if (asmInstances[idStr]){ + return asmInstances[idStr]; + }; + + var lumaSize = parWidth * parHeight; + var chromaSize = (lumaSize|0) >> 2; + + var inpSize = lumaSize + chromaSize + chromaSize; + var outSize = parWidth * parHeight * 4; + var cacheSize = Math.pow(2, 24) * 4; + var size = inpSize + outSize + cacheSize; + + var chunkSize = Math.pow(2, 24); + var heapSize = chunkSize; + while (heapSize < size){ + heapSize += chunkSize; + }; + var heap = new ArrayBuffer(heapSize); + + var res = asmFactory(global, {}, heap); + res.init(parWidth, parHeight); + asmInstances[idStr] = res; + + res.heap = heap; + res.out = new Uint8Array(heap, 0, outSize); + res.inp = new Uint8Array(heap, outSize, inpSize); + res.outSize = outSize; + + return res; + }; + + + function asmFactory(stdlib, foreign, heap) { + "use asm"; + + var imul = stdlib.Math.imul; + var min = stdlib.Math.min; + var max = stdlib.Math.max; + var pow = stdlib.Math.pow; + var out = new stdlib.Uint8Array(heap); + var out32 = new stdlib.Uint32Array(heap); + var inp = new stdlib.Uint8Array(heap); + var mem = new stdlib.Uint8Array(heap); + var mem32 = new stdlib.Uint32Array(heap); + + // for double algo + /*var vt = 1.370705; + var gt = 0.698001; + var gt2 = 0.337633; + var bt = 1.732446;*/ + + var width = 0; + var height = 0; + var lumaSize = 0; + var chromaSize = 0; + var inpSize = 0; + var outSize = 0; + + var inpStart = 0; + var outStart = 0; + + var widthFour = 0; + + var cacheStart = 0; + + + function init(parWidth, parHeight){ + parWidth = parWidth|0; + parHeight = parHeight|0; + + var i = 0; + var s = 0; + + width = parWidth; + widthFour = imul(parWidth, 4)|0; + height = parHeight; + lumaSize = imul(width|0, height|0)|0; + chromaSize = (lumaSize|0) >> 2; + outSize = imul(imul(width, height)|0, 4)|0; + inpSize = ((lumaSize + chromaSize)|0 + chromaSize)|0; + + outStart = 0; + inpStart = (outStart + outSize)|0; + cacheStart = (inpStart + inpSize)|0; + + // initializing memory (to be on the safe side) + s = ~~(+pow(+2, +24)); + s = imul(s, 4)|0; + + for (i = 0|0; ((i|0) < (s|0))|0; i = (i + 4)|0){ + mem32[((cacheStart + i)|0) >> 2] = 0; + }; + }; + + function doit(){ + var ystart = 0; + var ustart = 0; + var vstart = 0; + + var y = 0; + var yn = 0; + var u = 0; + var v = 0; + + var o = 0; + + var line = 0; + var col = 0; + + var usave = 0; + var vsave = 0; + + var ostart = 0; + var cacheAdr = 0; + + ostart = outStart|0; + + ystart = inpStart|0; + ustart = (ystart + lumaSize|0)|0; + vstart = (ustart + chromaSize)|0; + + for (line = 0; (line|0) < (height|0); line = (line + 2)|0){ + usave = ustart; + vsave = vstart; + for (col = 0; (col|0) < (width|0); col = (col + 2)|0){ + y = inp[ystart >> 0]|0; + yn = inp[((ystart + width)|0) >> 0]|0; + + u = inp[ustart >> 0]|0; + v = inp[vstart >> 0]|0; + + cacheAdr = (((((y << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(y,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[ostart >> 2] = o; + + cacheAdr = (((((yn << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(yn,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[((ostart + widthFour)|0) >> 2] = o; + + //yuv2rgb5(y, u, v, ostart); + //yuv2rgb5(yn, u, v, (ostart + widthFour)|0); + ostart = (ostart + 4)|0; + + // next step only for y. u and v stay the same + ystart = (ystart + 1)|0; + y = inp[ystart >> 0]|0; + yn = inp[((ystart + width)|0) >> 0]|0; + + //yuv2rgb5(y, u, v, ostart); + cacheAdr = (((((y << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(y,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[ostart >> 2] = o; + + //yuv2rgb5(yn, u, v, (ostart + widthFour)|0); + cacheAdr = (((((yn << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(yn,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[((ostart + widthFour)|0) >> 2] = o; + ostart = (ostart + 4)|0; + + //all positions inc 1 + + ystart = (ystart + 1)|0; + ustart = (ustart + 1)|0; + vstart = (vstart + 1)|0; + }; + ostart = (ostart + widthFour)|0; + ystart = (ystart + width)|0; + + }; + + }; + + function yuv2rgbcalc(y, u, v){ + y = y|0; + u = u|0; + v = v|0; + + var r = 0; + var g = 0; + var b = 0; + + var o = 0; + + var a0 = 0; + var a1 = 0; + var a2 = 0; + var a3 = 0; + var a4 = 0; + + a0 = imul(1192, (y - 16)|0)|0; + a1 = imul(1634, (v - 128)|0)|0; + a2 = imul(832, (v - 128)|0)|0; + a3 = imul(400, (u - 128)|0)|0; + a4 = imul(2066, (u - 128)|0)|0; + + r = (((a0 + a1)|0) >> 10)|0; + g = (((((a0 - a2)|0) - a3)|0) >> 10)|0; + b = (((a0 + a4)|0) >> 10)|0; + + if ((((r & 255)|0) != (r|0))|0){ + r = min(255, max(0, r|0)|0)|0; + }; + if ((((g & 255)|0) != (g|0))|0){ + g = min(255, max(0, g|0)|0)|0; + }; + if ((((b & 255)|0) != (b|0))|0){ + b = min(255, max(0, b|0)|0)|0; + }; + + o = 255; + o = (o << 8)|0; + o = (o + b)|0; + o = (o << 8)|0; + o = (o + g)|0; + o = (o << 8)|0; + o = (o + r)|0; + + return o|0; + + }; + + + + return { + init: init, + doit: doit + }; + }; + + + /* + potential worker initialization + + */ + + + if (typeof self != "undefined"){ + var isWorker = false; + var decoder; + var reuseMemory = false; + + var memAr = []; + var getMem = function(length){ + if (memAr.length){ + var u = memAr.shift(); + while (u && u.byteLength !== length){ + u = memAr.shift(); + }; + if (u){ + return u; + }; + }; + return new ArrayBuffer(length); + }; + + self.addEventListener('message', function(e) { + + if (isWorker){ + if (reuseMemory){ + if (e.data.reuse){ + memAr.push(e.data.reuse); + }; + }; + if (e.data.buf){ + decoder.decode(new Uint8Array(e.data.buf, e.data.offset || 0, e.data.length), e.data.info); + }; + + }else{ + if (e.data && e.data.type === "Broadway.js - Worker init"){ + isWorker = true; + decoder = new Broadway(e.data.options); + + if (e.data.options.reuseMemory){ + reuseMemory = true; + decoder.onPictureDecoded = function (buffer, width, height, infos) { + + //var buf = getMem(); + + // buffer needs to be copied because we give up ownership + var copyU8 = new Uint8Array(getMem(buffer.length)); + copyU8.set( buffer, 0, buffer.length ); + + postMessage({ + buf: copyU8.buffer, + length: buffer.length, + width: width, + height: height, + infos: infos + }, [copyU8.buffer]); // 2nd parameter is used to indicate transfer of ownership + + }; + + }else{ + decoder.onPictureDecoded = function (buffer, width, height, infos) { + if (buffer) { + buffer = new Uint8Array(buffer); + }; + + // buffer needs to be copied because we give up ownership + var copyU8 = new Uint8Array(buffer.length); + copyU8.set( buffer, 0, buffer.length ); + + postMessage({ + buf: copyU8.buffer, + length: buffer.length, + width: width, + height: height, + infos: infos + }, [copyU8.buffer]); // 2nd parameter is used to indicate transfer of ownership + + }; + }; + postMessage({ consoleLog: "broadway worker initialized" }); + }; + }; + + + }, false); + }; + + Broadway.nowValue = nowValue; + + return Broadway; + + })(); + + +})); + + +}).call(this,"/dvp\\node_modules\\h264-live-player\\vendor\\broadway") +},{}],5:[function(require,module,exports){ +"use strict"; +var assert = require('../utils/assert'); + + +function Program(gl) { + this.gl = gl; + this.program = this.gl.createProgram(); +} + +Program.prototype = { + attach: function (shader) { + this.gl.attachShader(this.program, shader.shader); + }, + link: function () { + this.gl.linkProgram(this.program); + // If creating the shader program failed, alert. + assert(this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS), + "Unable to initialize the shader program."); + }, + use: function () { + this.gl.useProgram(this.program); + }, + getAttributeLocation: function(name) { + return this.gl.getAttribLocation(this.program, name); + }, + setMatrixUniform: function(name, array) { + var uniform = this.gl.getUniformLocation(this.program, name); + this.gl.uniformMatrix4fv(uniform, false, array); + } +}; +module.exports = Program; + + +},{"../utils/assert":20}],6:[function(require,module,exports){ +"use strict"; + +var assert = require('../utils/assert'); + +/** + * Represents a WebGL shader script. + */ + +function Script() {} + +Script.createFromElementId = function(id) { + var script = document.getElementById(id); + + // Didn't find an element with the specified ID, abort. + assert(script , "Could not find shader with ID: " + id); + + // Walk through the source element's children, building the shader source string. + var source = ""; + var currentChild = script .firstChild; + while(currentChild) { + if (currentChild.nodeType == 3) { + source += currentChild.textContent; + } + currentChild = currentChild.nextSibling; + } + + var res = new Scriptor(); + res.type = script.type; + res.source = source; + return res; +}; + +Script.createFromSource = function(type, source) { + var res = new Script(); + res.type = type; + res.source = source; + return res; +} + + +module.exports = Script; +},{"../utils/assert":20}],7:[function(require,module,exports){ +"use strict"; + +var error = require('../utils/error'); + +/** + * Represents a WebGL shader object and provides a mechanism to load shaders from HTML + * script tags. + */ + + +function Shader(gl, script) { + + // Now figure out what type of shader script we have, based on its MIME type. + if (script.type == "x-shader/x-fragment") { + this.shader = gl.createShader(gl.FRAGMENT_SHADER); + } else if (script.type == "x-shader/x-vertex") { + this.shader = gl.createShader(gl.VERTEX_SHADER); + } else { + error("Unknown shader type: " + script.type); + return; + } + + // Send the source to the shader object. + gl.shaderSource(this.shader, script.source); + + // Compile the shader program. + gl.compileShader(this.shader); + + // See if it compiled successfully. + if (!gl.getShaderParameter(this.shader, gl.COMPILE_STATUS)) { + error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(this.shader)); + return; + } +} +module.exports = Shader; + + + + +},{"../utils/error":21}],8:[function(require,module,exports){ +"use strict"; + +var assert = require('../utils/assert'); + +/** + * Represents a WebGL texture object. + */ + +function Texture(gl, size, format) { + this.gl = gl; + this.size = size; + this.texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + this.format = format ? format : gl.LUMINANCE; + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, size.w, size.h, 0, this.format, gl.UNSIGNED_BYTE, null); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); +} + +var textureIDs = null; +Texture.prototype = { + fill: function(textureData, useTexSubImage2D) { + var gl = this.gl; + assert(textureData.length >= this.size.w * this.size.h, + "Texture size mismatch, data:" + textureData.length + ", texture: " + this.size.w * this.size.h); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + if (useTexSubImage2D) { + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.size.w , this.size.h, this.format, gl.UNSIGNED_BYTE, textureData); + } else { + // texImage2D seems to be faster, thus keeping it as the default + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.size.w, this.size.h, 0, this.format, gl.UNSIGNED_BYTE, textureData); + } + }, + bind: function(n, program, name) { + var gl = this.gl; + if (!textureIDs) { + textureIDs = [gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2]; + } + gl.activeTexture(textureIDs[n]); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.uniform1i(gl.getUniformLocation(program.program, name), n); + } +}; +module.exports = Texture; + + +},{"../utils/assert":20}],9:[function(require,module,exports){ +"use strict"; + +/** + * Generic WebGL backed canvas that sets up: a quad to paint a texture on, appropriate vertex/fragment shaders, + * scene parameters and other things. Specialized versions of this class can be created by overriding several + * initialization methods. + + */ + +var Script = require('./Script'); +var error = require('../utils/error'); +var makePerspective = require('../utils/glUtils').makePerspective; +var Matrix = require('sylvester.js').Matrix; +var Class = require('uclass'); + + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", ` + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D texture; + void main(void) { + gl_FragColor = texture2D(texture, vTextureCoord); + } +`); + +var WebGLCanvas = new Class({ + + initialize : function(canvas, size, useFrameBuffer) { + + this.canvas = canvas; + this.size = size; + this.canvas.width = size.w; + this.canvas.height = size.h; + + this.onInitWebGL(); + this.onInitShaders(); + this.initBuffers(); + + if (useFrameBuffer) + this.initFramebuffer(); + + this.onInitTextures(); + this.initScene(); + }, + + +/** + * Initialize a frame buffer so that we can render off-screen. + */ + initFramebuffer : function() { + + var gl = this.gl; + + // Create framebuffer object and texture. + this.framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + this.framebufferTexture = new Texture(this.gl, this.size, gl.RGBA); + + // Create and allocate renderbuffer for depth data. + var renderbuffer = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.size.w, this.size.h); + + // Attach texture and renderbuffer to the framebuffer. + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.framebufferTexture.texture, 0); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer); + }, + + + +/** + * Initialize vertex and texture coordinate buffers for a plane. + */ + initBuffers : function () { + var tmp; + var gl = this.gl; + + // Create vertex position buffer. + this.quadVPBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer); + tmp = [ + 1.0, 1.0, 0.0, + -1.0, 1.0, 0.0, + 1.0, -1.0, 0.0, + -1.0, -1.0, 0.0]; + + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW); + this.quadVPBuffer.itemSize = 3; + this.quadVPBuffer.numItems = 4; + + /* + +--------------------+ + | -1,1 (1) | 1,1 (0) + | | + | | + | | + | | + | | + | -1,-1 (3) | 1,-1 (2) + +--------------------+ + */ + + var scaleX = 1.0; + var scaleY = 1.0; + + // Create vertex texture coordinate buffer. + this.quadVTCBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer); + tmp = [ + scaleX, 0.0, + 0.0, 0.0, + scaleX, scaleY, + 0.0, scaleY, + ]; + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW); + }, + + + mvIdentity : function () { + this.mvMatrix = Matrix.I(4); + }, + + mvMultiply : function(m) { + this.mvMatrix = this.mvMatrix.x(m); + }, + + mvTranslate : function (m) { + this.mvMultiply(Matrix.Translation($V([m[0], m[1], m[2]])).ensure4x4()); + }, + + setMatrixUniforms : function () { + this.program.setMatrixUniform("uPMatrix", new Float32Array(this.perspectiveMatrix.flatten())); + this.program.setMatrixUniform("uMVMatrix", new Float32Array(this.mvMatrix.flatten())); + }, + + initScene : function() { + var gl = this.gl; + + // Establish the perspective with which we want to view the + // scene. Our field of view is 45 degrees, with a width/height + // ratio of 640:480, and we only want to see objects between 0.1 units + // and 100 units away from the camera. + + this.perspectiveMatrix = makePerspective(45, 1, 0.1, 100.0); + + // Set the drawing position to the "identity" point, which is + // the center of the scene. + this.mvIdentity(); + + // Now move the drawing position a bit to where we want to start + // drawing the square. + this.mvTranslate([0.0, 0.0, -2.4]); + + // Draw the cube by binding the array buffer to the cube's vertices + // array, setting attributes, and pushing it to GL. + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer); + gl.vertexAttribPointer(this.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); + + // Set the texture coordinates attribute for the vertices. + + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer); + gl.vertexAttribPointer(this.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + + this.onInitSceneTextures(); + + this.setMatrixUniforms(); + + if (this.framebuffer) { + console.log("Bound Frame Buffer"); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + } + }, + + + + toString: function() { + return "WebGLCanvas Size: " + this.size; + }, + + checkLastError: function (operation) { + var err = this.gl.getError(); + if (err != this.gl.NO_ERROR) { + var name = this.glNames[err]; + name = (name !== undefined) ? name + "(" + err + ")": + ("Unknown WebGL ENUM (0x" + value.toString(16) + ")"); + if (operation) { + console.log("WebGL Error: %s, %s", operation, name); + } else { + console.log("WebGL Error: %s", name); + } + console.trace(); + } + }, + + onInitWebGL: function () { + try { + this.gl = this.canvas.getContext("experimental-webgl"); + } catch(e) {} + + if (!this.gl) { + error("Unable to initialize WebGL. Your browser may not support it."); + } + if (this.glNames) { + return; + } + this.glNames = {}; + for (var propertyName in this.gl) { + if (typeof this.gl[propertyName] == 'number') { + this.glNames[this.gl[propertyName]] = propertyName; + } + } + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");; + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + var gl = this.gl; + this.texture = new Texture(gl, this.size, gl.RGBA); + }, + + onInitSceneTextures: function () { + this.texture.bind(0, this.program, "texture"); + }, + + drawScene: function() { + this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); + }, + + readPixels: function(buffer) { + var gl = this.gl; + gl.readPixels(0, 0, this.size.w, this.size.h, gl.RGBA, gl.UNSIGNED_BYTE, buffer); + }, + + +}); + + + +module.exports = WebGLCanvas; + +},{"../utils/error":21,"../utils/glUtils":22,"./Script":6,"sylvester.js":12,"uclass":47}],10:[function(require,module,exports){ +"use strict"; +var Class = require('uclass'); + +var YUVCanvas = new Class({ + + Binds : ['decode'], + + initialize : function(canvas, size) { + this.canvas = canvas; + this.canvasCtx = this.canvas.getContext("2d"); + this.canvasBuffer = this.canvasCtx.createImageData(size.w, size.h); + }, + + decode : function (buffer, width, height) { + if (!buffer) + return; + + var lumaSize = width * height; + var chromaSize = lumaSize >> 2; + + var ybuf = buffer.subarray(0, lumaSize); + var ubuf = buffer.subarray(lumaSize, lumaSize + chromaSize); + var vbuf = buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize); + + for (var y = 0; y < height; y++) { + for (var x = 0; x < width; x++) { + var yIndex = x + y * width; + var uIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2); + var vIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2); + var R = 1.164 * (ybuf[yIndex] - 16) + 1.596 * (vbuf[vIndex] - 128); + var G = 1.164 * (ybuf[yIndex] - 16) - 0.813 * (vbuf[vIndex] - 128) - 0.391 * (ubuf[uIndex] - 128); + var B = 1.164 * (ybuf[yIndex] - 16) + 2.018 * (ubuf[uIndex] - 128); + + var rgbIndex = yIndex * 4; + this.canvasBuffer.data[rgbIndex+0] = R; + this.canvasBuffer.data[rgbIndex+1] = G; + this.canvasBuffer.data[rgbIndex+2] = B; + this.canvasBuffer.data[rgbIndex+3] = 0xff; + } + } + + this.canvasCtx.putImageData(this.canvasBuffer, 0, 0); + +// var date = new Date(); + //console.log("WSAvcPlayer: Decode time: " + (date.getTime() - this.rcvtime) + " ms"); + }, + +}); + + +module.exports = YUVCanvas; +},{"uclass":47}],11:[function(require,module,exports){ +"use strict"; + +var Program = require('./Program'); +var Shader = require('./Shader'); +var Texture = require('./Texture'); +var Script = require('./Script'); +var WebGLCanvas = require('./WebGLCanvas'); + +var Class = require('uclass'); + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", ` + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D YTexture; + uniform sampler2D UTexture; + uniform sampler2D VTexture; + const mat4 YUV2RGB = mat4 + ( + 1.1643828125, 0, 1.59602734375, -.87078515625, + 1.1643828125, -.39176171875, -.81296875, .52959375, + 1.1643828125, 2.017234375, 0, -1.081390625, + 0, 0, 0, 1 + ); + + void main(void) { + gl_FragColor = vec4( texture2D(YTexture, vTextureCoord).x, texture2D(UTexture, vTextureCoord).x, texture2D(VTexture, vTextureCoord).x, 1) * YUV2RGB; + } +`); + + + + +var YUVWebGLCanvas = new Class({ + Extends : WebGLCanvas, + Binds : ['decode'], + + initialize : function(canvas, size) { + YUVWebGLCanvas.parent.initialize.call(this, canvas, size); + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");; + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + console.log("creatingTextures: size: " + this.size); + this.YTexture = new Texture(this.gl, this.size); + this.UTexture = new Texture(this.gl, this.size.getHalfSize()); + this.VTexture = new Texture(this.gl, this.size.getHalfSize()); + }, + + onInitSceneTextures: function () { + this.YTexture.bind(0, this.program, "YTexture"); + this.UTexture.bind(1, this.program, "UTexture"); + this.VTexture.bind(2, this.program, "VTexture"); + }, + + fillYUVTextures: function(y, u, v) { + this.YTexture.fill(y); + this.UTexture.fill(u); + this.VTexture.fill(v); + }, + + decode: function(buffer, width, height) { + + if (!buffer) + return; + + var lumaSize = width * height; + var chromaSize = lumaSize >> 2; + + this.YTexture.fill(buffer.subarray(0, lumaSize)); + this.UTexture.fill(buffer.subarray(lumaSize, lumaSize + chromaSize)); + this.VTexture.fill(buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize)); + this.drawScene(); + }, + + toString: function() { + return "YUVCanvas Size: " + this.size; + } +}); + + + + + +module.exports = YUVWebGLCanvas; + +},{"./Program":5,"./Script":6,"./Shader":7,"./Texture":8,"./WebGLCanvas":9,"uclass":47}],12:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel + +var global = (Function('return this'))(); + +exports.Vector = require('./vector'); +global.$V = exports.Vector.create; +exports.Matrix = require('./matrix'); +global.$M = exports.Matrix.create; +exports.Line = require('./line'); +global.$L = exports.Line.create; +exports.Plane = require('./plane'); +global.$P = exports.Plane.create; +exports.Line.Segment = require('./line.segment'); +exports.Sylvester = require('./sylvester'); + +},{"./line":13,"./line.segment":14,"./matrix":15,"./plane":16,"./sylvester":17,"./vector":18}],13:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +var Vector = require('./vector'); +var Matrix = require('./matrix'); +var Plane = require('./plane'); +var Sylvester = require('./sylvester'); + +// Line class - depends on Vector, and some methods require Matrix and Plane. + +function Line() {} +Line.prototype = { + + // Returns true if the argument occupies the same space as the line + eql: function(line) { + return (this.isParallelTo(line) && this.contains(line.anchor)); + }, + + // Returns a copy of the line + dup: function() { + return Line.create(this.anchor, this.direction); + }, + + // Returns the result of translating the line by the given vector/array + translate: function(vector) { + var V = vector.elements || vector; + return Line.create([ + this.anchor.elements[0] + V[0], + this.anchor.elements[1] + V[1], + this.anchor.elements[2] + (V[2] || 0) + ], this.direction); + }, + + // Returns true if the line is parallel to the argument. Here, 'parallel to' + // means that the argument's direction is either parallel or antiparallel to + // the line's own direction. A line is parallel to a plane if the two do not + // have a unique intersection. + isParallelTo: function(obj) { + if (obj.normal || (obj.start && obj.end)) { return obj.isParallelTo(this); } + var theta = this.direction.angleFrom(obj.direction); + return (Math.abs(theta) <= Sylvester.precision || Math.abs(theta - Math.PI) <= Sylvester.precision); + }, + + // Returns the line's perpendicular distance from the argument, + // which can be a point, a line or a plane + distanceFrom: function(obj) { + if (obj.normal || (obj.start && obj.end)) { return obj.distanceFrom(this); } + if (obj.direction) { + // obj is a line + if (this.isParallelTo(obj)) { return this.distanceFrom(obj.anchor); } + var N = this.direction.cross(obj.direction).toUnitVector().elements; + var A = this.anchor.elements, B = obj.anchor.elements; + return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]); + } else { + // obj is a point + var P = obj.elements || obj; + var A = this.anchor.elements, D = this.direction.elements; + var PA1 = P[0] - A[0], PA2 = P[1] - A[1], PA3 = (P[2] || 0) - A[2]; + var modPA = Math.sqrt(PA1*PA1 + PA2*PA2 + PA3*PA3); + if (modPA === 0) return 0; + // Assumes direction vector is normalized + var cosTheta = (PA1 * D[0] + PA2 * D[1] + PA3 * D[2]) / modPA; + var sin2 = 1 - cosTheta*cosTheta; + return Math.abs(modPA * Math.sqrt(sin2 < 0 ? 0 : sin2)); + } + }, + + // Returns true iff the argument is a point on the line, or if the argument + // is a line segment lying within the receiver + contains: function(obj) { + if (obj.start && obj.end) { return this.contains(obj.start) && this.contains(obj.end); } + var dist = this.distanceFrom(obj); + return (dist !== null && dist <= Sylvester.precision); + }, + + // Returns the distance from the anchor of the given point. Negative values are + // returned for points that are in the opposite direction to the line's direction from + // the line's anchor point. + positionOf: function(point) { + if (!this.contains(point)) { return null; } + var P = point.elements || point; + var A = this.anchor.elements, D = this.direction.elements; + return (P[0] - A[0]) * D[0] + (P[1] - A[1]) * D[1] + ((P[2] || 0) - A[2]) * D[2]; + }, + + // Returns true iff the line lies in the given plane + liesIn: function(plane) { + return plane.contains(this); + }, + + // Returns true iff the line has a unique point of intersection with the argument + intersects: function(obj) { + if (obj.normal) { return obj.intersects(this); } + return (!this.isParallelTo(obj) && this.distanceFrom(obj) <= Sylvester.precision); + }, + + // Returns the unique intersection point with the argument, if one exists + intersectionWith: function(obj) { + if (obj.normal || (obj.start && obj.end)) { return obj.intersectionWith(this); } + if (!this.intersects(obj)) { return null; } + var P = this.anchor.elements, X = this.direction.elements, + Q = obj.anchor.elements, Y = obj.direction.elements; + var X1 = X[0], X2 = X[1], X3 = X[2], Y1 = Y[0], Y2 = Y[1], Y3 = Y[2]; + var PsubQ1 = P[0] - Q[0], PsubQ2 = P[1] - Q[1], PsubQ3 = P[2] - Q[2]; + var XdotQsubP = - X1*PsubQ1 - X2*PsubQ2 - X3*PsubQ3; + var YdotPsubQ = Y1*PsubQ1 + Y2*PsubQ2 + Y3*PsubQ3; + var XdotX = X1*X1 + X2*X2 + X3*X3; + var YdotY = Y1*Y1 + Y2*Y2 + Y3*Y3; + var XdotY = X1*Y1 + X2*Y2 + X3*Y3; + var k = (XdotQsubP * YdotY / XdotX + XdotY * YdotPsubQ) / (YdotY - XdotY * XdotY); + return Vector.create([P[0] + k*X1, P[1] + k*X2, P[2] + k*X3]); + }, + + // Returns the point on the line that is closest to the given point or line/line segment + pointClosestTo: function(obj) { + if (obj.start && obj.end) { + // obj is a line segment + var P = obj.pointClosestTo(this); + return (P === null) ? null : this.pointClosestTo(P); + } else if (obj.direction) { + // obj is a line + if (this.intersects(obj)) { return this.intersectionWith(obj); } + if (this.isParallelTo(obj)) { return null; } + var D = this.direction.elements, E = obj.direction.elements; + var D1 = D[0], D2 = D[1], D3 = D[2], E1 = E[0], E2 = E[1], E3 = E[2]; + // Create plane containing obj and the shared normal and intersect this with it + // Thank you: http://www.cgafaq.info/wiki/Line-line_distance + var x = (D3 * E1 - D1 * E3), y = (D1 * E2 - D2 * E1), z = (D2 * E3 - D3 * E2); + var N = [x * E3 - y * E2, y * E1 - z * E3, z * E2 - x * E1]; + var P = Plane.create(obj.anchor, N); + return P.intersectionWith(this); + } else { + // obj is a point + var P = obj.elements || obj; + if (this.contains(P)) { return Vector.create(P); } + var A = this.anchor.elements, D = this.direction.elements; + var D1 = D[0], D2 = D[1], D3 = D[2], A1 = A[0], A2 = A[1], A3 = A[2]; + var x = D1 * (P[1]-A2) - D2 * (P[0]-A1), y = D2 * ((P[2] || 0) - A3) - D3 * (P[1]-A2), + z = D3 * (P[0]-A1) - D1 * ((P[2] || 0) - A3); + var V = Vector.create([D2 * x - D3 * z, D3 * y - D1 * x, D1 * z - D2 * y]); + var k = this.distanceFrom(P) / V.modulus(); + return Vector.create([ + P[0] + V.elements[0] * k, + P[1] + V.elements[1] * k, + (P[2] || 0) + V.elements[2] * k + ]); + } + }, + + // Returns a copy of the line rotated by t radians about the given line. Works by + // finding the argument's closest point to this line's anchor point (call this C) and + // rotating the anchor about C. Also rotates the line's direction about the argument's. + // Be careful with this - the rotation axis' direction affects the outcome! + rotate: function(t, line) { + // If we're working in 2D + if (typeof(line.direction) == 'undefined') { line = Line.create(line.to3D(), Vector.k); } + var R = Matrix.Rotation(t, line.direction).elements; + var C = line.pointClosestTo(this.anchor).elements; + var A = this.anchor.elements, D = this.direction.elements; + var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2]; + var x = A1 - C1, y = A2 - C2, z = A3 - C3; + return Line.create([ + C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z, + C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z, + C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z + ], [ + R[0][0] * D[0] + R[0][1] * D[1] + R[0][2] * D[2], + R[1][0] * D[0] + R[1][1] * D[1] + R[1][2] * D[2], + R[2][0] * D[0] + R[2][1] * D[1] + R[2][2] * D[2] + ]); + }, + + // Returns a copy of the line with its direction vector reversed. + // Useful when using lines for rotations. + reverse: function() { + return Line.create(this.anchor, this.direction.x(-1)); + }, + + // Returns the line's reflection in the given point or line + reflectionIn: function(obj) { + if (obj.normal) { + // obj is a plane + var A = this.anchor.elements, D = this.direction.elements; + var A1 = A[0], A2 = A[1], A3 = A[2], D1 = D[0], D2 = D[1], D3 = D[2]; + var newA = this.anchor.reflectionIn(obj).elements; + // Add the line's direction vector to its anchor, then mirror that in the plane + var AD1 = A1 + D1, AD2 = A2 + D2, AD3 = A3 + D3; + var Q = obj.pointClosestTo([AD1, AD2, AD3]).elements; + var newD = [Q[0] + (Q[0] - AD1) - newA[0], Q[1] + (Q[1] - AD2) - newA[1], Q[2] + (Q[2] - AD3) - newA[2]]; + return Line.create(newA, newD); + } else if (obj.direction) { + // obj is a line - reflection obtained by rotating PI radians about obj + return this.rotate(Math.PI, obj); + } else { + // obj is a point - just reflect the line's anchor in it + var P = obj.elements || obj; + return Line.create(this.anchor.reflectionIn([P[0], P[1], (P[2] || 0)]), this.direction); + } + }, + + // Set the line's anchor point and direction. + setVectors: function(anchor, direction) { + // Need to do this so that line's properties are not + // references to the arguments passed in + anchor = Vector.create(anchor); + direction = Vector.create(direction); + if (anchor.elements.length == 2) {anchor.elements.push(0); } + if (direction.elements.length == 2) { direction.elements.push(0); } + if (anchor.elements.length > 3 || direction.elements.length > 3) { return null; } + var mod = direction.modulus(); + if (mod === 0) { return null; } + this.anchor = anchor; + this.direction = Vector.create([ + direction.elements[0] / mod, + direction.elements[1] / mod, + direction.elements[2] / mod + ]); + return this; + } +}; + +// Constructor function +Line.create = function(anchor, direction) { + var L = new Line(); + return L.setVectors(anchor, direction); +}; + +// Axes +Line.X = Line.create(Vector.Zero(3), Vector.i); +Line.Y = Line.create(Vector.Zero(3), Vector.j); +Line.Z = Line.create(Vector.Zero(3), Vector.k); + +module.exports = Line; + +},{"./matrix":15,"./plane":16,"./sylvester":17,"./vector":18}],14:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// Line.Segment class - depends on Line and its dependencies. + +var Line = require('./line'); +var Vector = require('./vector'); + +Line.Segment = function() {}; +Line.Segment.prototype = { + + // Returns true iff the line segment is equal to the argument + eql: function(segment) { + return (this.start.eql(segment.start) && this.end.eql(segment.end)) || + (this.start.eql(segment.end) && this.end.eql(segment.start)); + }, + + // Returns a copy of the line segment + dup: function() { + return Line.Segment.create(this.start, this.end); + }, + + // Returns the length of the line segment + length: function() { + var A = this.start.elements, B = this.end.elements; + var C1 = B[0] - A[0], C2 = B[1] - A[1], C3 = B[2] - A[2]; + return Math.sqrt(C1*C1 + C2*C2 + C3*C3); + }, + + // Returns the line segment as a vector equal to its + // end point relative to its endpoint + toVector: function() { + var A = this.start.elements, B = this.end.elements; + return Vector.create([B[0] - A[0], B[1] - A[1], B[2] - A[2]]); + }, + + // Returns the segment's midpoint as a vector + midpoint: function() { + var A = this.start.elements, B = this.end.elements; + return Vector.create([(B[0] + A[0])/2, (B[1] + A[1])/2, (B[2] + A[2])/2]); + }, + + // Returns the plane that bisects the segment + bisectingPlane: function() { + return Plane.create(this.midpoint(), this.toVector()); + }, + + // Returns the result of translating the line by the given vector/array + translate: function(vector) { + var V = vector.elements || vector; + var S = this.start.elements, E = this.end.elements; + return Line.Segment.create( + [S[0] + V[0], S[1] + V[1], S[2] + (V[2] || 0)], + [E[0] + V[0], E[1] + V[1], E[2] + (V[2] || 0)] + ); + }, + + // Returns true iff the line segment is parallel to the argument. It simply forwards + // the method call onto its line property. + isParallelTo: function(obj) { + return this.line.isParallelTo(obj); + }, + + // Returns the distance between the argument and the line segment's closest point to the argument + distanceFrom: function(obj) { + var P = this.pointClosestTo(obj); + return (P === null) ? null : P.distanceFrom(obj); + }, + + // Returns true iff the given point lies on the segment + contains: function(obj) { + if (obj.start && obj.end) { return this.contains(obj.start) && this.contains(obj.end); } + var P = (obj.elements || obj).slice(); + if (P.length == 2) { P.push(0); } + if (this.start.eql(P)) { return true; } + var S = this.start.elements; + var V = Vector.create([S[0] - P[0], S[1] - P[1], S[2] - (P[2] || 0)]); + var vect = this.toVector(); + return V.isAntiparallelTo(vect) && V.modulus() <= vect.modulus(); + }, + + // Returns true iff the line segment intersects the argument + intersects: function(obj) { + return (this.intersectionWith(obj) !== null); + }, + + // Returns the unique point of intersection with the argument + intersectionWith: function(obj) { + if (!this.line.intersects(obj)) { return null; } + var P = this.line.intersectionWith(obj); + return (this.contains(P) ? P : null); + }, + + // Returns the point on the line segment closest to the given object + pointClosestTo: function(obj) { + if (obj.normal) { + // obj is a plane + var V = this.line.intersectionWith(obj); + if (V === null) { return null; } + return this.pointClosestTo(V); + } else { + // obj is a line (segment) or point + var P = this.line.pointClosestTo(obj); + if (P === null) { return null; } + if (this.contains(P)) { return P; } + return (this.line.positionOf(P) < 0 ? this.start : this.end).dup(); + } + }, + + // Set the start and end-points of the segment + setPoints: function(startPoint, endPoint) { + startPoint = Vector.create(startPoint).to3D(); + endPoint = Vector.create(endPoint).to3D(); + if (startPoint === null || endPoint === null) { return null; } + this.line = Line.create(startPoint, endPoint.subtract(startPoint)); + this.start = startPoint; + this.end = endPoint; + return this; + } +}; + +// Constructor function +Line.Segment.create = function(v1, v2) { + var S = new Line.Segment(); + return S.setPoints(v1, v2); +}; + +module.exports = Line.Segment; + +},{"./line":13,"./vector":18}],15:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// Matrix class - depends on Vector. + +var Sylvester = require('./sylvester'); +var Vector = require('./vector'); + +// augment a matrix M with identity rows/cols +function identSize(M, m, n, k) { + var e = M.elements; + var i = k - 1; + + while(i--) { + var row = []; + + for(var j = 0; j < n; j++) + row.push(j == i ? 1 : 0); + + e.unshift(row); + } + + for(var i = k - 1; i < m; i++) { + while(e[i].length < n) + e[i].unshift(0); + } + + return $M(e); +} + +function pca(X) { + var Sigma = X.transpose().x(X).x(1 / X.rows()); + var svd = Sigma.svd(); + return {U: svd.U, S: svd.S}; +} + +// singular value decomposition in pure javascript +function svdJs() { + var A = this; + var V = Matrix.I(A.rows()); + var S = A.transpose(); + var U = Matrix.I(A.cols()); + var err = Number.MAX_VALUE; + var i = 0; + var maxLoop = 100; + + while(err > 2.2737e-13 && i < maxLoop) { + var qr = S.transpose().qrJs(); + S = qr.R; + V = V.x(qr.Q); + qr = S.transpose().qrJs(); + U = U.x(qr.Q); + S = qr.R; + + var e = S.triu(1).unroll().norm(); + var f = S.diagonal().norm(); + + if(f == 0) + f = 1; + + err = e / f; + + i++; + } + + var ss = S.diagonal(); + var s = []; + + for(var i = 1; i <= ss.cols(); i++) { + var ssn = ss.e(i); + s.push(Math.abs(ssn)); + + if(ssn < 0) { + for(var j = 0; j < U.rows(); j++) { + V.elements[j][i - 1] = -(V.elements[j][i - 1]); + } + } + } + + return {U: U, S: $V(s).toDiagonalMatrix(), V: V}; +} + + + +// QR decomposition in pure javascript +function qrJs() { + var m = this.rows(); + var n = this.cols(); + var Q = Matrix.I(m); + var A = this; + + for(var k = 1; k < Math.min(m, n); k++) { + var ak = A.slice(k, 0, k, k).col(1); + var oneZero = [1]; + + while(oneZero.length <= m - k) + oneZero.push(0); + + oneZero = $V(oneZero); + var vk = ak.add(oneZero.x(ak.norm() * Math.sign(ak.e(1)))); + var Vk = $M(vk); + var Hk = Matrix.I(m - k + 1).subtract(Vk.x(2).x(Vk.transpose()).div(Vk.transpose().x(Vk).e(1, 1))); + var Qk = identSize(Hk, m, n, k); + A = Qk.x(A); + // slow way to compute Q + Q = Q.x(Qk); + } + + return {Q: Q, R: A}; +} + + + + +function Matrix() {} +Matrix.prototype = { + // solve a system of linear equations (work in progress) + solve: function(b) { + var lu = this.lu(); + b = lu.P.x(b); + var y = lu.L.forwardSubstitute(b); + var x = lu.U.backSubstitute(y); + return lu.P.x(x); + //return this.inv().x(b); + }, + + // project a matrix onto a lower dim + pcaProject: function(k, U) { + var U = U || pca(this).U; + var Ureduce= U.slice(1, U.rows(), 1, k); + return {Z: this.x(Ureduce), U: U}; + }, + + // recover a matrix to a higher dimension + pcaRecover: function(U) { + var k = this.cols(); + var Ureduce = U.slice(1, U.rows(), 1, k); + return this.x(Ureduce.transpose()); + }, + + // grab the upper triangular part of the matrix + triu: function(k) { + if(!k) + k = 0; + + return this.map(function(x, i, j) { + return j - i >= k ? x : 0; + }); + }, + + // unroll a matrix into a vector + unroll: function() { + var v = []; + + for(var i = 1; i <= this.cols(); i++) { + for(var j = 1; j <= this.rows(); j++) { + v.push(this.e(j, i)); + } + } + + return $V(v); + }, + + // return a sub-block of the matrix + slice: function(startRow, endRow, startCol, endCol) { + var x = []; + + if(endRow == 0) + endRow = this.rows(); + + if(endCol == 0) + endCol = this.cols(); + + for(i = startRow; i <= endRow; i++) { + var row = []; + + for(j = startCol; j <= endCol; j++) { + row.push(this.e(i, j)); + } + + x.push(row); + } + + return $M(x); + }, + + // Returns element (i,j) of the matrix + e: function(i,j) { + if (i < 1 || i > this.elements.length || j < 1 || j > this.elements[0].length) { return null; } + return this.elements[i - 1][j - 1]; + }, + + // Returns row k of the matrix as a vector + row: function(i) { + if (i > this.elements.length) { return null; } + return $V(this.elements[i - 1]); + }, + + // Returns column k of the matrix as a vector + col: function(j) { + if (j > this.elements[0].length) { return null; } + var col = [], n = this.elements.length; + for (var i = 0; i < n; i++) { col.push(this.elements[i][j - 1]); } + return $V(col); + }, + + // Returns the number of rows/columns the matrix has + dimensions: function() { + return {rows: this.elements.length, cols: this.elements[0].length}; + }, + + // Returns the number of rows in the matrix + rows: function() { + return this.elements.length; + }, + + // Returns the number of columns in the matrix + cols: function() { + return this.elements[0].length; + }, + + approxEql: function(matrix) { + return this.eql(matrix, Sylvester.approxPrecision); + }, + + // Returns true iff the matrix is equal to the argument. You can supply + // a vector as the argument, in which case the receiver must be a + // one-column matrix equal to the vector. + eql: function(matrix, precision) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + if (this.elements.length != M.length || + this.elements[0].length != M[0].length) { return false; } + var i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { j = nj; + while (j--) { + if (Math.abs(this.elements[i][j] - M[i][j]) > (precision || Sylvester.precision)) { return false; } + } + } + return true; + }, + + // Returns a copy of the matrix + dup: function() { + return Matrix.create(this.elements); + }, + + // Maps the matrix to another matrix (of the same dimensions) according to the given function + map: function(fn) { + var els = [], i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { j = nj; + els[i] = []; + while (j--) { + els[i][j] = fn(this.elements[i][j], i + 1, j + 1); + } + } + return Matrix.create(els); + }, + + // Returns true iff the argument has the same dimensions as the matrix + isSameSizeAs: function(matrix) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + return (this.elements.length == M.length && + this.elements[0].length == M[0].length); + }, + + // Returns the result of adding the argument to the matrix + add: function(matrix) { + if(typeof(matrix) == 'number') { + return this.map(function(x, i, j) { return x + matrix}); + } else { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + if (!this.isSameSizeAs(M)) { return null; } + return this.map(function(x, i, j) { return x + M[i - 1][j - 1]; }); + } + }, + + // Returns the result of subtracting the argument from the matrix + subtract: function(matrix) { + if(typeof(matrix) == 'number') { + return this.map(function(x, i, j) { return x - matrix}); + } else { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + if (!this.isSameSizeAs(M)) { return null; } + return this.map(function(x, i, j) { return x - M[i - 1][j - 1]; }); + } + }, + + // Returns true iff the matrix can multiply the argument from the left + canMultiplyFromLeft: function(matrix) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + // this.columns should equal matrix.rows + return (this.elements[0].length == M.length); + }, + + // Returns the result of a multiplication-style operation the matrix from the right by the argument. + // If the argument is a scalar then just operate on all the elements. If the argument is + // a vector, a vector is returned, which saves you having to remember calling + // col(1) on the result. + mulOp: function(matrix, op) { + if (!matrix.elements) { + return this.map(function(x) { return op(x, matrix); }); + } + + var returnVector = matrix.modulus ? true : false; + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') + M = Matrix.create(M).elements; + if (!this.canMultiplyFromLeft(M)) + return null; + var e = this.elements, rowThis, rowElem, elements = [], + sum, m = e.length, n = M[0].length, o = e[0].length, i = m, j, k; + + while (i--) { + rowElem = []; + rowThis = e[i]; + j = n; + + while (j--) { + sum = 0; + k = o; + + while (k--) { + sum += op(rowThis[k], M[k][j]); + } + + rowElem[j] = sum; + } + + elements[i] = rowElem; + } + + var M = Matrix.create(elements); + return returnVector ? M.col(1) : M; + }, + + // Returns the result of dividing the matrix from the right by the argument. + // If the argument is a scalar then just divide all the elements. If the argument is + // a vector, a vector is returned, which saves you having to remember calling + // col(1) on the result. + div: function(matrix) { + return this.mulOp(matrix, function(x, y) { return x / y}); + }, + + // Returns the result of multiplying the matrix from the right by the argument. + // If the argument is a scalar then just multiply all the elements. If the argument is + // a vector, a vector is returned, which saves you having to remember calling + // col(1) on the result. + multiply: function(matrix) { + return this.mulOp(matrix, function(x, y) { return x * y}); + }, + + x: function(matrix) { return this.multiply(matrix); }, + + elementMultiply: function(v) { + return this.map(function(k, i, j) { + return v.e(i, j) * k; + }); + }, + + // sum all elements in the matrix + sum: function() { + var sum = 0; + + this.map(function(x) { sum += x;}); + + return sum; + }, + + // Returns a Vector of each colum averaged. + mean: function() { + var dim = this.dimensions(); + var r = []; + for (var i = 1; i <= dim.cols; i++) { + r.push(this.col(i).sum() / dim.rows); + } + return $V(r); + }, + + column: function(n) { + return this.col(n); + }, + + // element-wise log + log: function() { + return this.map(function(x) { return Math.log(x); }); + }, + + // Returns a submatrix taken from the matrix + // Argument order is: start row, start col, nrows, ncols + // Element selection wraps if the required index is outside the matrix's bounds, so you could + // use this to perform row/column cycling or copy-augmenting. + minor: function(a, b, c, d) { + var elements = [], ni = c, i, nj, j; + var rows = this.elements.length, cols = this.elements[0].length; + while (ni--) { + i = c - ni - 1; + elements[i] = []; + nj = d; + while (nj--) { + j = d - nj - 1; + elements[i][j] = this.elements[(a + i - 1) % rows][(b + j - 1) % cols]; + } + } + return Matrix.create(elements); + }, + + // Returns the transpose of the matrix + transpose: function() { + var rows = this.elements.length, i, cols = this.elements[0].length, j; + var elements = [], i = cols; + while (i--) { + j = rows; + elements[i] = []; + while (j--) { + elements[i][j] = this.elements[j][i]; + } + } + return Matrix.create(elements); + }, + + // Returns true iff the matrix is square + isSquare: function() { + return (this.elements.length == this.elements[0].length); + }, + + // Returns the (absolute) largest element of the matrix + max: function() { + var m = 0, i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { + j = nj; + while (j--) { + if (Math.abs(this.elements[i][j]) > Math.abs(m)) { m = this.elements[i][j]; } + } + } + return m; + }, + + // Returns the indeces of the first match found by reading row-by-row from left to right + indexOf: function(x) { + var index = null, ni = this.elements.length, i, nj = this.elements[0].length, j; + for (i = 0; i < ni; i++) { + for (j = 0; j < nj; j++) { + if (this.elements[i][j] == x) { return {i: i + 1, j: j + 1}; } + } + } + return null; + }, + + // If the matrix is square, returns the diagonal elements as a vector. + // Otherwise, returns null. + diagonal: function() { + if (!this.isSquare) { return null; } + var els = [], n = this.elements.length; + for (var i = 0; i < n; i++) { + els.push(this.elements[i][i]); + } + return $V(els); + }, + + // Make the matrix upper (right) triangular by Gaussian elimination. + // This method only adds multiples of rows to other rows. No rows are + // scaled up or switched, and the determinant is preserved. + toRightTriangular: function() { + var M = this.dup(), els; + var n = this.elements.length, i, j, np = this.elements[0].length, p; + for (i = 0; i < n; i++) { + if (M.elements[i][i] == 0) { + for (j = i + 1; j < n; j++) { + if (M.elements[j][i] != 0) { + els = []; + for (p = 0; p < np; p++) { els.push(M.elements[i][p] + M.elements[j][p]); } + M.elements[i] = els; + break; + } + } + } + if (M.elements[i][i] != 0) { + for (j = i + 1; j < n; j++) { + var multiplier = M.elements[j][i] / M.elements[i][i]; + els = []; + for (p = 0; p < np; p++) { + // Elements with column numbers up to an including the number + // of the row that we're subtracting can safely be set straight to + // zero, since that's the point of this routine and it avoids having + // to loop over and correct rounding errors later + els.push(p <= i ? 0 : M.elements[j][p] - M.elements[i][p] * multiplier); + } + M.elements[j] = els; + } + } + } + return M; + }, + + toUpperTriangular: function() { return this.toRightTriangular(); }, + + // Returns the determinant for square matrices + determinant: function() { + if (!this.isSquare()) { return null; } + if (this.cols == 1 && this.rows == 1) { return this.row(1); } + if (this.cols == 0 && this.rows == 0) { return 1; } + var M = this.toRightTriangular(); + var det = M.elements[0][0], n = M.elements.length; + for (var i = 1; i < n; i++) { + det = det * M.elements[i][i]; + } + return det; + }, + det: function() { return this.determinant(); }, + + // Returns true iff the matrix is singular + isSingular: function() { + return (this.isSquare() && this.determinant() === 0); + }, + + // Returns the trace for square matrices + trace: function() { + if (!this.isSquare()) { return null; } + var tr = this.elements[0][0], n = this.elements.length; + for (var i = 1; i < n; i++) { + tr += this.elements[i][i]; + } + return tr; + }, + + tr: function() { return this.trace(); }, + + // Returns the rank of the matrix + rank: function() { + var M = this.toRightTriangular(), rank = 0; + var i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { + j = nj; + while (j--) { + if (Math.abs(M.elements[i][j]) > Sylvester.precision) { rank++; break; } + } + } + return rank; + }, + + rk: function() { return this.rank(); }, + + // Returns the result of attaching the given argument to the right-hand side of the matrix + augment: function(matrix) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + var T = this.dup(), cols = T.elements[0].length; + var i = T.elements.length, nj = M[0].length, j; + if (i != M.length) { return null; } + while (i--) { + j = nj; + while (j--) { + T.elements[i][cols + j] = M[i][j]; + } + } + return T; + }, + + // Returns the inverse (if one exists) using Gauss-Jordan + inverse: function() { + if (!this.isSquare() || this.isSingular()) { return null; } + var n = this.elements.length, i = n, j; + var M = this.augment(Matrix.I(n)).toRightTriangular(); + var np = M.elements[0].length, p, els, divisor; + var inverse_elements = [], new_element; + // Matrix is non-singular so there will be no zeros on the diagonal + // Cycle through rows from last to first + while (i--) { + // First, normalise diagonal elements to 1 + els = []; + inverse_elements[i] = []; + divisor = M.elements[i][i]; + for (p = 0; p < np; p++) { + new_element = M.elements[i][p] / divisor; + els.push(new_element); + // Shuffle off the current row of the right hand side into the results + // array as it will not be modified by later runs through this loop + if (p >= n) { inverse_elements[i].push(new_element); } + } + M.elements[i] = els; + // Then, subtract this row from those above it to + // give the identity matrix on the left hand side + j = i; + while (j--) { + els = []; + for (p = 0; p < np; p++) { + els.push(M.elements[j][p] - M.elements[i][p] * M.elements[j][i]); + } + M.elements[j] = els; + } + } + return Matrix.create(inverse_elements); + }, + + inv: function() { return this.inverse(); }, + + // Returns the result of rounding all the elements + round: function() { + return this.map(function(x) { return Math.round(x); }); + }, + + // Returns a copy of the matrix with elements set to the given value if they + // differ from it by less than Sylvester.precision + snapTo: function(x) { + return this.map(function(p) { + return (Math.abs(p - x) <= Sylvester.precision) ? x : p; + }); + }, + + // Returns a string representation of the matrix + inspect: function() { + var matrix_rows = []; + var n = this.elements.length; + for (var i = 0; i < n; i++) { + matrix_rows.push($V(this.elements[i]).inspect()); + } + return matrix_rows.join('\n'); + }, + + // Returns a array representation of the matrix + toArray: function() { + var matrix_rows = []; + var n = this.elements.length; + for (var i = 0; i < n; i++) { + matrix_rows.push(this.elements[i]); + } + return matrix_rows; + }, + + + // Set the matrix's elements from an array. If the argument passed + // is a vector, the resulting matrix will be a single column. + setElements: function(els) { + var i, j, elements = els.elements || els; + if (typeof(elements[0][0]) != 'undefined') { + i = elements.length; + this.elements = []; + while (i--) { + j = elements[i].length; + this.elements[i] = []; + while (j--) { + this.elements[i][j] = elements[i][j]; + } + } + return this; + } + var n = elements.length; + this.elements = []; + for (i = 0; i < n; i++) { + this.elements.push([elements[i]]); + } + return this; + }, + + // return the indexes of the columns with the largest value + // for each row + maxColumnIndexes: function() { + var maxes = []; + + for(var i = 1; i <= this.rows(); i++) { + var max = null; + var maxIndex = -1; + + for(var j = 1; j <= this.cols(); j++) { + if(max === null || this.e(i, j) > max) { + max = this.e(i, j); + maxIndex = j; + } + } + + maxes.push(maxIndex); + } + + return $V(maxes); + }, + + // return the largest values in each row + maxColumns: function() { + var maxes = []; + + for(var i = 1; i <= this.rows(); i++) { + var max = null; + + for(var j = 1; j <= this.cols(); j++) { + if(max === null || this.e(i, j) > max) { + max = this.e(i, j); + } + } + + maxes.push(max); + } + + return $V(maxes); + }, + + // return the indexes of the columns with the smallest values + // for each row + minColumnIndexes: function() { + var mins = []; + + for(var i = 1; i <= this.rows(); i++) { + var min = null; + var minIndex = -1; + + for(var j = 1; j <= this.cols(); j++) { + if(min === null || this.e(i, j) < min) { + min = this.e(i, j); + minIndex = j; + } + } + + mins.push(minIndex); + } + + return $V(mins); + }, + + // return the smallest values in each row + minColumns: function() { + var mins = []; + + for(var i = 1; i <= this.rows(); i++) { + var min = null; + + for(var j = 1; j <= this.cols(); j++) { + if(min === null || this.e(i, j) < min) { + min = this.e(i, j); + } + } + + mins.push(min); + } + + return $V(mins); + }, + + // perorm a partial pivot on the matrix. essentially move the largest + // row below-or-including the pivot and replace the pivot's row with it. + // a pivot matrix is returned so multiplication can perform the transform. + partialPivot: function(k, j, P, A, L) { + var maxIndex = 0; + var maxValue = 0; + + for(var i = k; i <= A.rows(); i++) { + if(Math.abs(A.e(i, j)) > maxValue) { + maxValue = Math.abs(A.e(k, j)); + maxIndex = i; + } + } + + if(maxIndex != k) { + var tmp = A.elements[k - 1]; + A.elements[k - 1] = A.elements[maxIndex - 1]; + A.elements[maxIndex - 1] = tmp; + + P.elements[k - 1][k - 1] = 0; + P.elements[k - 1][maxIndex - 1] = 1; + P.elements[maxIndex - 1][maxIndex - 1] = 0; + P.elements[maxIndex - 1][k - 1] = 1; + } + + return P; + }, + + // solve lower-triangular matrix * x = b via forward substitution + forwardSubstitute: function(b) { + var xa = []; + + for(var i = 1; i <= this.rows(); i++) { + var w = 0; + + for(var j = 1; j < i; j++) { + w += this.e(i, j) * xa[j - 1]; + } + + xa.push((b.e(i) - w) / this.e(i, i)); + } + + return $V(xa); + }, + + // solve an upper-triangular matrix * x = b via back substitution + backSubstitute: function(b) { + var xa = []; + + for(var i = this.rows(); i > 0; i--) { + var w = 0; + + for(var j = this.cols(); j > i; j--) { + w += this.e(i, j) * xa[this.rows() - j]; + } + + xa.push((b.e(i) - w) / this.e(i, i)); + } + + return $V(xa.reverse()); + }, + + luJs: luJs, + svdJs: svdJs, + qrJs: qrJs, +}; + + +var tolerance = 1.4901e-08; + +// pure Javascript LU factorization +function luJs() { + var A = this.dup(); + var L = Matrix.I(A.rows()); + var P = Matrix.I(A.rows()); + var U = Matrix.Zeros(A.rows(), A.cols()); + var p = 1; + + for(var k = 1; k <= Math.min(A.cols(), A.rows()); k++) { + P = A.partialPivot(k, p, P, A, L); + + for(var i = k + 1; i <= A.rows(); i++) { + var l = A.e(i, p) / A.e(k, p); + L.elements[i - 1][k - 1] = l; + + for(var j = k + 1 ; j <= A.cols(); j++) { + A.elements[i - 1][j - 1] -= A.e(k, j) * l; + } + } + + for(var j = k; j <= A.cols(); j++) { + U.elements[k - 1][j - 1] = A.e(k, j); + } + + if(p < A.cols()) + p++; + } + + return {L: L, U: U, P: P}; +} + + + +Matrix.prototype.svd = svdJs; +Matrix.prototype.qr = qrJs; +Matrix.prototype.lu = luJs; + +// Constructor function +Matrix.create = function(aElements) { + var M = new Matrix().setElements(aElements); + return M; +}; + +// Identity matrix of size n +Matrix.I = function(n) { + var els = [], i = n, j; + while (i--) { + j = n; + els[i] = []; + while (j--) { + els[i][j] = (i == j) ? 1 : 0; + } + } + return Matrix.create(els); +}; + +Matrix.loadFile = function(file) { + var fs = require('fs'); + var contents = fs.readFileSync(file, 'utf-8'); + var matrix = []; + + var rowArray = contents.split('\n'); + for (var i = 0; i < rowArray.length; i++) { + var d = rowArray[i].split(','); + if (d.length > 1) { + matrix.push(d); + } + } + + var M = new Matrix(); + return M.setElements(matrix); +}; + +// Diagonal matrix - all off-diagonal elements are zero +Matrix.Diagonal = function(elements) { + var i = elements.length; + var M = Matrix.I(i); + while (i--) { + M.elements[i][i] = elements[i]; + } + return M; +}; + +// Rotation matrix about some axis. If no axis is +// supplied, assume we're after a 2D transform +Matrix.Rotation = function(theta, a) { + if (!a) { + return Matrix.create([ + [Math.cos(theta), -Math.sin(theta)], + [Math.sin(theta), Math.cos(theta)] + ]); + } + var axis = a.dup(); + if (axis.elements.length != 3) { return null; } + var mod = axis.modulus(); + var x = axis.elements[0] / mod, y = axis.elements[1] / mod, z = axis.elements[2] / mod; + var s = Math.sin(theta), c = Math.cos(theta), t = 1 - c; + // Formula derived here: http://www.gamedev.net/reference/articles/article1199.asp + // That proof rotates the co-ordinate system so theta + // becomes -theta and sin becomes -sin here. + return Matrix.create([ + [t * x * x + c, t * x * y - s * z, t * x * z + s * y], + [t * x * y + s * z, t * y * y + c, t * y * z - s * x], + [t * x * z - s * y, t * y * z + s * x, t * z * z + c] + ]); +}; + +// Special case rotations +Matrix.RotationX = function(t) { + var c = Math.cos(t), s = Math.sin(t); + return Matrix.create([ + [1, 0, 0], + [0, c, -s], + [0, s, c] + ]); +}; + +Matrix.RotationY = function(t) { + var c = Math.cos(t), s = Math.sin(t); + return Matrix.create([ + [c, 0, s], + [0, 1, 0], + [-s, 0, c] + ]); +}; + +Matrix.RotationZ = function(t) { + var c = Math.cos(t), s = Math.sin(t); + return Matrix.create([ + [c, -s, 0], + [s, c, 0], + [0, 0, 1] + ]); +}; + +// Random matrix of n rows, m columns +Matrix.Random = function(n, m) { + if (arguments.length === 1) m = n; + return Matrix.Zero(n, m).map( + function() { return Math.random(); } + ); +}; + +Matrix.Fill = function(n, m, v) { + if (arguments.length === 2) { + v = m; + m = n; + } + + var els = [], i = n, j; + + while (i--) { + j = m; + els[i] = []; + + while (j--) { + els[i][j] = v; + } + } + + return Matrix.create(els); +}; + +// Matrix filled with zeros +Matrix.Zero = function(n, m) { + return Matrix.Fill(n, m, 0); +}; + +// Matrix filled with zeros +Matrix.Zeros = function(n, m) { + return Matrix.Zero(n, m); +}; + +// Matrix filled with ones +Matrix.One = function(n, m) { + return Matrix.Fill(n, m, 1); +}; + +// Matrix filled with ones +Matrix.Ones = function(n, m) { + return Matrix.One(n, m); +}; + +module.exports = Matrix; + +},{"./sylvester":17,"./vector":18,"fs":undefined}],16:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// Plane class - depends on Vector. Some methods require Matrix and Line. +var Vector = require('./vector'); +var Matrix = require('./matrix'); +var Line = require('./line'); + +var Sylvester = require('./sylvester'); + +function Plane() {} +Plane.prototype = { + + // Returns true iff the plane occupies the same space as the argument + eql: function(plane) { + return (this.contains(plane.anchor) && this.isParallelTo(plane)); + }, + + // Returns a copy of the plane + dup: function() { + return Plane.create(this.anchor, this.normal); + }, + + // Returns the result of translating the plane by the given vector + translate: function(vector) { + var V = vector.elements || vector; + return Plane.create([ + this.anchor.elements[0] + V[0], + this.anchor.elements[1] + V[1], + this.anchor.elements[2] + (V[2] || 0) + ], this.normal); + }, + + // Returns true iff the plane is parallel to the argument. Will return true + // if the planes are equal, or if you give a line and it lies in the plane. + isParallelTo: function(obj) { + var theta; + if (obj.normal) { + // obj is a plane + theta = this.normal.angleFrom(obj.normal); + return (Math.abs(theta) <= Sylvester.precision || Math.abs(Math.PI - theta) <= Sylvester.precision); + } else if (obj.direction) { + // obj is a line + return this.normal.isPerpendicularTo(obj.direction); + } + return null; + }, + + // Returns true iff the receiver is perpendicular to the argument + isPerpendicularTo: function(plane) { + var theta = this.normal.angleFrom(plane.normal); + return (Math.abs(Math.PI/2 - theta) <= Sylvester.precision); + }, + + // Returns the plane's distance from the given object (point, line or plane) + distanceFrom: function(obj) { + if (this.intersects(obj) || this.contains(obj)) { return 0; } + if (obj.anchor) { + // obj is a plane or line + var A = this.anchor.elements, B = obj.anchor.elements, N = this.normal.elements; + return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]); + } else { + // obj is a point + var P = obj.elements || obj; + var A = this.anchor.elements, N = this.normal.elements; + return Math.abs((A[0] - P[0]) * N[0] + (A[1] - P[1]) * N[1] + (A[2] - (P[2] || 0)) * N[2]); + } + }, + + // Returns true iff the plane contains the given point or line + contains: function(obj) { + if (obj.normal) { return null; } + if (obj.direction) { + return (this.contains(obj.anchor) && this.contains(obj.anchor.add(obj.direction))); + } else { + var P = obj.elements || obj; + var A = this.anchor.elements, N = this.normal.elements; + var diff = Math.abs(N[0]*(A[0] - P[0]) + N[1]*(A[1] - P[1]) + N[2]*(A[2] - (P[2] || 0))); + return (diff <= Sylvester.precision); + } + }, + + // Returns true iff the plane has a unique point/line of intersection with the argument + intersects: function(obj) { + if (typeof(obj.direction) == 'undefined' && typeof(obj.normal) == 'undefined') { return null; } + return !this.isParallelTo(obj); + }, + + // Returns the unique intersection with the argument, if one exists. The result + // will be a vector if a line is supplied, and a line if a plane is supplied. + intersectionWith: function(obj) { + if (!this.intersects(obj)) { return null; } + if (obj.direction) { + // obj is a line + var A = obj.anchor.elements, D = obj.direction.elements, + P = this.anchor.elements, N = this.normal.elements; + var multiplier = (N[0]*(P[0]-A[0]) + N[1]*(P[1]-A[1]) + N[2]*(P[2]-A[2])) / (N[0]*D[0] + N[1]*D[1] + N[2]*D[2]); + return Vector.create([A[0] + D[0]*multiplier, A[1] + D[1]*multiplier, A[2] + D[2]*multiplier]); + } else if (obj.normal) { + // obj is a plane + var direction = this.normal.cross(obj.normal).toUnitVector(); + // To find an anchor point, we find one co-ordinate that has a value + // of zero somewhere on the intersection, and remember which one we picked + var N = this.normal.elements, A = this.anchor.elements, + O = obj.normal.elements, B = obj.anchor.elements; + var solver = Matrix.Zero(2,2), i = 0; + while (solver.isSingular()) { + i++; + solver = Matrix.create([ + [ N[i%3], N[(i+1)%3] ], + [ O[i%3], O[(i+1)%3] ] + ]); + } + // Then we solve the simultaneous equations in the remaining dimensions + var inverse = solver.inverse().elements; + var x = N[0]*A[0] + N[1]*A[1] + N[2]*A[2]; + var y = O[0]*B[0] + O[1]*B[1] + O[2]*B[2]; + var intersection = [ + inverse[0][0] * x + inverse[0][1] * y, + inverse[1][0] * x + inverse[1][1] * y + ]; + var anchor = []; + for (var j = 1; j <= 3; j++) { + // This formula picks the right element from intersection by + // cycling depending on which element we set to zero above + anchor.push((i == j) ? 0 : intersection[(j + (5 - i)%3)%3]); + } + return Line.create(anchor, direction); + } + }, + + // Returns the point in the plane closest to the given point + pointClosestTo: function(point) { + var P = point.elements || point; + var A = this.anchor.elements, N = this.normal.elements; + var dot = (A[0] - P[0]) * N[0] + (A[1] - P[1]) * N[1] + (A[2] - (P[2] || 0)) * N[2]; + return Vector.create([P[0] + N[0] * dot, P[1] + N[1] * dot, (P[2] || 0) + N[2] * dot]); + }, + + // Returns a copy of the plane, rotated by t radians about the given line + // See notes on Line#rotate. + rotate: function(t, line) { + var R = t.determinant ? t.elements : Matrix.Rotation(t, line.direction).elements; + var C = line.pointClosestTo(this.anchor).elements; + var A = this.anchor.elements, N = this.normal.elements; + var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2]; + var x = A1 - C1, y = A2 - C2, z = A3 - C3; + return Plane.create([ + C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z, + C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z, + C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z + ], [ + R[0][0] * N[0] + R[0][1] * N[1] + R[0][2] * N[2], + R[1][0] * N[0] + R[1][1] * N[1] + R[1][2] * N[2], + R[2][0] * N[0] + R[2][1] * N[1] + R[2][2] * N[2] + ]); + }, + + // Returns the reflection of the plane in the given point, line or plane. + reflectionIn: function(obj) { + if (obj.normal) { + // obj is a plane + var A = this.anchor.elements, N = this.normal.elements; + var A1 = A[0], A2 = A[1], A3 = A[2], N1 = N[0], N2 = N[1], N3 = N[2]; + var newA = this.anchor.reflectionIn(obj).elements; + // Add the plane's normal to its anchor, then mirror that in the other plane + var AN1 = A1 + N1, AN2 = A2 + N2, AN3 = A3 + N3; + var Q = obj.pointClosestTo([AN1, AN2, AN3]).elements; + var newN = [Q[0] + (Q[0] - AN1) - newA[0], Q[1] + (Q[1] - AN2) - newA[1], Q[2] + (Q[2] - AN3) - newA[2]]; + return Plane.create(newA, newN); + } else if (obj.direction) { + // obj is a line + return this.rotate(Math.PI, obj); + } else { + // obj is a point + var P = obj.elements || obj; + return Plane.create(this.anchor.reflectionIn([P[0], P[1], (P[2] || 0)]), this.normal); + } + }, + + // Sets the anchor point and normal to the plane. If three arguments are specified, + // the normal is calculated by assuming the three points should lie in the same plane. + // If only two are sepcified, the second is taken to be the normal. Normal vector is + // normalised before storage. + setVectors: function(anchor, v1, v2) { + anchor = Vector.create(anchor); + anchor = anchor.to3D(); if (anchor === null) { return null; } + v1 = Vector.create(v1); + v1 = v1.to3D(); if (v1 === null) { return null; } + if (typeof(v2) == 'undefined') { + v2 = null; + } else { + v2 = Vector.create(v2); + v2 = v2.to3D(); if (v2 === null) { return null; } + } + var A1 = anchor.elements[0], A2 = anchor.elements[1], A3 = anchor.elements[2]; + var v11 = v1.elements[0], v12 = v1.elements[1], v13 = v1.elements[2]; + var normal, mod; + if (v2 !== null) { + var v21 = v2.elements[0], v22 = v2.elements[1], v23 = v2.elements[2]; + normal = Vector.create([ + (v12 - A2) * (v23 - A3) - (v13 - A3) * (v22 - A2), + (v13 - A3) * (v21 - A1) - (v11 - A1) * (v23 - A3), + (v11 - A1) * (v22 - A2) - (v12 - A2) * (v21 - A1) + ]); + mod = normal.modulus(); + if (mod === 0) { return null; } + normal = Vector.create([normal.elements[0] / mod, normal.elements[1] / mod, normal.elements[2] / mod]); + } else { + mod = Math.sqrt(v11*v11 + v12*v12 + v13*v13); + if (mod === 0) { return null; } + normal = Vector.create([v1.elements[0] / mod, v1.elements[1] / mod, v1.elements[2] / mod]); + } + this.anchor = anchor; + this.normal = normal; + return this; + } +}; + +// Constructor function +Plane.create = function(anchor, v1, v2) { + var P = new Plane(); + return P.setVectors(anchor, v1, v2); +}; + +// X-Y-Z planes +Plane.XY = Plane.create(Vector.Zero(3), Vector.k); +Plane.YZ = Plane.create(Vector.Zero(3), Vector.i); +Plane.ZX = Plane.create(Vector.Zero(3), Vector.j); +Plane.YX = Plane.XY; Plane.ZY = Plane.YZ; Plane.XZ = Plane.ZX; + +// Returns the plane containing the given points (can be arrays as +// well as vectors). If the points are not coplanar, returns null. +Plane.fromPoints = function(points) { + var np = points.length, list = [], i, P, n, N, A, B, C, D, theta, prevN, totalN = Vector.Zero(3); + for (i = 0; i < np; i++) { + P = Vector.create(points[i]).to3D(); + if (P === null) { return null; } + list.push(P); + n = list.length; + if (n > 2) { + // Compute plane normal for the latest three points + A = list[n-1].elements; B = list[n-2].elements; C = list[n-3].elements; + N = Vector.create([ + (A[1] - B[1]) * (C[2] - B[2]) - (A[2] - B[2]) * (C[1] - B[1]), + (A[2] - B[2]) * (C[0] - B[0]) - (A[0] - B[0]) * (C[2] - B[2]), + (A[0] - B[0]) * (C[1] - B[1]) - (A[1] - B[1]) * (C[0] - B[0]) + ]).toUnitVector(); + if (n > 3) { + // If the latest normal is not (anti)parallel to the previous one, we've strayed off the plane. + // This might be a slightly long-winded way of doing things, but we need the sum of all the normals + // to find which way the plane normal should point so that the points form an anticlockwise list. + theta = N.angleFrom(prevN); + if (theta !== null) { + if (!(Math.abs(theta) <= Sylvester.precision || Math.abs(theta - Math.PI) <= Sylvester.precision)) { return null; } + } + } + totalN = totalN.add(N); + prevN = N; + } + } + // We need to add in the normals at the start and end points, which the above misses out + A = list[1].elements; B = list[0].elements; C = list[n-1].elements; D = list[n-2].elements; + totalN = totalN.add(Vector.create([ + (A[1] - B[1]) * (C[2] - B[2]) - (A[2] - B[2]) * (C[1] - B[1]), + (A[2] - B[2]) * (C[0] - B[0]) - (A[0] - B[0]) * (C[2] - B[2]), + (A[0] - B[0]) * (C[1] - B[1]) - (A[1] - B[1]) * (C[0] - B[0]) + ]).toUnitVector()).add(Vector.create([ + (B[1] - C[1]) * (D[2] - C[2]) - (B[2] - C[2]) * (D[1] - C[1]), + (B[2] - C[2]) * (D[0] - C[0]) - (B[0] - C[0]) * (D[2] - C[2]), + (B[0] - C[0]) * (D[1] - C[1]) - (B[1] - C[1]) * (D[0] - C[0]) + ]).toUnitVector()); + return Plane.create(list[0], totalN); +}; + +module.exports = Plane; + +},{"./line":13,"./matrix":15,"./sylvester":17,"./vector":18}],17:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// This file is required in order for any other classes to work. Some Vector methods work with the +// other Sylvester classes and are useless unless they are included. Other classes such as Line and +// Plane will not function at all without Vector being loaded first. + +Math.sign = function(x) { + return x < 0 ? -1: 1; +} + +var Sylvester = { + precision: 1e-6, + approxPrecision: 1e-5 +}; + +module.exports = Sylvester; + +},{}],18:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// This file is required in order for any other classes to work. Some Vector methods work with the +// other Sylvester classes and are useless unless they are included. Other classes such as Line and +// Plane will not function at all without Vector being loaded first. + +var Sylvester = require('./sylvester'), +Matrix = require('./matrix'); + +function Vector() {} +Vector.prototype = { + + norm: function() { + var n = this.elements.length; + var sum = 0; + + while (n--) { + sum += Math.pow(this.elements[n], 2); + } + + return Math.sqrt(sum); + }, + + // Returns element i of the vector + e: function(i) { + return (i < 1 || i > this.elements.length) ? null : this.elements[i - 1]; + }, + + // Returns the number of rows/columns the vector has + dimensions: function() { + return {rows: 1, cols: this.elements.length}; + }, + + // Returns the number of rows in the vector + rows: function() { + return 1; + }, + + // Returns the number of columns in the vector + cols: function() { + return this.elements.length; + }, + + // Returns the modulus ('length') of the vector + modulus: function() { + return Math.sqrt(this.dot(this)); + }, + + // Returns true iff the vector is equal to the argument + eql: function(vector) { + var n = this.elements.length; + var V = vector.elements || vector; + if (n != V.length) { return false; } + while (n--) { + if (Math.abs(this.elements[n] - V[n]) > Sylvester.precision) { return false; } + } + return true; + }, + + // Returns a copy of the vector + dup: function() { + return Vector.create(this.elements); + }, + + // Maps the vector to another vector according to the given function + map: function(fn) { + var elements = []; + this.each(function(x, i) { + elements.push(fn(x, i)); + }); + return Vector.create(elements); + }, + + // Calls the iterator for each element of the vector in turn + each: function(fn) { + var n = this.elements.length; + for (var i = 0; i < n; i++) { + fn(this.elements[i], i + 1); + } + }, + + // Returns a new vector created by normalizing the receiver + toUnitVector: function() { + var r = this.modulus(); + if (r === 0) { return this.dup(); } + return this.map(function(x) { return x / r; }); + }, + + // Returns the angle between the vector and the argument (also a vector) + angleFrom: function(vector) { + var V = vector.elements || vector; + var n = this.elements.length, k = n, i; + if (n != V.length) { return null; } + var dot = 0, mod1 = 0, mod2 = 0; + // Work things out in parallel to save time + this.each(function(x, i) { + dot += x * V[i - 1]; + mod1 += x * x; + mod2 += V[i - 1] * V[i - 1]; + }); + mod1 = Math.sqrt(mod1); mod2 = Math.sqrt(mod2); + if (mod1 * mod2 === 0) { return null; } + var theta = dot / (mod1 * mod2); + if (theta < -1) { theta = -1; } + if (theta > 1) { theta = 1; } + return Math.acos(theta); + }, + + // Returns true iff the vector is parallel to the argument + isParallelTo: function(vector) { + var angle = this.angleFrom(vector); + return (angle === null) ? null : (angle <= Sylvester.precision); + }, + + // Returns true iff the vector is antiparallel to the argument + isAntiparallelTo: function(vector) { + var angle = this.angleFrom(vector); + return (angle === null) ? null : (Math.abs(angle - Math.PI) <= Sylvester.precision); + }, + + // Returns true iff the vector is perpendicular to the argument + isPerpendicularTo: function(vector) { + var dot = this.dot(vector); + return (dot === null) ? null : (Math.abs(dot) <= Sylvester.precision); + }, + + // Returns the result of adding the argument to the vector + add: function(value) { + var V = value.elements || value; + + if (this.elements.length != V.length) + return this.map(function(v) { return v + value }); + else + return this.map(function(x, i) { return x + V[i - 1]; }); + }, + + // Returns the result of subtracting the argument from the vector + subtract: function(v) { + if (typeof(v) == 'number') + return this.map(function(k) { return k - v; }); + + var V = v.elements || v; + if (this.elements.length != V.length) { return null; } + return this.map(function(x, i) { return x - V[i - 1]; }); + }, + + // Returns the result of multiplying the elements of the vector by the argument + multiply: function(k) { + return this.map(function(x) { return x * k; }); + }, + + elementMultiply: function(v) { + return this.map(function(k, i) { + return v.e(i) * k; + }); + }, + + sum: function() { + var sum = 0; + this.map(function(x) { sum += x;}); + return sum; + }, + + chomp: function(n) { + var elements = []; + + for (var i = n; i < this.elements.length; i++) { + elements.push(this.elements[i]); + } + + return Vector.create(elements); + }, + + top: function(n) { + var elements = []; + + for (var i = 0; i < n; i++) { + elements.push(this.elements[i]); + } + + return Vector.create(elements); + }, + + augment: function(elements) { + var newElements = this.elements; + + for (var i = 0; i < elements.length; i++) { + newElements.push(elements[i]); + } + + return Vector.create(newElements); + }, + + x: function(k) { return this.multiply(k); }, + + log: function() { + return Vector.log(this); + }, + + elementDivide: function(vector) { + return this.map(function(v, i) { + return v / vector.e(i); + }); + }, + + product: function() { + var p = 1; + + this.map(function(v) { + p *= v; + }); + + return p; + }, + + // Returns the scalar product of the vector with the argument + // Both vectors must have equal dimensionality + dot: function(vector) { + var V = vector.elements || vector; + var i, product = 0, n = this.elements.length; + if (n != V.length) { return null; } + while (n--) { product += this.elements[n] * V[n]; } + return product; + }, + + // Returns the vector product of the vector with the argument + // Both vectors must have dimensionality 3 + cross: function(vector) { + var B = vector.elements || vector; + if (this.elements.length != 3 || B.length != 3) { return null; } + var A = this.elements; + return Vector.create([ + (A[1] * B[2]) - (A[2] * B[1]), + (A[2] * B[0]) - (A[0] * B[2]), + (A[0] * B[1]) - (A[1] * B[0]) + ]); + }, + + // Returns the (absolute) largest element of the vector + max: function() { + var m = 0, i = this.elements.length; + while (i--) { + if (Math.abs(this.elements[i]) > Math.abs(m)) { m = this.elements[i]; } + } + return m; + }, + + + maxIndex: function() { + var m = 0, i = this.elements.length; + var maxIndex = -1; + + while (i--) { + if (Math.abs(this.elements[i]) > Math.abs(m)) { + m = this.elements[i]; + maxIndex = i + 1; + } + } + + return maxIndex; + }, + + + // Returns the index of the first match found + indexOf: function(x) { + var index = null, n = this.elements.length; + for (var i = 0; i < n; i++) { + if (index === null && this.elements[i] == x) { + index = i + 1; + } + } + return index; + }, + + // Returns a diagonal matrix with the vector's elements as its diagonal elements + toDiagonalMatrix: function() { + return Matrix.Diagonal(this.elements); + }, + + // Returns the result of rounding the elements of the vector + round: function() { + return this.map(function(x) { return Math.round(x); }); + }, + + // Transpose a Vector, return a 1xn Matrix + transpose: function() { + var rows = this.elements.length; + var elements = []; + + for (var i = 0; i < rows; i++) { + elements.push([this.elements[i]]); + } + return Matrix.create(elements); + }, + + // Returns a copy of the vector with elements set to the given value if they + // differ from it by less than Sylvester.precision + snapTo: function(x) { + return this.map(function(y) { + return (Math.abs(y - x) <= Sylvester.precision) ? x : y; + }); + }, + + // Returns the vector's distance from the argument, when considered as a point in space + distanceFrom: function(obj) { + if (obj.anchor || (obj.start && obj.end)) { return obj.distanceFrom(this); } + var V = obj.elements || obj; + if (V.length != this.elements.length) { return null; } + var sum = 0, part; + this.each(function(x, i) { + part = x - V[i - 1]; + sum += part * part; + }); + return Math.sqrt(sum); + }, + + // Returns true if the vector is point on the given line + liesOn: function(line) { + return line.contains(this); + }, + + // Return true iff the vector is a point in the given plane + liesIn: function(plane) { + return plane.contains(this); + }, + + // Rotates the vector about the given object. The object should be a + // point if the vector is 2D, and a line if it is 3D. Be careful with line directions! + rotate: function(t, obj) { + var V, R = null, x, y, z; + if (t.determinant) { R = t.elements; } + switch (this.elements.length) { + case 2: + V = obj.elements || obj; + if (V.length != 2) { return null; } + if (!R) { R = Matrix.Rotation(t).elements; } + x = this.elements[0] - V[0]; + y = this.elements[1] - V[1]; + return Vector.create([ + V[0] + R[0][0] * x + R[0][1] * y, + V[1] + R[1][0] * x + R[1][1] * y + ]); + break; + case 3: + if (!obj.direction) { return null; } + var C = obj.pointClosestTo(this).elements; + if (!R) { R = Matrix.Rotation(t, obj.direction).elements; } + x = this.elements[0] - C[0]; + y = this.elements[1] - C[1]; + z = this.elements[2] - C[2]; + return Vector.create([ + C[0] + R[0][0] * x + R[0][1] * y + R[0][2] * z, + C[1] + R[1][0] * x + R[1][1] * y + R[1][2] * z, + C[2] + R[2][0] * x + R[2][1] * y + R[2][2] * z + ]); + break; + default: + return null; + } + }, + + // Returns the result of reflecting the point in the given point, line or plane + reflectionIn: function(obj) { + if (obj.anchor) { + // obj is a plane or line + var P = this.elements.slice(); + var C = obj.pointClosestTo(P).elements; + return Vector.create([C[0] + (C[0] - P[0]), C[1] + (C[1] - P[1]), C[2] + (C[2] - (P[2] || 0))]); + } else { + // obj is a point + var Q = obj.elements || obj; + if (this.elements.length != Q.length) { return null; } + return this.map(function(x, i) { return Q[i - 1] + (Q[i - 1] - x); }); + } + }, + + // Utility to make sure vectors are 3D. If they are 2D, a zero z-component is added + to3D: function() { + var V = this.dup(); + switch (V.elements.length) { + case 3: break; + case 2: V.elements.push(0); break; + default: return null; + } + return V; + }, + + // Returns a string representation of the vector + inspect: function() { + return '[' + this.elements.join(', ') + ']'; + }, + + // Set vector's elements from an array + setElements: function(els) { + this.elements = (els.elements || els).slice(); + return this; + } +}; + +// Constructor function +Vector.create = function(elements) { + var V = new Vector(); + return V.setElements(elements); +}; + +// i, j, k unit vectors +Vector.i = Vector.create([1, 0, 0]); +Vector.j = Vector.create([0, 1, 0]); +Vector.k = Vector.create([0, 0, 1]); + +// Random vector of size n +Vector.Random = function(n) { + var elements = []; + while (n--) { elements.push(Math.random()); } + return Vector.create(elements); +}; + +Vector.Fill = function(n, v) { + var elements = []; + while (n--) { elements.push(v); } + return Vector.create(elements); +}; + +// Vector filled with zeros +Vector.Zero = function(n) { + return Vector.Fill(n, 0); +}; + +Vector.One = function(n) { + return Vector.Fill(n, 1); +}; + +Vector.log = function(v) { + return v.map(function(x) { + return Math.log(x); + }); +}; + +module.exports = Vector; + +},{"./matrix":15,"./sylvester":17}],19:[function(require,module,exports){ +"use strict"; + +/** + * Represents a 2-dimensional size value. + */ + +function Size(w, h) { + this.w = w; + this.h = h; +} + +Size.prototype = { + toString: function () { + return "(" + this.w + ", " + this.h + ")"; + }, + getHalfSize: function() { + return new Size(this.w >>> 1, this.h >>> 1); + }, + length: function() { + return this.w * this.h; + } +} +module.exports = Size; +},{}],20:[function(require,module,exports){ +"use strict"; + +var error = require('./error'); + +function assert(condition, message) { + if (!condition) { + error(message); + } +} + + +module.exports = assert; + +},{"./error":21}],21:[function(require,module,exports){ +"use strict"; + +function error(message) { + console.error(message); + console.trace(); +} + +module.exports = error; + +},{}],22:[function(require,module,exports){ +"use strict"; + +var Matrix = require('sylvester.js').Matrix; +var Vector = require('sylvester.js').Vector; +var $M = Matrix.create; + + +// augment Sylvester some +Matrix.Translation = function (v) +{ + if (v.elements.length == 2) { + var r = Matrix.I(3); + r.elements[2][0] = v.elements[0]; + r.elements[2][1] = v.elements[1]; + return r; + } + + if (v.elements.length == 3) { + var r = Matrix.I(4); + r.elements[0][3] = v.elements[0]; + r.elements[1][3] = v.elements[1]; + r.elements[2][3] = v.elements[2]; + return r; + } + + throw "Invalid length for Translation"; +} + +Matrix.prototype.flatten = function () +{ + var result = []; + if (this.elements.length == 0) + return []; + + + for (var j = 0; j < this.elements[0].length; j++) + for (var i = 0; i < this.elements.length; i++) + result.push(this.elements[i][j]); + return result; +} + +Matrix.prototype.ensure4x4 = function() +{ + if (this.elements.length == 4 && + this.elements[0].length == 4) + return this; + + if (this.elements.length > 4 || + this.elements[0].length > 4) + return null; + + for (var i = 0; i < this.elements.length; i++) { + for (var j = this.elements[i].length; j < 4; j++) { + if (i == j) + this.elements[i].push(1); + else + this.elements[i].push(0); + } + } + + for (var i = this.elements.length; i < 4; i++) { + if (i == 0) + this.elements.push([1, 0, 0, 0]); + else if (i == 1) + this.elements.push([0, 1, 0, 0]); + else if (i == 2) + this.elements.push([0, 0, 1, 0]); + else if (i == 3) + this.elements.push([0, 0, 0, 1]); + } + + return this; +}; + + +Vector.prototype.flatten = function () +{ + return this.elements; +}; + + + +// +// gluPerspective +// +function makePerspective(fovy, aspect, znear, zfar) +{ + var ymax = znear * Math.tan(fovy * Math.PI / 360.0); + var ymin = -ymax; + var xmin = ymin * aspect; + var xmax = ymax * aspect; + + return makeFrustum(xmin, xmax, ymin, ymax, znear, zfar); +} + +// +// glFrustum +// +function makeFrustum(left, right, + bottom, top, + znear, zfar) +{ + var X = 2*znear/(right-left); + var Y = 2*znear/(top-bottom); + var A = (right+left)/(right-left); + var B = (top+bottom)/(top-bottom); + var C = -(zfar+znear)/(zfar-znear); + var D = -2*zfar*znear/(zfar-znear); + + return $M([[X, 0, A, 0], + [0, Y, B, 0], + [0, 0, C, D], + [0, 0, -1, 0]]); +} + +module.exports.makePerspective = makePerspective; + + +},{"sylvester.js":12}],23:[function(require,module,exports){ +"use strict"; + +var Avc = require('../broadway/Decoder'); +var YUVWebGLCanvas = require('../canvas/YUVWebGLCanvas'); +var YUVCanvas = require('../canvas/YUVCanvas'); +var Size = require('../utils/Size'); +var Class = require('uclass'); +var Events = require('uclass/events'); +var debug = require('debug'); +var log = console.log; + +var WSAvcPlayer = new Class({ + Implements : [Events], + + + initialize : function(canvas, canvastype) { + + this.canvas = canvas; + this.canvastype = canvastype; + + // AVC codec initialization + this.avc = new Avc(); + if(false) this.avc.configure({ + filter: "original", + filterHorLuma: "optimized", + filterVerLumaEdge: "optimized", + getBoundaryStrengthsA: "optimized" + }); + + //WebSocket variable + this.ws; + this.pktnum = 0; + + }, + + + decode : function(data) { + var naltype = "invalid frame"; + + if (data.length > 4) { + if (data[4] == 0x65) { + naltype = "I frame"; + } + else if (data[4] == 0x41) { + naltype = "P frame"; + } + else if (data[4] == 0x67) { + naltype = "SPS"; + } + else if (data[4] == 0x68) { + naltype = "PPS"; + } + } + //log("Passed " + naltype + " to decoder"); + this.avc.decode(data); + }, + + connect : function(url) { + var framesList = []; + this.write = function(data){ + this.pktnum++; + var frame = new Uint8Array(data); + //log("[Pkt " + this.pktnum + " (" + data.byteLength + " bytes)]"); + //this.decode(frame); + framesList.push(frame); + } + var running = true; + + var shiftFrame = function() { + if(!running) + return; + + + if(framesList.length > 10) { + log("Dropping frames", framesList.length); + framesList.splice(0,10); + } + + var frame = framesList.shift(); + + + if(frame) + this.decode(frame); + + requestAnimationFrame(shiftFrame); + }.bind(this); + + + shiftFrame(); + }, + + initCanvas : function(width, height) { + var canvasFactory = this.canvastype == "webgl" || this.canvastype == "YUVWebGLCanvas" + ? YUVWebGLCanvas + : YUVCanvas; + + var canvas = new canvasFactory(this.canvas, new Size(width, height)); + this.avc.onPictureDecoded = canvas.decode; + this.emit("canvasReady", width, height); + }, + + cmd : function(cmd){ + log("Incoming request", cmd); + + if(cmd.action == "init") { + this.initCanvas(cmd.width, cmd.height); + this.canvas.width = cmd.width; + this.canvas.height = cmd.height; + } + }, + + disconnect : function() { +// this.ws.close(); + }, + + playStream : function() { + var message = "REQUESTSTREAM "; +// this.ws.send(message); + log("Sent " + message); + }, + + + stopStream : function() { + this.ws.send("STOPSTREAM"); + log("Sent STOPSTREAM"); + }, +}); + + +module.exports = WSAvcPlayer; +module.exports.debug = debug; + +},{"../broadway/Decoder":4,"../canvas/YUVCanvas":10,"../canvas/YUVWebGLCanvas":11,"../utils/Size":19,"debug":1,"uclass":47,"uclass/events":24}],24:[function(require,module,exports){ +"use strict"; + +var Class = require('../'); +var guid = require('mout/random/guid'); +var forIn = require('mout/object/forIn'); + +var EventEmitter = new Class({ + Binds : ['on', 'off', 'once', 'emit'], + + callbacks : {}, + + initialize : function() { + var self = this; + this.addEvent = this.on; + this.removeListener = this.off; + this.removeAllListeners = this.off; + this.fireEvent = this.emit; + }, + + emit:function(event, payload){ + if(!this.callbacks[event]) + return; + + var args = Array.prototype.slice.call(arguments, 1); + + forIn(this.callbacks[event], function(callback){ + callback.apply(null, args); + }); + }, + + + on:function(event, callback){ + if(typeof callback != "function") + return console.log("you try to register a non function in " , event) + if(!this.callbacks[event]) + this.callbacks[event] = {}; + this.callbacks[event][guid()] = callback; + }, + + once:function(event, callback){ + var self = this; + var once = function(){ + self.off(event, once); + self.off(event, callback); + }; + + this.on(event, callback); + this.on(event, once); + }, + + off:function(event, callback){ + if(!event) + this.callbacks = {}; + else if(!callback) + this.callbacks[event] = {}; + else forIn(this.callbacks[event] || {}, function(v, k) { + if(v == callback) + delete this.callbacks[event][k]; + }, this); + }, +}); + +module.exports = EventEmitter; +},{"../":47,"mout/object/forIn":36,"mout/random/guid":42}],25:[function(require,module,exports){ +"use strict"; + +var verbs = /^Implements|Extends|Binds$/ + +module.exports = function(ctx, obj){ + for(var key in obj) { + if(key.match(verbs)) continue; + if((typeof obj[key] == 'function') && obj[key].$static) + ctx[key] = obj[key]; + else + ctx.prototype[key] = obj[key]; + } + return ctx; +} +},{}],26:[function(require,module,exports){ +var kindOf = require('./kindOf'); +var isPlainObject = require('./isPlainObject'); +var mixIn = require('../object/mixIn'); + + /** + * Clone native types. + */ + function clone(val){ + switch (kindOf(val)) { + case 'Object': + return cloneObject(val); + case 'Array': + return cloneArray(val); + case 'RegExp': + return cloneRegExp(val); + case 'Date': + return cloneDate(val); + default: + return val; + } + } + + function cloneObject(source) { + if (isPlainObject(source)) { + return mixIn({}, source); + } else { + return source; + } + } + + function cloneRegExp(r) { + var flags = ''; + flags += r.multiline ? 'm' : ''; + flags += r.global ? 'g' : ''; + flags += r.ignoreCase ? 'i' : ''; + return new RegExp(r.source, flags); + } + + function cloneDate(date) { + return new Date(+date); + } + + function cloneArray(arr) { + return arr.slice(); + } + + module.exports = clone; + + + +},{"../object/mixIn":40,"./isPlainObject":32,"./kindOf":33}],27:[function(require,module,exports){ +var mixIn = require('../object/mixIn'); + + /** + * Create Object using prototypal inheritance and setting custom properties. + * - Mix between Douglas Crockford Prototypal Inheritance and the EcmaScript 5 `Object.create()` method. + * @param {object} parent Parent Object. + * @param {object} [props] Object properties. + * @return {object} Created object. + */ + function createObject(parent, props){ + function F(){} + F.prototype = parent; + return mixIn(new F(), props); + + } + module.exports = createObject; + + + +},{"../object/mixIn":40}],28:[function(require,module,exports){ +var clone = require('./clone'); +var forOwn = require('../object/forOwn'); +var kindOf = require('./kindOf'); +var isPlainObject = require('./isPlainObject'); + + /** + * Recursively clone native types. + */ + function deepClone(val, instanceClone) { + switch ( kindOf(val) ) { + case 'Object': + return cloneObject(val, instanceClone); + case 'Array': + return cloneArray(val, instanceClone); + default: + return clone(val); + } + } + + function cloneObject(source, instanceClone) { + if (isPlainObject(source)) { + var out = {}; + forOwn(source, function(val, key) { + this[key] = deepClone(val, instanceClone); + }, out); + return out; + } else if (instanceClone) { + return instanceClone(source); + } else { + return source; + } + } + + function cloneArray(arr, instanceClone) { + var out = [], + i = -1, + n = arr.length, + val; + while (++i < n) { + out[i] = deepClone(arr[i], instanceClone); + } + return out; + } + + module.exports = deepClone; + + + + +},{"../object/forOwn":37,"./clone":26,"./isPlainObject":32,"./kindOf":33}],29:[function(require,module,exports){ +var isKind = require('./isKind'); + /** + */ + var isArray = Array.isArray || function (val) { + return isKind(val, 'Array'); + }; + module.exports = isArray; + + +},{"./isKind":30}],30:[function(require,module,exports){ +var kindOf = require('./kindOf'); + /** + * Check if value is from a specific "kind". + */ + function isKind(val, kind){ + return kindOf(val) === kind; + } + module.exports = isKind; + + +},{"./kindOf":33}],31:[function(require,module,exports){ +var isKind = require('./isKind'); + /** + */ + function isObject(val) { + return isKind(val, 'Object'); + } + module.exports = isObject; + + +},{"./isKind":30}],32:[function(require,module,exports){ + + + /** + * Checks if the value is created by the `Object` constructor. + */ + function isPlainObject(value) { + return (!!value && typeof value === 'object' && + value.constructor === Object); + } + + module.exports = isPlainObject; + + + +},{}],33:[function(require,module,exports){ + + + var _rKind = /^\[object (.*)\]$/, + _toString = Object.prototype.toString, + UNDEF; + + /** + * Gets the "kind" of value. (e.g. "String", "Number", etc) + */ + function kindOf(val) { + if (val === null) { + return 'Null'; + } else if (val === UNDEF) { + return 'Undefined'; + } else { + return _rKind.exec( _toString.call(val) )[1]; + } + } + module.exports = kindOf; + + +},{}],34:[function(require,module,exports){ +/** + * @constant Maximum 32-bit signed integer value. (2^31 - 1) + */ + + module.exports = 2147483647; + + +},{}],35:[function(require,module,exports){ +/** + * @constant Minimum 32-bit signed integer value (-2^31). + */ + + module.exports = -2147483648; + + +},{}],36:[function(require,module,exports){ +var hasOwn = require('./hasOwn'); + + var _hasDontEnumBug, + _dontEnums; + + function checkDontEnum(){ + _dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' + ]; + + _hasDontEnumBug = true; + + for (var key in {'toString': null}) { + _hasDontEnumBug = false; + } + } + + /** + * Similar to Array/forEach but works over object properties and fixes Don't + * Enum bug on IE. + * based on: http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation + */ + function forIn(obj, fn, thisObj){ + var key, i = 0; + // no need to check if argument is a real object that way we can use + // it for arrays, functions, date, etc. + + //post-pone check till needed + if (_hasDontEnumBug == null) checkDontEnum(); + + for (key in obj) { + if (exec(fn, obj, key, thisObj) === false) { + break; + } + } + + + if (_hasDontEnumBug) { + var ctor = obj.constructor, + isProto = !!ctor && obj === ctor.prototype; + + while (key = _dontEnums[i++]) { + // For constructor, if it is a prototype object the constructor + // is always non-enumerable unless defined otherwise (and + // enumerated above). For non-prototype objects, it will have + // to be defined on this object, since it cannot be defined on + // any prototype objects. + // + // For other [[DontEnum]] properties, check if the value is + // different than Object prototype value. + if ( + (key !== 'constructor' || + (!isProto && hasOwn(obj, key))) && + obj[key] !== Object.prototype[key] + ) { + if (exec(fn, obj, key, thisObj) === false) { + break; + } + } + } + } + } + + function exec(fn, obj, key, thisObj){ + return fn.call(thisObj, obj[key], key, obj); + } + + module.exports = forIn; + + + +},{"./hasOwn":38}],37:[function(require,module,exports){ +var hasOwn = require('./hasOwn'); +var forIn = require('./forIn'); + + /** + * Similar to Array/forEach but works over object properties and fixes Don't + * Enum bug on IE. + * based on: http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation + */ + function forOwn(obj, fn, thisObj){ + forIn(obj, function(val, key){ + if (hasOwn(obj, key)) { + return fn.call(thisObj, obj[key], key, obj); + } + }); + } + + module.exports = forOwn; + + + +},{"./forIn":36,"./hasOwn":38}],38:[function(require,module,exports){ + + + /** + * Safer Object.hasOwnProperty + */ + function hasOwn(obj, prop){ + return Object.prototype.hasOwnProperty.call(obj, prop); + } + + module.exports = hasOwn; + + + +},{}],39:[function(require,module,exports){ +var hasOwn = require('./hasOwn'); +var deepClone = require('../lang/deepClone'); +var isObject = require('../lang/isObject'); + + /** + * Deep merge objects. + */ + function merge() { + var i = 1, + key, val, obj, target; + + // make sure we don't modify source element and it's properties + // objects are passed by reference + target = deepClone( arguments[0] ); + + while (obj = arguments[i++]) { + for (key in obj) { + if ( ! hasOwn(obj, key) ) { + continue; + } + + val = obj[key]; + + if ( isObject(val) && isObject(target[key]) ){ + // inception, deep merge objects + target[key] = merge(target[key], val); + } else { + // make sure arrays, regexp, date, objects are cloned + target[key] = deepClone(val); + } + + } + } + + return target; + } + + module.exports = merge; + + + +},{"../lang/deepClone":28,"../lang/isObject":31,"./hasOwn":38}],40:[function(require,module,exports){ +var forOwn = require('./forOwn'); + + /** + * Combine properties from all the objects into first one. + * - This method affects target object in place, if you want to create a new Object pass an empty object as first param. + * @param {object} target Target Object + * @param {...object} objects Objects to be combined (0...n objects). + * @return {object} Target Object. + */ + function mixIn(target, objects){ + var i = 0, + n = arguments.length, + obj; + while(++i < n){ + obj = arguments[i]; + if (obj != null) { + forOwn(obj, copyProp, target); + } + } + return target; + } + + function copyProp(val, key){ + this[key] = val; + } + + module.exports = mixIn; + + +},{"./forOwn":37}],41:[function(require,module,exports){ +var randInt = require('./randInt'); +var isArray = require('../lang/isArray'); + + /** + * Returns a random element from the supplied arguments + * or from the array (if single argument is an array). + */ + function choice(items) { + var target = (arguments.length === 1 && isArray(items))? items : arguments; + return target[ randInt(0, target.length - 1) ]; + } + + module.exports = choice; + + + +},{"../lang/isArray":29,"./randInt":45}],42:[function(require,module,exports){ +var randHex = require('./randHex'); +var choice = require('./choice'); + + /** + * Returns pseudo-random guid (UUID v4) + * IMPORTANT: it's not totally "safe" since randHex/choice uses Math.random + * by default and sequences can be predicted in some cases. See the + * "random/random" documentation for more info about it and how to replace + * the default PRNG. + */ + function guid() { + return ( + randHex(8)+'-'+ + randHex(4)+'-'+ + // v4 UUID always contain "4" at this position to specify it was + // randomly generated + '4' + randHex(3) +'-'+ + // v4 UUID always contain chars [a,b,8,9] at this position + choice(8, 9, 'a', 'b') + randHex(3)+'-'+ + randHex(12) + ); + } + module.exports = guid; + + +},{"./choice":41,"./randHex":44}],43:[function(require,module,exports){ +var random = require('./random'); +var MIN_INT = require('../number/MIN_INT'); +var MAX_INT = require('../number/MAX_INT'); + + /** + * Returns random number inside range + */ + function rand(min, max){ + min = min == null? MIN_INT : min; + max = max == null? MAX_INT : max; + return min + (max - min) * random(); + } + + module.exports = rand; + + +},{"../number/MAX_INT":34,"../number/MIN_INT":35,"./random":46}],44:[function(require,module,exports){ +var choice = require('./choice'); + + var _chars = '0123456789abcdef'.split(''); + + /** + * Returns a random hexadecimal string + */ + function randHex(size){ + size = size && size > 0? size : 6; + var str = ''; + while (size--) { + str += choice(_chars); + } + return str; + } + + module.exports = randHex; + + + +},{"./choice":41}],45:[function(require,module,exports){ +var MIN_INT = require('../number/MIN_INT'); +var MAX_INT = require('../number/MAX_INT'); +var rand = require('./rand'); + + /** + * Gets random integer inside range or snap to min/max values. + */ + function randInt(min, max){ + min = min == null? MIN_INT : ~~min; + max = max == null? MAX_INT : ~~max; + // can't be max + 0.5 otherwise it will round up if `rand` + // returns `max` causing it to overflow range. + // -0.5 and + 0.49 are required to avoid bias caused by rounding + return Math.round( rand(min - 0.5, max + 0.499999999999) ); + } + + module.exports = randInt; + + +},{"../number/MAX_INT":34,"../number/MIN_INT":35,"./rand":43}],46:[function(require,module,exports){ + + + /** + * Just a wrapper to Math.random. No methods inside mout/random should call + * Math.random() directly so we can inject the pseudo-random number + * generator if needed (ie. in case we need a seeded random or a better + * algorithm than the native one) + */ + function random(){ + return random.get(); + } + + // we expose the method so it can be swapped if needed + random.get = Math.random; + + module.exports = random; + + + +},{}],47:[function(require,module,exports){ +"use strict"; + +var hasOwn = require("mout/object/hasOwn"); +var create = require("mout/lang/createObject"); +var merge = require("mout/object/merge"); +var kindOf = require("mout/lang/kindOf"); +var mixIn = require("mout/object/mixIn"); + +var implement = require('./implement'); +var verbs = /^Implements|Extends|Binds$/ + + + + +var uClass = function(proto){ + + if(kindOf(proto) === "Function") proto = {initialize: proto}; + + var superprime = proto.Extends; + + var constructor = (hasOwn(proto, "initialize")) ? proto.initialize : superprime ? superprime : function(){}; + + + + var out = function() { + var self = this; + //autobinding takes place here + if(proto.Binds) proto.Binds.forEach(function(f){ + var original = self[f]; + if(original) + self[f] = mixIn(self[f].bind(self), original); + }); + + //clone non function/static properties to current instance + for(var key in out.prototype) { + var v = out.prototype[key], t = kindOf(v); + + if(key.match(verbs) || t === "Function" || t == "GeneratorFunction") + continue; + + if(t == "Object") + self[key] = merge({}, self[key]); //create(null, self[key]); + else if(t == "Array") + self[key] = v.slice(); //clone ?? + else + self[key] = v; + } + + if(proto.Implements) + proto.Implements.forEach(function(Mixin){ + Mixin.call(self); + }); + + + + + constructor.apply(this, arguments); + } + + + if (superprime) { + // inherit from superprime + var superproto = superprime.prototype; + if(superproto.Binds) + proto.Binds = (proto.Binds || []).concat(superproto.Binds); + + if(superproto.Implements) + proto.Implements = (proto.Implements || []).concat(superproto.Implements); + + var cproto = out.prototype = create(superproto); + // setting constructor.parent to superprime.prototype + // because it's the shortest possible absolute reference + out.parent = superproto; + cproto.constructor = out + + } + + + if(proto.Implements) { + if (kindOf(proto.Implements) !== "Array") + proto.Implements = [proto.Implements]; + proto.Implements.forEach(function(Mixin){ + implement(out, Mixin.prototype); + }); + } + + implement(out, proto); + if(proto.Binds) + out.prototype.Binds = proto.Binds; + if(proto.Implements) + out.prototype.Implements = proto.Implements; + + return out; +}; + + + +module.exports = uClass; +},{"./implement":25,"mout/lang/createObject":27,"mout/lang/kindOf":33,"mout/object/hasOwn":38,"mout/object/merge":39,"mout/object/mixIn":40}]},{},[23])(23) +}); \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/package.json b/tools/ffmpegToWeb/Player/broadway/package.json new file mode 100644 index 0000000..9bcc8b9 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/package.json @@ -0,0 +1,35 @@ +{ + "name": "h264-live-player", + "version": "1.3.1", + "main": "wsavc/index.js", + "scripts": { + "dist": "browserify --bare --standalone WSAvcPlayer --plugin discify wsavc/ > dist/http-live-player.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git@github.com:131/h264-live-player.git" + }, + "keywords": [ + "h264", + "nal", + "live", + "broadcast", + "streaming" + ], + "author": "Francois Leurent <131.js@cloudyks.org>", + "license": "ISC", + "bugs": { + "url": "https://github.com/131/h264-live-player/issues" + }, + "description": "This is a very simple h264 video player (that can run on live stream) for your browser.\r You might use this with raspicam raw h264 stream.\r This is a player around [Broadway](https://github.com/mbebenita/Broadway) Decoder, with very simple API.\r NAL unit (h264 frames) are split on the server side, so the client side is very simple (and allow frame skipping easily)", + "dependencies": { + "debug": "^2.3.2", + "sylvester.js": "^0.1.1", + "uclass": "^2.4.0" + }, + "devDependencies": { + "browserify": "^13.0.0", + "discify": "^1.4.2" + } +} diff --git a/tools/ffmpegToWeb/Player/broadway/utils/Size.js b/tools/ffmpegToWeb/Player/broadway/utils/Size.js new file mode 100644 index 0000000..4b2edfb --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/utils/Size.js @@ -0,0 +1,23 @@ +"use strict"; + +/** + * Represents a 2-dimensional size value. + */ + +function Size(w, h) { + this.w = w; + this.h = h; +} + +Size.prototype = { + toString: function () { + return "(" + this.w + ", " + this.h + ")"; + }, + getHalfSize: function() { + return new Size(this.w >>> 1, this.h >>> 1); + }, + length: function() { + return this.w * this.h; + } +} +module.exports = Size; \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/utils/assert.js b/tools/ffmpegToWeb/Player/broadway/utils/assert.js new file mode 100644 index 0000000..4db14a5 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/utils/assert.js @@ -0,0 +1,12 @@ +"use strict"; + +var error = require('./error'); + +function assert(condition, message) { + if (!condition) { + error(message); + } +} + + +module.exports = assert; diff --git a/tools/ffmpegToWeb/Player/broadway/utils/error.js b/tools/ffmpegToWeb/Player/broadway/utils/error.js new file mode 100644 index 0000000..f3f06f1 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/utils/error.js @@ -0,0 +1,8 @@ +"use strict"; + +function error(message) { + console.error(message); + console.trace(); +} + +module.exports = error; diff --git a/tools/ffmpegToWeb/Player/broadway/utils/glUtils.js b/tools/ffmpegToWeb/Player/broadway/utils/glUtils.js new file mode 100644 index 0000000..53d0160 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/utils/glUtils.js @@ -0,0 +1,117 @@ +"use strict"; + +var Matrix = require('sylvester.js').Matrix; +var Vector = require('sylvester.js').Vector; +var $M = Matrix.create; + + +// augment Sylvester some +Matrix.Translation = function (v) +{ + if (v.elements.length == 2) { + var r = Matrix.I(3); + r.elements[2][0] = v.elements[0]; + r.elements[2][1] = v.elements[1]; + return r; + } + + if (v.elements.length == 3) { + var r = Matrix.I(4); + r.elements[0][3] = v.elements[0]; + r.elements[1][3] = v.elements[1]; + r.elements[2][3] = v.elements[2]; + return r; + } + + throw "Invalid length for Translation"; +} + +Matrix.prototype.flatten = function () +{ + var result = []; + if (this.elements.length == 0) + return []; + + + for (var j = 0; j < this.elements[0].length; j++) + for (var i = 0; i < this.elements.length; i++) + result.push(this.elements[i][j]); + return result; +} + +Matrix.prototype.ensure4x4 = function() +{ + if (this.elements.length == 4 && + this.elements[0].length == 4) + return this; + + if (this.elements.length > 4 || + this.elements[0].length > 4) + return null; + + for (var i = 0; i < this.elements.length; i++) { + for (var j = this.elements[i].length; j < 4; j++) { + if (i == j) + this.elements[i].push(1); + else + this.elements[i].push(0); + } + } + + for (var i = this.elements.length; i < 4; i++) { + if (i == 0) + this.elements.push([1, 0, 0, 0]); + else if (i == 1) + this.elements.push([0, 1, 0, 0]); + else if (i == 2) + this.elements.push([0, 0, 1, 0]); + else if (i == 3) + this.elements.push([0, 0, 0, 1]); + } + + return this; +}; + + +Vector.prototype.flatten = function () +{ + return this.elements; +}; + + + +// +// gluPerspective +// +function makePerspective(fovy, aspect, znear, zfar) +{ + var ymax = znear * Math.tan(fovy * Math.PI / 360.0); + var ymin = -ymax; + var xmin = ymin * aspect; + var xmax = ymax * aspect; + + return makeFrustum(xmin, xmax, ymin, ymax, znear, zfar); +} + +// +// glFrustum +// +function makeFrustum(left, right, + bottom, top, + znear, zfar) +{ + var X = 2*znear/(right-left); + var Y = 2*znear/(top-bottom); + var A = (right+left)/(right-left); + var B = (top+bottom)/(top-bottom); + var C = -(zfar+znear)/(zfar-znear); + var D = -2*zfar*znear/(zfar-znear); + + return $M([[X, 0, A, 0], + [0, Y, B, 0], + [0, 0, C, D], + [0, 0, -1, 0]]); +} + +module.exports.makePerspective = makePerspective; + diff --git a/tools/ffmpegToWeb/Player/broadway/utils/inherit.js b/tools/ffmpegToWeb/Player/broadway/utils/inherit.js new file mode 100644 index 0000000..2ea40b2 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/utils/inherit.js @@ -0,0 +1,17 @@ +"use strict"; + +/** + * Creates a new prototype object derived from another objects prototype along with a list of additional properties. + * + * @param base object whose prototype to use as the created prototype object's prototype + * @param properties additional properties to add to the created prototype object + */ +function inherit(base, properties) { + var prot = Object.create(base.prototype); + for (var p in properties) { + prot[p] = properties[p]; + } + return prot; +} + +module.exports = inherit; \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/wsavc/index.js b/tools/ffmpegToWeb/Player/broadway/wsavc/index.js new file mode 100644 index 0000000..6e48bc7 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/wsavc/index.js @@ -0,0 +1,159 @@ +"use strict"; + +var Avc = require('../broadway/Decoder'); +var YUVWebGLCanvas = require('../canvas/YUVWebGLCanvas'); +var YUVCanvas = require('../canvas/YUVCanvas'); +var Size = require('../utils/Size'); +var Class = require('uclass'); +var Events = require('uclass/events'); +var debug = require('debug'); +var log = debug("wsavc"); + +var WSAvcPlayer = new Class({ + Implements : [Events], + + + initialize : function(canvas, canvastype) { + + this.canvas = canvas; + this.canvastype = canvastype; + + // AVC codec initialization + this.avc = new Avc(); + if(false) this.avc.configure({ + filter: "original", + filterHorLuma: "optimized", + filterVerLumaEdge: "optimized", + getBoundaryStrengthsA: "optimized" + }); + + //WebSocket variable + this.ws; + this.pktnum = 0; + + }, + + + decode : function(data) { + var naltype = "invalid frame"; + + if (data.length > 4) { + if (data[4] == 0x65) { + naltype = "I frame"; + } + else if (data[4] == 0x41) { + naltype = "P frame"; + } + else if (data[4] == 0x67) { + naltype = "SPS"; + } + else if (data[4] == 0x68) { + naltype = "PPS"; + } + } + //log("Passed " + naltype + " to decoder"); + this.avc.decode(data); + }, + + connect : function(url) { + + // Websocket initialization + if (this.ws != undefined) { + this.ws.close(); + delete this.ws; + } + this.ws = new WebSocket(url); + this.ws.binaryType = "arraybuffer"; + + this.ws.onopen = () => { + log("Connected to " + url); + }; + + + var framesList = []; + + this.ws.onmessage = (evt) => { + if(typeof evt.data == "string") + return this.cmd(JSON.parse(evt.data)); + + this.pktnum++; + var frame = new Uint8Array(evt.data); + //log("[Pkt " + this.pktnum + " (" + evt.data.byteLength + " bytes)]"); + //this.decode(frame); + framesList.push(frame); + }; + + + var running = true; + + var shiftFrame = function() { + if(!running) + return; + + + if(framesList.length > 10) { + log("Dropping frames", framesList.length); + framesList = []; + } + + var frame = framesList.shift(); + + + if(frame) + this.decode(frame); + + requestAnimationFrame(shiftFrame); + }.bind(this); + + + shiftFrame(); + + + + this.ws.onclose = () => { + running = false; + log("WSAvcPlayer: Connection closed") + }; + + }, + + initCanvas : function(width, height) { + var canvasFactory = this.canvastype == "webgl" || this.canvastype == "YUVWebGLCanvas" + ? YUVWebGLCanvas + : YUVCanvas; + + var canvas = new canvasFactory(this.canvas, new Size(width, height)); + this.avc.onPictureDecoded = canvas.decode; + this.emit("canvasReady", width, height); + }, + + cmd : function(cmd){ + log("Incoming request", cmd); + + if(cmd.action == "init") { + this.initCanvas(cmd.width, cmd.height); + this.canvas.width = cmd.width; + this.canvas.height = cmd.height; + } + }, + + disconnect : function() { + this.ws.close(); + }, + + playStream : function() { + var message = "REQUESTSTREAM "; + this.ws.send(message); + log("Sent " + message); + }, + + + stopStream : function() { + this.ws.send("STOPSTREAM"); + log("Sent STOPSTREAM"); + }, +}); + + +module.exports = WSAvcPlayer; +module.exports.debug = debug; diff --git a/tools/ffmpegToWeb/eventemitter.js b/tools/ffmpegToWeb/eventemitter.js new file mode 100644 index 0000000..87dbf6a --- /dev/null +++ b/tools/ffmpegToWeb/eventemitter.js @@ -0,0 +1,69 @@ +/* Polyfill indexOf. */ +var indexOf; + +if (typeof Array.prototype.indexOf === 'function') { + indexOf = function (haystack, needle) { + return haystack.indexOf(needle); + }; +} else { + indexOf = function (haystack, needle) { + var i = 0, length = haystack.length, idx = -1, found = false; + + while (i < length && !found) { + if (haystack[i] === needle) { + idx = i; + found = true; + } + + i++; + } + + return idx; + }; +}; + + +/* Polyfill EventEmitter. */ +var EventEmitter = function () { + this.events = {}; +}; + +EventEmitter.prototype.on = function (event, listener) { + if (typeof this.events[event] !== 'object') { + this.events[event] = []; + } + + this.events[event].push(listener); +}; + +EventEmitter.prototype.removeListener = function (event, listener) { + var idx; + + if (typeof this.events[event] === 'object') { + idx = indexOf(this.events[event], listener); + + if (idx > -1) { + this.events[event].splice(idx, 1); + } + } +}; + +EventEmitter.prototype.emit = function (event) { + var i, listeners, length, args = [].slice.call(arguments, 1); + + if (typeof this.events[event] === 'object') { + listeners = this.events[event].slice(); + length = listeners.length; + + for (i = 0; i < length; i++) { + listeners[i].apply(this, args); + } + } +}; + +EventEmitter.prototype.once = function (event, listener) { + this.on(event, function g () { + this.removeListener(event, g); + listener.apply(this, arguments); + }); +}; \ No newline at end of file diff --git a/tools/ffmpegToWeb/ffmpegToWeb.js b/tools/ffmpegToWeb/ffmpegToWeb.js new file mode 100644 index 0000000..83e9ba4 --- /dev/null +++ b/tools/ffmpegToWeb/ffmpegToWeb.js @@ -0,0 +1,117 @@ +// Shinobi (http://shinobi.video) - FFMPEG H.264 over HTTP Test +// How to Use raw H.264 (Simulated RTSP) +// 1. Start with `node ffmpegToWeb.js` +// 2. Get the IP address of the computer where you did step 1. Example : 127.0.0.1 +// 3. Open VLC and "Open Network Stream". +// 4. Input the following without quotes : `http://127.0.0.1:8001/h264` and start. + +var child = require('child_process'); +var io = require('socket.io'); +var Splitter = require('stream-split') +var events = require('events'); +var express = require('express') +var app = express(); +var server = require('http').Server(app); +var io = require('socket.io')(server); +var spawn = child.spawn; +var exec = child.exec; +var Emitters = {} +var config = { + port:8001, + url:'rtsp://131.95.3.162/axis-media/media.3gp' +} +var initEmitter = function(feed){ + if(!Emitters[feed]){ + Emitters[feed] = new events.EventEmitter().setMaxListeners(0) + } + return Emitters[feed] +} +var NALseparator = new Buffer([0,0,0,1]); +//web app +console.log('Starting Express Web Server on Port '+config.port) + +server.listen(config.port); + +app.use('/libs',express.static(__dirname + '/../../web/libs')); +app.use('/Player',express.static(__dirname + '/Player')); + +app.get('/', function (req, res) { + res.sendFile(__dirname + '/index.html'); +}) + +//ffmpeg pushed stream in here to make a pipe +app.all('/streamIn/:feed', function (req, res) { + req.Emitter = initEmitter(req.params.feed) + //req.params.feed = Feed Number (Pipe NWebGLumber) + res.connection.setTimeout(0); + + var Split = new Splitter(NALseparator) + var cn = io.to('STREAM_'+req.params.feed) + req.on('data', function(buffer){ + req.Emitter.emit('data',buffer) + }); + + req.pipe(Split).on('data',function(buffer){ + cn.emit('h264_'+req.params.feed,Buffer.concat([NALseparator,buffer])) + }) + + req.on('end',function(){ + delete(Split) + console.log('close'); + }); +}) + +//socket.io client commands +io.on('connection', function (cn) { + cn.on('f',function (data) { + switch(data.function){ + case'getStream': + console.log(data) + cn.join('STREAM_'+data.feed) + break; + } + }) +}); + +//simulate RTSP over HTTP +app.get(['/h264','/h264/:feed'], function (req, res) { + if(!req.params.feed){req.params.feed='1'} + req.Emitter = initEmitter(req.params.feed) + var contentWriter + var date = new Date(); + res.writeHead(200, { + 'Date': date.toUTCString(), + 'Connection': 'keep-alive', + 'Cache-Control': 'no-cache', + 'Pragma': 'no-cache', + 'Content-Type': 'video/mp4', + 'Server': 'Shinobi H.264 Test Stream', + }); + req.Emitter.on('data',contentWriter=function(buffer){ + res.write(buffer) + }) + res.on('close', function () { + req.Emitter.removeListener('data',contentWriter) + }) +}); + +//ffmpeg +console.log('Starting FFMPEG') +var ffmpegString = '-i '+config.url+'' +ffmpegString += ' -f mpegts -c:v mpeg1video -an http://localhost:'+config.port+'/streamIn/1' +ffmpegString += ' -pix_fmt yuv420p -b:v 600k -f rawvideo -c:v libx264 -vprofile baseline -tune zerolatency http://localhost:'+config.port+'/streamIn/2' +//ffmpegString += ' -f mpegts -c:v mpeg1video -an http://localhost:'+config.port+'/streamIn/2' +if(ffmpegString.indexOf('rtsp://')>-1){ + ffmpegString='-rtsp_transport tcp '+ffmpegString +} +console.log('Executing : ffmpeg '+ffmpegString) +var ffmpeg = spawn('ffmpeg',ffmpegString.split(' ')); +ffmpeg.on('close', function (buffer) { + console.log('ffmpeg died') +}) +//ffmpeg.stderr.on('data', function (buffer) { +// console.log(buffer.toString()) +//}); +//ffmpeg.stdout.on('data', function (buffer) { +// Emitter.emit('data',buffer) +//}); \ No newline at end of file diff --git a/tools/ffmpegToWeb/index.html b/tools/ffmpegToWeb/index.html new file mode 100644 index 0000000..0318990 --- /dev/null +++ b/tools/ffmpegToWeb/index.html @@ -0,0 +1,45 @@ + + + + + + + + + + \ No newline at end of file diff --git a/tools/ffmpegToWeb/package.json b/tools/ffmpegToWeb/package.json new file mode 100644 index 0000000..75640b8 --- /dev/null +++ b/tools/ffmpegToWeb/package.json @@ -0,0 +1,15 @@ +{ + "name": "ffmpegtoweb", + "version": "1.0.0", + "description": "Shinobi Testing Tool for H.264 over HTTP and Socket.IO", + "main": "ffmpegToWeb.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "dependencies": { + "express": "^4.14.0", + "socket.io": "^1.7.1" + }, + "author": "Moe Alam", + "license": "MIT" +} diff --git a/tools/getGitLog.js b/tools/getGitLog.js new file mode 100644 index 0000000..8bf9b4b --- /dev/null +++ b/tools/getGitLog.js @@ -0,0 +1,2 @@ +var fs = require('fs'); +fs.readFileSync(__dirname+'/.git/logs/') \ No newline at end of file diff --git a/tools/getVersionFromGit.js b/tools/getVersionFromGit.js new file mode 100644 index 0000000..b2009f5 --- /dev/null +++ b/tools/getVersionFromGit.js @@ -0,0 +1,23 @@ +var fs = require('fs'); +var branch = fs.readFileSync(__dirname+'/../.git/HEAD','utf8').replace('ref: refs/heads/',''); +var version = fs.readFileSync(__dirname+'/../.git/FETCH_HEAD','utf8').split('\t')[0]; +var rawLogRows = fs.readFileSync(__dirname+'/../.git/logs/HEAD','utf8').split('\t'); +var prettyLog = []; + +rawLogRows.forEach(function(logRow,n){ + var log = logRow.split('\n')[1].replace('\n','') + if(log){ + var log = log.split(' ') + prettyLog.push({ + version:log[1], + lastVersion:log[0], + time:log[4], + timezone:log[5] + }) + } +}) +module.exports = { + version:version, + branch:branch, + log:prettyLog, +} diff --git a/tools/httpHookTest.js b/tools/httpHookTest.js new file mode 100644 index 0000000..26147e7 --- /dev/null +++ b/tools/httpHookTest.js @@ -0,0 +1,23 @@ + var express = require("express"); + var app = express(); + + /* serves main page */ + app.get("/", function(req, res) { + console.log('Home Test Success') + res.end("Home Test Success"); + }); + + app.get("/test", function(req, res) { + console.log('Hook Test Success') + res.end("Hook Test Success"); + }); + + app.post("/post", function(req, res) { + console.log('Post Test Success') + res.end("Post Test Success"); + }); + + var port = process.env.PORT || 5000; + app.listen(port, function() { + console.log("Listening on " + port); + }); \ No newline at end of file diff --git a/tools/matchFeaturesTest/PeopleCounterMain.js b/tools/matchFeaturesTest/PeopleCounterMain.js new file mode 100644 index 0000000..553836d --- /dev/null +++ b/tools/matchFeaturesTest/PeopleCounterMain.js @@ -0,0 +1,109 @@ +; +var argparse = require('argparse'); +var datetime = require('datetime'); +var imutils = require('imutils'); +var math = require('math'); +var cv2 = require('opencv4nodejs'); +var np = require('numpy'); + +width = 800; + +textIn = 0; +textOut = 0; + +function testIntersectionIn(x, y) { + + res = -450 * x + 400 * y + 157500; + if((res >= -550) && (res < 550))) { + console.log (str(res)); + return true; + return false; + } +} + +function testIntersectionOut(x, y) { + res = -450 * x + 400 * y + 180000; + if (res >= -550) && (res <= 550))) { + console.log (str(res)); + return true; + } + return false; +} +camera = cv2.VideoCapture('test2.mp4'); + +firstFrame = null; + +// loop over the frames of the video +while (true) { + // grab the current frame and initialize the occupied/unoccupied + // text + (grabbed, frame) = camera.read(); + text = 'Unoccupied'; +} + // if the frame could not be grabbed, then we have reached the end + // of the video + if (!grabbed) { + break; + } + // resize the frame, convert it to grayscale, and blur it + frame = imutils.resize(frame, width=width); + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY); + gray = cv2.GaussianBlur(gray, (21, 21), 0); + + // if the first frame is None, initialize it + if (firstFrame === null) { + firstFrame = gray; + continue; + } + // compute the absolute difference between the current frame and + // first frame + frameDelta = cv2.absdiff(firstFrame, gray); + thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]; + // dilate the thresholded image to fill in holes, then find contours + // on thresholded image + thresh = cv2.dilate(thresh, null, iterations=2); + _, cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE); + // loop over the contours + for (c in cnts) { + // if the contour is too small, ignore it + if (cv2.contourArea(c) < 12000) { + continue; + // compute the bounding box for the contour, draw it on the frame, + // and update the text + (x, y, w, h) = cv2.boundingRect(c); + cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2); + } + cv2.line(frame, (width / 2, 0), (width, 450), (250, 0, 1), 2) #blue line; + cv2.line(frame, (width / 2 - 50, 0), (width - 50, 450), (0, 0, 255), 2)#red line; + } + + rectagleCenterPont = ((x + x + w) /2, (y + y + h) /2); + cv2.circle(frame, rectagleCenterPont, 1, (0, 0, 255), 5); + + if(testIntersectionIn((x + x + w) / 2, (y + y + h) / 2))) { + textIn += 1; + } + if(testIntersectionOut((x + x + w) / 2, (y + y + h) / 2))) { + textOut += 1; + } + // draw the text and timestamp on the frame + + // show the frame and record if the user presses a key + // cv2.imshow("Thresh", thresh) + // cv2.imshow("Frame Delta", frameDelta) + + if (cv2.waitKey(1) & 0xFF == ord('q')) { + break; + } + cv2.putText(frame, 'In: {}'.format(str(textIn)), (10, 50), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2); + cv2.putText(frame, 'Out: {}'.format(str(textOut)), (10, 70), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2); + cv2.putText(frame, datetime.datetime.now().strftime('%A %d %B %Y %I:%M:%S%p'), + (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1); + cv2.imshow('Security Feed', frame); + + +// cleanup the camera and close any open windows +camera.release(); +cv2.destroyAllWindows(); diff --git a/tools/matchFeaturesTest/findwaldo.jpg b/tools/matchFeaturesTest/findwaldo.jpg new file mode 100644 index 0000000..96b498a Binary files /dev/null and b/tools/matchFeaturesTest/findwaldo.jpg differ diff --git a/tools/matchFeaturesTest/matchFeaturesTest.js b/tools/matchFeaturesTest/matchFeaturesTest.js new file mode 100644 index 0000000..ba2cf48 --- /dev/null +++ b/tools/matchFeaturesTest/matchFeaturesTest.js @@ -0,0 +1,98 @@ +const cv = require('opencv4nodejs'); + +width = 800 + +textIn = 0 +textOut = 0 + +testIntersectionIn = function(x, y): + + res = -450 * x + 400 * y + 157500 + if((res >= -550) and (res < 550)): + print (str(res)) + return True + return False + + + +testIntersectionOut = function(x, y): + res = -450 * x + 400 * y + 180000 + if ((res >= -550) and (res <= 550)): + print (str(res)) + return True + + return False + +camera = cv2.VideoCapture("test2.mp4") + +firstFrame = None + +# loop over the frames of the video +while True: + # grab the current frame and initialize the occupied/unoccupied + # text + (grabbed, frame) = camera.read() + text = "Unoccupied" + + # if the frame could not be grabbed, then we have reached the end + # of the video + if not grabbed: + break + + # resize the frame, convert it to grayscale, and blur it + frame = imutils.resize(frame, width=width) + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + gray = cv2.GaussianBlur(gray, (21, 21), 0) + + # if the first frame is None, initialize it + if firstFrame is None: + firstFrame = gray + continue + + # compute the absolute difference between the current frame and + # first frame + frameDelta = cv2.absdiff(firstFrame, gray) + thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1] + # dilate the thresholded image to fill in holes, then find contours + # on thresholded image + thresh = cv2.dilate(thresh, None, iterations=2) + _, cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + # loop over the contours + for c in cnts: + # if the contour is too small, ignore it + if cv2.contourArea(c) < 12000: + continue + # compute the bounding box for the contour, draw it on the frame, + # and update the text + (x, y, w, h) = cv2.boundingRect(c) + cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) + + cv2.line(frame, (width / 2, 0), (width, 450), (250, 0, 1), 2) #blue line + cv2.line(frame, (width / 2 - 50, 0), (width - 50, 450), (0, 0, 255), 2)#red line + + + rectagleCenterPont = ((x + x + w) /2, (y + y + h) /2) + cv2.circle(frame, rectagleCenterPont, 1, (0, 0, 255), 5) + + if(testIntersectionIn((x + x + w) / 2, (y + y + h) / 2)): + textIn += 1 + + if(testIntersectionOut((x + x + w) / 2, (y + y + h) / 2)): + textOut += 1 + + # draw the text and timestamp on the frame + + # show the frame and record if the user presses a key + # cv2.imshow("Thresh", thresh) + # cv2.imshow("Frame Delta", frameDelta) + + if cv2.waitKey(1) & 0xFF == ord('q'): + break + + cv2.putText(frame, "In: {}".format(str(textIn)), (10, 50), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) + cv2.putText(frame, "Out: {}".format(str(textOut)), (10, 70), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) + cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"), + (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1) + cv2.imshow("Security Feed", frame) \ No newline at end of file diff --git a/tools/matchFeaturesTest/waldo.jpg b/tools/matchFeaturesTest/waldo.jpg new file mode 100644 index 0000000..d5e01d7 Binary files /dev/null and b/tools/matchFeaturesTest/waldo.jpg differ diff --git a/tools/modifyConfiguration.js b/tools/modifyConfiguration.js new file mode 100644 index 0000000..f73fbea --- /dev/null +++ b/tools/modifyConfiguration.js @@ -0,0 +1,30 @@ +process.on('uncaughtException', function (err) { + console.error('Uncaught Exception occured!'); + console.error(err.stack); +}); +var configLocation = __dirname+'/../conf.json'; +var fs = require('fs'); +var jsonfile = require("jsonfile"); +var config = jsonfile.readFileSync(configLocation); +var processArgv = process.argv.splice(2,process.argv.length) +var arguments = {}; +processArgv.forEach(function(val) { + var theSplit = val.split('='); + var index = theSplit[0]; + var value = theSplit[1]; + if(value==='DELETE'){ + delete(config[index]) + }else{ + try{ + config[index] = JSON.parse(value); + }catch(err){ + config[index] = value; + } + } + console.log(index + ': ' + value); +}); + +jsonfile.writeFile(configLocation,config,{spaces: 2},function(){ + console.log('Changes Complete. Here is what it is now.') + console.log(JSON.stringify(config,null,2)) +}) \ No newline at end of file diff --git a/tools/sql2mongo/mesh.js b/tools/sql2mongo/mesh.js new file mode 100644 index 0000000..660a463 --- /dev/null +++ b/tools/sql2mongo/mesh.js @@ -0,0 +1,2342 @@ +/*global print, _, moment, db, ObjectId, hostname */ +/*! + * mesh - the MongoDB Extended Shell + * + * Version: 1.5.0 + * Date: September 25th, 2013 + * Project: http://skratchdot.com/projects/mesh/ + * Source Code: https://github.com/skratchdot/mesh/ + * Issues: https://github.com/skratchdot/mesh/issues/ + * Included Libraries: https://github.com/skratchdot/mesh/#whats-included + * Dependencies: MongoDB v1.8+ + * + * Copyright 2013 + * Dual licensed under the MIT or GPL Version 2 licenses. + * https://raw.github.com/skratchdot/mesh/master/LICENSE-MIT.txt + * https://raw.github.com/skratchdot/mesh/master/LICENSE-GPL.txt + * + */ +var mesh = (function (global) { + 'use strict'; + + var api, + version = "1.5.0", + lastTime = null, + config = { + defaultPrompt : 0, // 0-4 or a string + aliases : {} // can pass in a map of aliases. see: mesh.setAliases(); + }; + + /* + * This is the "mesh" function. If someone types: mesh(), then we will just + * print the current version info. + */ + api = function () { + return api.version(); + }; + + /* + * We can override the default settings by calling this function. + * + * The idea is to keep a "mesh.config.js" file that calls this function. + * + * When updating mesh.js, we will never override mesh.config.js + */ + api.config = function (settings) { + // Handle defaultPrompt + if (settings.hasOwnProperty('defaultPrompt')) { + config.defaultPrompt = settings.defaultPrompt; + api.prompt(config.defaultPrompt); + } + if (settings.hasOwnProperty('aliases') && typeof settings.aliases === 'object') { + api.setAliases(settings.aliases); + } + }; + + /* + * Print the current version + */ + api.version = function () { + return print('mesh (the MongoDB Extended Shell) version: ' + version); + }; + + /* + * Print help information. + * + * TODO: make sure that "help mesh" works as well by overriding default mongo help() + */ + api.help = function () { + api.version(); + print('help coming soon!'); + }; + + /* + * Accept a map of aliases. The keys are the aliases, and the values + * are the paths to the variable. + * + * For instance, if we want to create an aliase for mesh.keys() to be k(), then + * we can call: + * + * mesh.setAliases({'k':'mesh.keys'}); + * + * We can create an alias for printjson() by doing something like: + * + * mesh.setAliases({'pj':'printjson'}); + * + */ + api.setAliases = function (aliases) { + var alias, keys, i, skip, obj; + + // do nothing if we weren't passed key/value pairs + if (typeof aliases !== 'object') { + return; + } + + // loop through our aliases + for (alias in aliases) { + if (aliases.hasOwnProperty(alias)) { + // we process dot delimited strings + keys = aliases[alias]; + if (typeof keys === 'string' && keys.length > 0) { + // we will drill down into the dot delimited string. + // if the given variable path doesn't exist, let's + // try to process the next alias + skip = false; + obj = global; + keys = keys.split('.'); + for (i = 0; i < keys.length; i++) { + if (obj && obj[keys[i]]) { + obj = obj[keys[i]]; + } else { + i = keys.length; + skip = true; + } + } + if (!skip) { + global[alias] = obj; + } + } + } + } + }; + + /* + * Sets the default prompt. + * + * See: http://www.kchodorow.com/blog/2011/06/27/ps1/ + * + * newPrompt can be a function, or a number: + * + * 0: '>' reset to default prompt + * 1: 'dbname>' + * 2: 'dbname>' for PRIMARY, '(dbname)>' for SECONDARY + * 3: 'host:dbname>' + * 4: '[YYYY-MM-DD hh:mm:ss] host:dbname>' + */ + api.prompt = function (newPrompt) { + var base = '> '; + if (typeof newPrompt === 'function') { + global.prompt = newPrompt; + } else if (newPrompt === 1) { + global.prompt = function () { + return db.getName() + base; + }; + } else if (newPrompt === 2) { + global.prompt = function () { + var isMaster = db.isMaster().ismaster; + return (isMaster ? '' : '(') + + db.getName() + + (isMaster ? '' : ')') + + base; + }; + } else if (newPrompt === 3) { + global.prompt = function () { + var isMaster = db.isMaster().ismaster; + return (isMaster ? '' : '(') + + hostname() + ":" + + db.getName() + + (isMaster ? '' : ')') + + base; + }; + } else if (newPrompt === 4) { + global.prompt = function () { + var isMaster = db.isMaster().ismaster; + return '[' + moment().format('YYYY-MM-DD hh:mm:ss') + '] ' + + (isMaster ? '' : '(') + + db.serverStatus().host + ":" + + db.getName() + + (isMaster ? '' : ')') + + base; + }; + } else if (typeof newPrompt === 'string') { + global.prompt = function () { + return newPrompt; + }; + } else { + delete global.prompt; + } + }; + + /* + * A simple wrapper for ObjectId(); + */ + api.oid = function (oidString) { + if (typeof oidString === 'string') { + return new ObjectId(oidString); + } + return new ObjectId(); + }; + + /* + * Generate an ObjectId() based on a time stamp. + * + * usage: + * + * // pass in nothing to get an ObjectId based on the current timestamp + * mesh.tid(); + * // you can pass in any valid Date object + * mesh.tid(new Date()); + * // you can pass in any valid moment object + * mesh.tid(moment()); + * mesh.tid('2 minutes ago'); + * mesh.tid('June 1, 2012'); // returns ObjectId("4fc83e400000000000000000") + * // you can pass in an optional increment value + * mesh.tid('June 1, 2012', 3); // returns ObjectId("4fc83e400000000000000003") + * + * see: + * + * http://www.kchodorow.com/blog/2011/12/20/querying-for-timestamps-using-objectids/ + * http://www.mongodb.org/display/DOCS/Object+IDs + * + * ObjectIds are 12-byte BSON objects: + * + * TimeStamp [bytes 0-3]: + * This is a unix style timestamp. It is a signed int representing + * the number of seconds before or after January 1st 1970 (UTC). + * + * Machine [bytes 4-6] + * This is the first three bytes of the (md5) hash of the machine host + * name, or of the mac/network address, or the virtual machine id. + * + * Pid [bytes 7-8] + * This is 2 bytes of the process id (or thread id) of the process + * generating the ObjectId. + * + * Increment [bytes 9-11] + * This is an ever incrementing value starting with a random number. + */ + api.tid = function (newMoment, inc) { + var theDate, seconds, hexSecs, hexInc; + + // build timestamp portion of ObjectId + newMoment = moment(newMoment); + if (newMoment && newMoment.isValid && newMoment.isValid()) { + theDate = newMoment.toDate(); + } else { + theDate = new Date(); + } + seconds = parseInt(theDate.getTime() / 1000, 10); + hexSecs = seconds.toString(16); + + // build increment portion of ObjectId + if (typeof inc !== 'number') { + inc = 0; + } + hexInc = _.lpad(parseInt(inc, 10).toString(16), 3, '0').substring(0, 3); + return new ObjectId(hexSecs + '0000000000000' + hexInc); + }; + + /* + * Returns a sorted array of all the keys in an object + */ + api.keys = function (obj) { + return _.keys(obj || global).sort(); + }; + + /* + * If passed a function, it will display the function execution time. + * + * If passed anything else, it will just print the current time. + * + * This function keeps track of the last time it was called, and will output + * how long it's been since the last time it was called. + */ + api.time = function (obj) { + var start = moment(), + formatString = 'YYYY-MM-DD hh:mm:ss a'; + + // Current Time + print('Current Time: ' + start.format(formatString)); + + // Last time called + if (lastTime !== null) { + print('Last time called ' + lastTime.fromNow() + ' [' + start.format(formatString) + ']'); + } + + // Execute function if one is passed + if (typeof obj === 'function') { + print('Executing function...'); + obj.apply(); + print(' Started ' + start.fromNow()); + print('Finished: ' + moment().format(formatString)); + } + + // Save last time + lastTime = start; + }; + + return api; +}(this)); + +/*jslint maxerr: 50, indent: 4, plusplus: true */ +/** + * console.js - a quick wrapper so console calls don't error out in the mongodb shell + * + * All console calls are currently just wrappers for the built in print() function that + * comes with the mongo shell. Eventually, it would be good to add "real" behavior to + * the console calls. For instance, console.error() should wrap ThrowError(), and console.timer() + * should work as well. + * + */ +(function (global) { + 'use strict'; + + var i = 0, + functionNames = [ + 'assert', 'clear', 'count', 'debug', 'dir', + 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', + 'groupEnd', 'info', 'log', 'profile', 'profileEnd', 'table', + 'time', 'timeEnd', 'timeStamp', 'trace', 'warn' + ], + wrapperFunction = function () { + print.apply(global, arguments); + }; + + // Make sure console exists + global.console = global.console || {}; + + // Make sure all functions exist + for (i = 0; i < functionNames.length; i++) { + global.console[functionNames[i]] = global.console[functionNames[i]] || wrapperFunction; + } + +}(this)); + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function () { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function () { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); + +/*jslint evil: true, regexp: true */ + +/*members $ref, apply, call, decycle, hasOwnProperty, length, prototype, push, + retrocycle, stringify, test, toString +*/ + +if (typeof JSON.decycle !== 'function') { + JSON.decycle = function decycle(object) { + 'use strict'; + +// Make a deep copy of an object or array, assuring that there is at most +// one instance of each object or array in the resulting structure. The +// duplicate references (which might be forming cycles) are replaced with +// an object of the form +// {$ref: PATH} +// where the PATH is a JSONPath string that locates the first occurance. +// So, +// var a = []; +// a[0] = a; +// return JSON.stringify(JSON.decycle(a)); +// produces the string '[{"$ref":"$"}]'. + +// JSONPath is used to locate the unique object. $ indicates the top level of +// the object or array. [NUMBER] or [STRING] indicates a child member or +// property. + + var objects = [], // Keep a reference to each unique object or array + paths = []; // Keep the path to each unique object or array + + return (function derez(value, path) { + +// The derez recurses through the object, producing the deep copy. + + var i, // The loop counter + name, // Property name + nu; // The new object or array + +// typeof null === 'object', so go on if this value is really an object but not +// one of the weird builtin objects. + + if (typeof value === 'object' && value !== null && + !(value instanceof Boolean) && + !(value instanceof Date) && + !(value instanceof Number) && + !(value instanceof RegExp) && + !(value instanceof String)) { + +// If the value is an object or array, look to see if we have already +// encountered it. If so, return a $ref/path object. This is a hard way, +// linear search that will get slower as the number of unique objects grows. + + for (i = 0; i < objects.length; i += 1) { + if (objects[i] === value) { + return {$ref: paths[i]}; + } + } + +// Otherwise, accumulate the unique value and its path. + + objects.push(value); + paths.push(path); + +// If it is an array, replicate the array. + + if (Object.prototype.toString.apply(value) === '[object Array]') { + nu = []; + for (i = 0; i < value.length; i += 1) { + nu[i] = derez(value[i], path + '[' + i + ']'); + } + } else { + +// If it is an object, replicate the object. + + nu = {}; + for (name in value) { + if (Object.prototype.hasOwnProperty.call(value, name)) { + nu[name] = derez(value[name], + path + '[' + JSON.stringify(name) + ']'); + } + } + } + return nu; + } + return value; + }(object, '$')); + }; +} + + +if (typeof JSON.retrocycle !== 'function') { + JSON.retrocycle = function retrocycle($) { + 'use strict'; + +// Restore an object that was reduced by decycle. Members whose values are +// objects of the form +// {$ref: PATH} +// are replaced with references to the value found by the PATH. This will +// restore cycles. The object will be mutated. + +// The eval function is used to locate the values described by a PATH. The +// root object is kept in a $ variable. A regular expression is used to +// assure that the PATH is extremely well formed. The regexp contains nested +// * quantifiers. That has been known to have extremely bad performance +// problems on some browsers for very long strings. A PATH is expected to be +// reasonably short. A PATH is allowed to belong to a very restricted subset of +// Goessner's JSONPath. + +// So, +// var s = '[{"$ref":"$"}]'; +// return JSON.retrocycle(JSON.parse(s)); +// produces an array containing a single element which is the array itself. + + var px = + /^\$(?:\[(?:\d+|\"(?:[^\\\"\u0000-\u001f]|\\([\\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*\")\])*$/; + + (function rez(value) { + +// The rez function walks recursively through the object looking for $ref +// properties. When it finds one that has a value that is a path, then it +// replaces the $ref object with a reference to the value that is found by +// the path. + + var i, item, name, path; + + if (value && typeof value === 'object') { + if (Object.prototype.toString.apply(value) === '[object Array]') { + for (i = 0; i < value.length; i += 1) { + item = value[i]; + if (item && typeof item === 'object') { + path = item.$ref; + if (typeof path === 'string' && px.test(path)) { + value[i] = eval(path); + } else { + rez(item); + } + } + } + } else { + for (name in value) { + if (typeof value[name] === 'object') { + item = value[name]; + if (item) { + path = item.$ref; + if (typeof path === 'string' && px.test(path)) { + value[name] = eval(path); + } else { + rez(item); + } + } + } + } + } + } + }($)); + return $; + }; +} + +// Underscore.js 1.5.2 +// http://underscorejs.org +// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. +(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,g=e.filter,d=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,w=Object.keys,_=i.bind,j=function(n){return n instanceof j?n:this instanceof j?(this._wrapped=n,void 0):new j(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=j),exports._=j):n._=j,j.VERSION="1.5.2";var A=j.each=j.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a=j.keys(n),u=0,i=a.length;i>u;u++)if(t.call(e,n[a[u]],a[u],n)===r)return};j.map=j.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e.push(t.call(r,n,u,i))}),e)};var E="Reduce of empty array with no initial value";j.reduce=j.foldl=j.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=j.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(E);return r},j.reduceRight=j.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=j.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=j.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(E);return r},j.find=j.detect=function(n,t,r){var e;return O(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},j.filter=j.select=function(n,t,r){var e=[];return null==n?e:g&&n.filter===g?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&e.push(n)}),e)},j.reject=function(n,t,r){return j.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},j.every=j.all=function(n,t,e){t||(t=j.identity);var u=!0;return null==n?u:d&&n.every===d?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var O=j.some=j.any=function(n,t,e){t||(t=j.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};j.contains=j.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:O(n,function(n){return n===t})},j.invoke=function(n,t){var r=o.call(arguments,2),e=j.isFunction(t);return j.map(n,function(n){return(e?t:n[t]).apply(n,r)})},j.pluck=function(n,t){return j.map(n,function(n){return n[t]})},j.where=function(n,t,r){return j.isEmpty(t)?r?void 0:[]:j[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},j.findWhere=function(n,t){return j.where(n,t,!0)},j.max=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.max.apply(Math,n);if(!t&&j.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>e.computed&&(e={value:n,computed:a})}),e.value},j.min=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.min.apply(Math,n);if(!t&&j.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;ae||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={},i=null==r?j.identity:k(r);return A(t,function(r,a){var o=i.call(e,r,a,t);n(u,o,r)}),u}};j.groupBy=F(function(n,t,r){(j.has(n,t)?n[t]:n[t]=[]).push(r)}),j.indexBy=F(function(n,t,r){n[t]=r}),j.countBy=F(function(n,t){j.has(n,t)?n[t]++:n[t]=1}),j.sortedIndex=function(n,t,r,e){r=null==r?j.identity:k(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;r.call(e,n[o])=0})})},j.difference=function(n){var t=c.apply(e,o.call(arguments,1));return j.filter(n,function(n){return!j.contains(t,n)})},j.zip=function(){for(var n=j.max(j.pluck(arguments,"length").concat(0)),t=new Array(n),r=0;n>r;r++)t[r]=j.pluck(arguments,""+r);return t},j.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},j.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=j.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},j.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},j.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=new Array(e);e>u;)i[u++]=n,n+=r;return i};var R=function(){};j.bind=function(n,t){var r,e;if(_&&n.bind===_)return _.apply(n,o.call(arguments,1));if(!j.isFunction(n))throw new TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(o.call(arguments)));R.prototype=n.prototype;var u=new R;R.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return Object(i)===i?i:u}},j.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},j.bindAll=function(n){var t=o.call(arguments,1);if(0===t.length)throw new Error("bindAll must be passed function names");return A(t,function(t){n[t]=j.bind(n[t],n)}),n},j.memoize=function(n,t){var r={};return t||(t=j.identity),function(){var e=t.apply(this,arguments);return j.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},j.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},j.defer=function(n){return j.delay.apply(j,[n,1].concat(o.call(arguments,1)))},j.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var c=function(){o=r.leading===!1?0:new Date,a=null,i=n.apply(e,u)};return function(){var l=new Date;o||r.leading!==!1||(o=l);var f=t-(l-o);return e=this,u=arguments,0>=f?(clearTimeout(a),a=null,o=l,i=n.apply(e,u)):a||r.trailing===!1||(a=setTimeout(c,f)),i}},j.debounce=function(n,t,r){var e,u,i,a,o;return function(){i=this,u=arguments,a=new Date;var c=function(){var l=new Date-a;t>l?e=setTimeout(c,t-l):(e=null,r||(o=n.apply(i,u)))},l=r&&!e;return e||(e=setTimeout(c,t)),l&&(o=n.apply(i,u)),o}},j.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},j.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},j.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},j.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},j.keys=w||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)j.has(n,r)&&t.push(r);return t},j.values=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},j.pairs=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},j.invert=function(n){for(var t={},r=j.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},j.functions=j.methods=function(n){var t=[];for(var r in n)j.isFunction(n[r])&&t.push(r);return t.sort()},j.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},j.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},j.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)j.contains(r,u)||(t[u]=n[u]);return t},j.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]===void 0&&(n[r]=t[r])}),n},j.clone=function(n){return j.isObject(n)?j.isArray(n)?n.slice():j.extend({},n):n},j.tap=function(n,t){return t(n),n};var S=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof j&&(n=n._wrapped),t instanceof j&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==String(t);case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;var a=n.constructor,o=t.constructor;if(a!==o&&!(j.isFunction(a)&&a instanceof a&&j.isFunction(o)&&o instanceof o))return!1;r.push(n),e.push(t);var c=0,f=!0;if("[object Array]"==u){if(c=n.length,f=c==t.length)for(;c--&&(f=S(n[c],t[c],r,e)););}else{for(var s in n)if(j.has(n,s)&&(c++,!(f=j.has(t,s)&&S(n[s],t[s],r,e))))break;if(f){for(s in t)if(j.has(t,s)&&!c--)break;f=!c}}return r.pop(),e.pop(),f};j.isEqual=function(n,t){return S(n,t,[],[])},j.isEmpty=function(n){if(null==n)return!0;if(j.isArray(n)||j.isString(n))return 0===n.length;for(var t in n)if(j.has(n,t))return!1;return!0},j.isElement=function(n){return!(!n||1!==n.nodeType)},j.isArray=x||function(n){return"[object Array]"==l.call(n)},j.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){j["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),j.isArguments(arguments)||(j.isArguments=function(n){return!(!n||!j.has(n,"callee"))}),"function"!=typeof/./&&(j.isFunction=function(n){return"function"==typeof n}),j.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},j.isNaN=function(n){return j.isNumber(n)&&n!=+n},j.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},j.isNull=function(n){return null===n},j.isUndefined=function(n){return n===void 0},j.has=function(n,t){return f.call(n,t)},j.noConflict=function(){return n._=t,this},j.identity=function(n){return n},j.times=function(n,t,r){for(var e=Array(Math.max(0,n)),u=0;n>u;u++)e[u]=t.call(r,u);return e},j.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var I={escape:{"&":"&","<":"<",">":">",'"':""","'":"'"}};I.unescape=j.invert(I.escape);var T={escape:new RegExp("["+j.keys(I.escape).join("")+"]","g"),unescape:new RegExp("("+j.keys(I.unescape).join("|")+")","g")};j.each(["escape","unescape"],function(n){j[n]=function(t){return null==t?"":(""+t).replace(T[n],function(t){return I[n][t]})}}),j.result=function(n,t){if(null==n)return void 0;var r=n[t];return j.isFunction(r)?r.call(n):r},j.mixin=function(n){A(j.functions(n),function(t){var r=j[t]=n[t];j.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),z.call(this,r.apply(j,n))}})};var N=0;j.uniqueId=function(n){var t=++N+"";return n?n+t:t},j.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;j.template=function(n,t,r){var e;r=j.defaults({},r,j.templateSettings);var u=new RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(D,function(n){return"\\"+B[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=new Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,j);var c=function(n){return e.call(this,n,j)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},j.chain=function(n){return j(n).chain()};var z=function(n){return this._chain?j(n).chain():n};j.mixin(j),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];j.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];j.prototype[n]=function(){return z.call(this,t.apply(this._wrapped,arguments))}}),j.extend(j.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this); +//# sourceMappingURL=underscore-min.map +!function(e,n){"use strict";function r(e,n){var r,t,u=e.toLowerCase();for(n=[].concat(n),r=0;n.length>r;r+=1)if(t=n[r]){if(t.test&&t.test(e))return!0;if(t.toLowerCase()===u)return!0}}var t=n.prototype.trim,u=n.prototype.trimRight,i=n.prototype.trimLeft,l=function(e){return 1*e||0},o=function(e,n){if(1>n)return"";for(var r="";n>0;)1&n&&(r+=e),n>>=1,e+=e;return r},a=[].slice,c=function(e){return null==e?"\\s":e.source?e.source:"["+g.escapeRegExp(e)+"]"},s={lt:"<",gt:">",quot:'"',amp:"&",apos:"'"},f={};for(var p in s)f[s[p]]=p;f["'"]="#39";var h=function(){function e(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}var r=o,t=function(){return t.cache.hasOwnProperty(arguments[0])||(t.cache[arguments[0]]=t.parse(arguments[0])),t.format.call(null,t.cache[arguments[0]],arguments)};return t.format=function(t,u){var i,l,o,a,c,s,f,p=1,g=t.length,d="",m=[];for(l=0;g>l;l++)if(d=e(t[l]),"string"===d)m.push(t[l]);else if("array"===d){if(a=t[l],a[2])for(i=u[p],o=0;a[2].length>o;o++){if(!i.hasOwnProperty(a[2][o]))throw new Error(h('[_.sprintf] property "%s" does not exist',a[2][o]));i=i[a[2][o]]}else i=a[1]?u[a[1]]:u[p++];if(/[^s]/.test(a[8])&&"number"!=e(i))throw new Error(h("[_.sprintf] expecting number but found %s",e(i)));switch(a[8]){case"b":i=i.toString(2);break;case"c":i=n.fromCharCode(i);break;case"d":i=parseInt(i,10);break;case"e":i=a[7]?i.toExponential(a[7]):i.toExponential();break;case"f":i=a[7]?parseFloat(i).toFixed(a[7]):parseFloat(i);break;case"o":i=i.toString(8);break;case"s":i=(i=n(i))&&a[7]?i.substring(0,a[7]):i;break;case"u":i=Math.abs(i);break;case"x":i=i.toString(16);break;case"X":i=i.toString(16).toUpperCase()}i=/[def]/.test(a[8])&&a[3]&&i>=0?"+"+i:i,s=a[4]?"0"==a[4]?"0":a[4].charAt(1):" ",f=a[6]-n(i).length,c=a[6]?r(s,f):"",m.push(a[5]?i+c:c+i)}return m.join("")},t.cache={},t.parse=function(e){for(var n=e,r=[],t=[],u=0;n;){if(null!==(r=/^[^\x25]+/.exec(n)))t.push(r[0]);else if(null!==(r=/^\x25{2}/.exec(n)))t.push("%");else{if(null===(r=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(n)))throw new Error("[_.sprintf] huh?");if(r[2]){u|=1;var i=[],l=r[2],o=[];if(null===(o=/^([a-z_][a-z_\d]*)/i.exec(l)))throw new Error("[_.sprintf] huh?");for(i.push(o[1]);""!==(l=l.substring(o[0].length));)if(null!==(o=/^\.([a-z_][a-z_\d]*)/i.exec(l)))i.push(o[1]);else{if(null===(o=/^\[(\d+)\]/.exec(l)))throw new Error("[_.sprintf] huh?");i.push(o[1])}r[2]=i}else u|=2;if(3===u)throw new Error("[_.sprintf] mixing positional and named placeholders is not (yet) supported");t.push(r)}n=n.substring(r[0].length)}return t},t}(),g={VERSION:"2.3.0",isBlank:function(e){return null==e&&(e=""),/^\s*$/.test(e)},stripTags:function(e){return null==e?"":n(e).replace(/<\/?[^>]+>/g,"")},capitalize:function(e){return e=null==e?"":n(e),e.charAt(0).toUpperCase()+e.slice(1)},chop:function(e,r){return null==e?[]:(e=n(e),r=~~r,r>0?e.match(new RegExp(".{1,"+r+"}","g")):[e])},clean:function(e){return g.strip(e).replace(/\s+/g," ")},count:function(e,r){if(null==e||null==r)return 0;e=n(e),r=n(r);for(var t=0,u=0,i=r.length;;){if(u=e.indexOf(r,u),-1===u)break;t++,u+=i}return t},chars:function(e){return null==e?[]:n(e).split("")},swapCase:function(e){return null==e?"":n(e).replace(/\S/g,function(e){return e===e.toUpperCase()?e.toLowerCase():e.toUpperCase()})},escapeHTML:function(e){return null==e?"":n(e).replace(/[&<>"']/g,function(e){return"&"+f[e]+";"})},unescapeHTML:function(e){return null==e?"":n(e).replace(/\&([^;]+);/g,function(e,r){var t;return r in s?s[r]:(t=r.match(/^#x([\da-fA-F]+)$/))?n.fromCharCode(parseInt(t[1],16)):(t=r.match(/^#(\d+)$/))?n.fromCharCode(~~t[1]):e})},escapeRegExp:function(e){return null==e?"":n(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},splice:function(e,n,r,t){var u=g.chars(e);return u.splice(~~n,~~r,t),u.join("")},insert:function(e,n,r){return g.splice(e,n,0,r)},include:function(e,r){return""===r?!0:null==e?!1:-1!==n(e).indexOf(r)},join:function(){var e=a.call(arguments),n=e.shift();return null==n&&(n=""),e.join(n)},lines:function(e){return null==e?[]:n(e).split("\n")},reverse:function(e){return g.chars(e).reverse().join("")},startsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(0,r.length)===r)},endsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(e.length-r.length)===r)},succ:function(e){return null==e?"":(e=n(e),e.slice(0,-1)+n.fromCharCode(e.charCodeAt(e.length-1)+1))},titleize:function(e){return null==e?"":(e=n(e).toLowerCase(),e.replace(/(?:^|\s|-)\S/g,function(e){return e.toUpperCase()}))},camelize:function(e){return g.trim(e).replace(/[-_\s]+(.)?/g,function(e,n){return n?n.toUpperCase():""})},underscored:function(e){return g.trim(e).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()},dasherize:function(e){return g.trim(e).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()},classify:function(e){return g.titleize(n(e).replace(/[\W_]/g," ")).replace(/\s/g,"")},humanize:function(e){return g.capitalize(g.underscored(e).replace(/_id$/,"").replace(/_/g," "))},trim:function(e,r){return null==e?"":!r&&t?t.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+|"+r+"+$","g"),""))},ltrim:function(e,r){return null==e?"":!r&&i?i.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+"),""))},rtrim:function(e,r){return null==e?"":!r&&u?u.call(e):(r=c(r),n(e).replace(new RegExp(r+"+$"),""))},truncate:function(e,r,t){return null==e?"":(e=n(e),t=t||"...",r=~~r,e.length>r?e.slice(0,r)+t:e)},prune:function(e,r,t){if(null==e)return"";if(e=n(e),r=~~r,t=null!=t?n(t):"...",r>=e.length)return e;var u=function(e){return e.toUpperCase()!==e.toLowerCase()?"A":" "},i=e.slice(0,r+1).replace(/.(?=\W*\w*$)/g,u);return i=i.slice(i.length-2).match(/\w\w/)?i.replace(/\s*\S+$/,""):g.rtrim(i.slice(0,i.length-1)),(i+t).length>e.length?e:e.slice(0,i.length)+t},words:function(e,n){return g.isBlank(e)?[]:g.trim(e,n).split(n||/\s+/)},pad:function(e,r,t,u){e=null==e?"":n(e),r=~~r;var i=0;switch(t?t.length>1&&(t=t.charAt(0)):t=" ",u){case"right":return i=r-e.length,e+o(t,i);case"both":return i=r-e.length,o(t,Math.ceil(i/2))+e+o(t,Math.floor(i/2));default:return i=r-e.length,o(t,i)+e}},lpad:function(e,n,r){return g.pad(e,n,r)},rpad:function(e,n,r){return g.pad(e,n,r,"right")},lrpad:function(e,n,r){return g.pad(e,n,r,"both")},sprintf:h,vsprintf:function(e,n){return n.unshift(e),h.apply(null,n)},toNumber:function(e,n){return e?(e=g.trim(e),e.match(/^-?\d+(?:\.\d+)?$/)?l(l(e).toFixed(~~n)):0/0):0},numberFormat:function(e,n,r,t){if(isNaN(e)||null==e)return"";e=e.toFixed(~~n),t="string"==typeof t?t:",";var u=e.split("."),i=u[0],l=u[1]?(r||".")+u[1]:"";return i.replace(/(\d)(?=(?:\d{3})+$)/g,"$1"+t)+l},strRight:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strRightBack:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.lastIndexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strLeft:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(0,t):e},strLeftBack:function(e,n){if(null==e)return"";e+="",n=null!=n?""+n:n;var r=e.lastIndexOf(n);return~r?e.slice(0,r):e},toSentence:function(e,n,r,t){n=n||", ",r=r||" and ";var u=e.slice(),i=u.pop();return e.length>2&&t&&(r=g.rtrim(n)+r),u.length?u.join(n)+r+i:i},toSentenceSerial:function(){var e=a.call(arguments);return e[3]=!0,g.toSentence.apply(g,e)},slugify:function(e){if(null==e)return"";var r="ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź",t="aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz",u=new RegExp(c(r),"g");return e=n(e).toLowerCase().replace(u,function(e){var n=r.indexOf(e);return t.charAt(n)||"-"}),g.dasherize(e.replace(/[^\w\s-]/g,""))},surround:function(e,n){return[n,e,n].join("")},quote:function(e,n){return g.surround(e,n||'"')},unquote:function(e,n){return n=n||'"',e[0]===n&&e[e.length-1]===n?e.slice(1,e.length-1):e},exports:function(){var e={};for(var n in this)this.hasOwnProperty(n)&&!n.match(/^(?:include|contains|reverse)$/)&&(e[n]=this[n]);return e},repeat:function(e,r,t){if(null==e)return"";if(r=~~r,null==t)return o(n(e),r);for(var u=[];r>0;u[--r]=e);return u.join(t)},naturalCmp:function(e,r){if(e==r)return 0;if(!e)return-1;if(!r)return 1;for(var t=/(\.\d+)|(\d+)|(\D+)/g,u=n(e).toLowerCase().match(t),i=n(r).toLowerCase().match(t),l=Math.min(u.length,i.length),o=0;l>o;o++){var a=u[o],c=i[o];if(a!==c){var s=parseInt(a,10);if(!isNaN(s)){var f=parseInt(c,10);if(!isNaN(f)&&s-f)return s-f}return c>a?-1:1}}return u.length===i.length?u.length-i.length:r>e?-1:1},levenshtein:function(e,r){if(null==e&&null==r)return 0;if(null==e)return n(r).length;if(null==r)return n(e).length;e=n(e),r=n(r);for(var t,u,i=[],l=0;r.length>=l;l++)for(var o=0;e.length>=o;o++)u=l&&o?e.charAt(o-1)===r.charAt(l-1)?t:Math.min(i[o],i[o-1],t)+1:l+o,t=i[o],i[o]=u;return i.pop()},toBoolean:function(e,n,t){return"number"==typeof e&&(e=""+e),"string"!=typeof e?!!e:(e=g.trim(e),r(e,n||["true","1"])?!0:r(e,t||["false","0"])?!1:void 0)}};g.strip=g.trim,g.lstrip=g.ltrim,g.rstrip=g.rtrim,g.center=g.lrpad,g.rjust=g.lpad,g.ljust=g.rpad,g.contains=g.include,g.q=g.quote,g.toBool=g.toBoolean,"undefined"!=typeof exports&&("undefined"!=typeof module&&module.exports&&(module.exports=g),exports._s=g),"function"==typeof define&&define.amd&&define("underscore.string",[],function(){return g}),e._=e._||{},e._.string=e._.str=g}(this,String); +//! moment.js +//! version : 2.2.1 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com +(function(a){function b(a,b){return function(c){return i(a.call(this,c),b)}}function c(a,b){return function(c){return this.lang().ordinal(a.call(this,c),b)}}function d(){}function e(a){g(this,a)}function f(a){var b=a.years||a.year||a.y||0,c=a.months||a.month||a.M||0,d=a.weeks||a.week||a.w||0,e=a.days||a.day||a.d||0,f=a.hours||a.hour||a.h||0,g=a.minutes||a.minute||a.m||0,h=a.seconds||a.second||a.s||0,i=a.milliseconds||a.millisecond||a.ms||0;this._input=a,this._milliseconds=+i+1e3*h+6e4*g+36e5*f,this._days=+e+7*d,this._months=+c+12*b,this._data={},this._bubble()}function g(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}function h(a){return 0>a?Math.ceil(a):Math.floor(a)}function i(a,b){for(var c=a+"";c.lengthc;c++)~~a[c]!==~~b[c]&&f++;return f+e}function m(a){return a?ib[a]||a.toLowerCase().replace(/(.)s$/,"$1"):a}function n(a,b){return b.abbr=a,P[a]||(P[a]=new d),P[a].set(b),P[a]}function o(a){delete P[a]}function p(a){if(!a)return L.fn._lang;if(!P[a]&&Q)try{require("./lang/"+a)}catch(b){return L.fn._lang}return P[a]||L.fn._lang}function q(a){return a.match(/\[.*\]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function r(a){var b,c,d=a.match(T);for(b=0,c=d.length;c>b;b++)d[b]=mb[d[b]]?mb[d[b]]:q(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function s(a,b){return b=t(b,a.lang()),jb[b]||(jb[b]=r(b)),jb[b](a)}function t(a,b){function c(a){return b.longDateFormat(a)||a}for(var d=5;d--&&(U.lastIndex=0,U.test(a));)a=a.replace(U,c);return a}function u(a,b){switch(a){case"DDDD":return X;case"YYYY":return Y;case"YYYYY":return Z;case"S":case"SS":case"SSS":case"DDD":return W;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return $;case"a":case"A":return p(b._l)._meridiemParse;case"X":return bb;case"Z":case"ZZ":return _;case"T":return ab;case"MM":case"DD":case"YY":case"HH":case"hh":case"mm":case"ss":case"M":case"D":case"d":case"H":case"h":case"m":case"s":return V;default:return new RegExp(a.replace("\\",""))}}function v(a){var b=(_.exec(a)||[])[0],c=(b+"").match(fb)||["-",0,0],d=+(60*c[1])+~~c[2];return"+"===c[0]?-d:d}function w(a,b,c){var d,e=c._a;switch(a){case"M":case"MM":null!=b&&(e[1]=~~b-1);break;case"MMM":case"MMMM":d=p(c._l).monthsParse(b),null!=d?e[1]=d:c._isValid=!1;break;case"D":case"DD":null!=b&&(e[2]=~~b);break;case"DDD":case"DDDD":null!=b&&(e[1]=0,e[2]=~~b);break;case"YY":e[0]=~~b+(~~b>68?1900:2e3);break;case"YYYY":case"YYYYY":e[0]=~~b;break;case"a":case"A":c._isPm=p(c._l).isPM(b);break;case"H":case"HH":case"h":case"hh":e[3]=~~b;break;case"m":case"mm":e[4]=~~b;break;case"s":case"ss":e[5]=~~b;break;case"S":case"SS":case"SSS":e[6]=~~(1e3*("0."+b));break;case"X":c._d=new Date(1e3*parseFloat(b));break;case"Z":case"ZZ":c._useUTC=!0,c._tzm=v(b)}null==b&&(c._isValid=!1)}function x(a){var b,c,d,e=[];if(!a._d){for(d=z(a),b=0;3>b&&null==a._a[b];++b)a._a[b]=e[b]=d[b];for(;7>b;b++)a._a[b]=e[b]=null==a._a[b]?2===b?1:0:a._a[b];e[3]+=~~((a._tzm||0)/60),e[4]+=~~((a._tzm||0)%60),c=new Date(0),a._useUTC?(c.setUTCFullYear(e[0],e[1],e[2]),c.setUTCHours(e[3],e[4],e[5],e[6])):(c.setFullYear(e[0],e[1],e[2]),c.setHours(e[3],e[4],e[5],e[6])),a._d=c}}function y(a){var b=a._i;a._d||(a._a=[b.years||b.year||b.y,b.months||b.month||b.M,b.days||b.day||b.d,b.hours||b.hour||b.h,b.minutes||b.minute||b.m,b.seconds||b.second||b.s,b.milliseconds||b.millisecond||b.ms],x(a))}function z(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function A(a){var b,c,d,e=p(a._l),f=""+a._i;for(d=t(a._f,e).match(T),a._a=[],b=0;bh&&(i=h,d=c);g(a,d)}function C(a){var b,c=a._i,d=cb.exec(c);if(d){for(a._f="YYYY-MM-DD"+(d[2]||" "),b=0;4>b;b++)if(eb[b][1].exec(c)){a._f+=eb[b][0];break}_.exec(c)&&(a._f+=" Z"),A(a)}else a._d=new Date(c)}function D(b){var c=b._i,d=R.exec(c);c===a?b._d=new Date:d?b._d=new Date(+d[1]):"string"==typeof c?C(b):k(c)?(b._a=c.slice(0),x(b)):c instanceof Date?b._d=new Date(+c):"object"==typeof c?y(b):b._d=new Date(c)}function E(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function F(a,b,c){var d=O(Math.abs(a)/1e3),e=O(d/60),f=O(e/60),g=O(f/24),h=O(g/365),i=45>d&&["s",d]||1===e&&["m"]||45>e&&["mm",e]||1===f&&["h"]||22>f&&["hh",f]||1===g&&["d"]||25>=g&&["dd",g]||45>=g&&["M"]||345>g&&["MM",O(g/30)]||1===h&&["y"]||["yy",h];return i[2]=b,i[3]=a>0,i[4]=c,E.apply({},i)}function G(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=L(a).add("d",f),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function H(a){var b=a._i,c=a._f;return null===b||""===b?null:("string"==typeof b&&(a._i=b=p().preparse(b)),L.isMoment(b)?(a=g({},b),a._d=new Date(+b._d)):c?k(c)?B(a):A(a):D(a),new e(a))}function I(a,b){L.fn[a]=L.fn[a+"s"]=function(a){var c=this._isUTC?"UTC":"";return null!=a?(this._d["set"+c+b](a),L.updateOffset(this),this):this._d["get"+c+b]()}}function J(a){L.duration.fn[a]=function(){return this._data[a]}}function K(a,b){L.duration.fn["as"+a]=function(){return+this/b}}for(var L,M,N="2.2.1",O=Math.round,P={},Q="undefined"!=typeof module&&module.exports,R=/^\/?Date\((\-?\d+)/i,S=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)\:(\d+)\.?(\d{3})?/,T=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,U=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,V=/\d\d?/,W=/\d{1,3}/,X=/\d{3}/,Y=/\d{1,4}/,Z=/[+\-]?\d{1,6}/,$=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,_=/Z|[\+\-]\d\d:?\d\d/i,ab=/T/i,bb=/[\+\-]?\d+(\.\d{1,3})?/,cb=/^\s*\d{4}-\d\d-\d\d((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,db="YYYY-MM-DDTHH:mm:ssZ",eb=[["HH:mm:ss.S",/(T| )\d\d:\d\d:\d\d\.\d{1,3}/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],fb=/([\+\-]|\d\d)/gi,gb="Date|Hours|Minutes|Seconds|Milliseconds".split("|"),hb={Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6},ib={ms:"millisecond",s:"second",m:"minute",h:"hour",d:"day",w:"week",W:"isoweek",M:"month",y:"year"},jb={},kb="DDD w W M D d".split(" "),lb="M D H h m s w W".split(" "),mb={M:function(){return this.month()+1},MMM:function(a){return this.lang().monthsShort(this,a)},MMMM:function(a){return this.lang().months(this,a)},D:function(){return this.date()},DDD:function(){return this.dayOfYear()},d:function(){return this.day()},dd:function(a){return this.lang().weekdaysMin(this,a)},ddd:function(a){return this.lang().weekdaysShort(this,a)},dddd:function(a){return this.lang().weekdays(this,a)},w:function(){return this.week()},W:function(){return this.isoWeek()},YY:function(){return i(this.year()%100,2)},YYYY:function(){return i(this.year(),4)},YYYYY:function(){return i(this.year(),5)},gg:function(){return i(this.weekYear()%100,2)},gggg:function(){return this.weekYear()},ggggg:function(){return i(this.weekYear(),5)},GG:function(){return i(this.isoWeekYear()%100,2)},GGGG:function(){return this.isoWeekYear()},GGGGG:function(){return i(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.lang().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.lang().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return~~(this.milliseconds()/100)},SS:function(){return i(~~(this.milliseconds()/10),2)},SSS:function(){return i(this.milliseconds(),3)},Z:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+i(~~(a/60),2)+":"+i(~~a%60,2)},ZZ:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+i(~~(10*a/6),4)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},X:function(){return this.unix()}};kb.length;)M=kb.pop(),mb[M+"o"]=c(mb[M],M);for(;lb.length;)M=lb.pop(),mb[M+M]=b(mb[M],2);for(mb.DDDD=b(mb.DDD,3),g(d.prototype,{set:function(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(a){return this._months[a.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(a){return this._monthsShort[a.month()]},monthsParse:function(a){var b,c,d;for(this._monthsParse||(this._monthsParse=[]),b=0;12>b;b++)if(this._monthsParse[b]||(c=L.utc([2e3,b]),d="^"+this.months(c,"")+"|^"+this.monthsShort(c,""),this._monthsParse[b]=new RegExp(d.replace(".",""),"i")),this._monthsParse[b].test(a))return b},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(a){return this._weekdays[a.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(a){return this._weekdaysShort[a.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(a){return this._weekdaysMin[a.day()]},weekdaysParse:function(a){var b,c,d;for(this._weekdaysParse||(this._weekdaysParse=[]),b=0;7>b;b++)if(this._weekdaysParse[b]||(c=L([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b},_longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D YYYY",LLL:"MMMM D YYYY LT",LLLL:"dddd, MMMM D YYYY LT"},longDateFormat:function(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b},isPM:function(a){return"p"===(a+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(a,b){var c=this._calendar[a];return"function"==typeof c?c.apply(b):c},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)},pastFuture:function(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)},ordinal:function(a){return this._ordinal.replace("%d",a)},_ordinal:"%d",preparse:function(a){return a},postformat:function(a){return a},week:function(a){return G(a,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6}}),L=function(a,b,c){return H({_i:a,_f:b,_l:c,_isUTC:!1})},L.utc=function(a,b,c){return H({_useUTC:!0,_isUTC:!0,_l:c,_i:a,_f:b}).utc()},L.unix=function(a){return L(1e3*a)},L.duration=function(a,b){var c,d,e=L.isDuration(a),g="number"==typeof a,h=e?a._input:g?{}:a,i=S.exec(a);return g?b?h[b]=a:h.milliseconds=a:i&&(c="-"===i[1]?-1:1,h={y:0,d:~~i[2]*c,h:~~i[3]*c,m:~~i[4]*c,s:~~i[5]*c,ms:~~i[6]*c}),d=new f(h),e&&a.hasOwnProperty("_lang")&&(d._lang=a._lang),d},L.version=N,L.defaultFormat=db,L.updateOffset=function(){},L.lang=function(a,b){return a?(a=a.toLowerCase(),a=a.replace("_","-"),b?n(a,b):null===b?(o(a),a="en"):P[a]||p(a),L.duration.fn._lang=L.fn._lang=p(a),void 0):L.fn._lang._abbr},L.langData=function(a){return a&&a._lang&&a._lang._abbr&&(a=a._lang._abbr),p(a)},L.isMoment=function(a){return a instanceof e},L.isDuration=function(a){return a instanceof f},g(L.fn=e.prototype,{clone:function(){return L(this)},valueOf:function(){return+this._d+6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){return s(L(this).utc(),"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},toArray:function(){var a=this;return[a.year(),a.month(),a.date(),a.hours(),a.minutes(),a.seconds(),a.milliseconds()]},isValid:function(){return null==this._isValid&&(this._isValid=this._a?!l(this._a,(this._isUTC?L.utc(this._a):L(this._a)).toArray()):!isNaN(this._d.getTime())),!!this._isValid},invalidAt:function(){var a,b=this._a,c=(this._isUTC?L.utc(this._a):L(this._a)).toArray();for(a=6;a>=0&&b[a]===c[a];--a);return a},utc:function(){return this.zone(0)},local:function(){return this.zone(0),this._isUTC=!1,this},format:function(a){var b=s(this,a||L.defaultFormat);return this.lang().postformat(b)},add:function(a,b){var c;return c="string"==typeof a?L.duration(+b,a):L.duration(a,b),j(this,c,1),this},subtract:function(a,b){var c;return c="string"==typeof a?L.duration(+b,a):L.duration(a,b),j(this,c,-1),this},diff:function(a,b,c){var d,e,f=this._isUTC?L(a).zone(this._offset||0):L(a).local(),g=6e4*(this.zone()-f.zone());return b=m(b),"year"===b||"month"===b?(d=432e5*(this.daysInMonth()+f.daysInMonth()),e=12*(this.year()-f.year())+(this.month()-f.month()),e+=(this-L(this).startOf("month")-(f-L(f).startOf("month")))/d,e-=6e4*(this.zone()-L(this).startOf("month").zone()-(f.zone()-L(f).startOf("month").zone()))/d,"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:h(e)},from:function(a,b){return L.duration(this.diff(a)).lang(this.lang()._abbr).humanize(!b)},fromNow:function(a){return this.from(L(),a)},calendar:function(){var a=this.diff(L().zone(this.zone()).startOf("day"),"days",!0),b=-6>a?"sameElse":-1>a?"lastWeek":0>a?"lastDay":1>a?"sameDay":2>a?"nextDay":7>a?"nextWeek":"sameElse";return this.format(this.lang().calendar(b,this))},isLeapYear:function(){var a=this.year();return 0===a%4&&0!==a%100||0===a%400},isDST:function(){return this.zone()+L(a).startOf(b)},isBefore:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)<+L(a).startOf(b)},isSame:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)===+L(a).startOf(b)},min:function(a){return a=L.apply(null,arguments),this>a?this:a},max:function(a){return a=L.apply(null,arguments),a>this?this:a},zone:function(a){var b=this._offset||0;return null==a?this._isUTC?b:this._d.getTimezoneOffset():("string"==typeof a&&(a=v(a)),Math.abs(a)<16&&(a=60*a),this._offset=a,this._isUTC=!0,b!==a&&j(this,L.duration(b-a,"m"),1,!0),this)},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},hasAlignedHourOffset:function(a){return a=a?L(a).zone():0,0===(this.zone()-a)%60},daysInMonth:function(){return L.utc([this.year(),this.month()+1,0]).date()},dayOfYear:function(a){var b=O((L(this).startOf("day")-L(this).startOf("year"))/864e5)+1;return null==a?b:this.add("d",a-b)},weekYear:function(a){var b=G(this,this.lang()._week.dow,this.lang()._week.doy).year;return null==a?b:this.add("y",a-b)},isoWeekYear:function(a){var b=G(this,1,4).year;return null==a?b:this.add("y",a-b)},week:function(a){var b=this.lang().week(this);return null==a?b:this.add("d",7*(a-b))},isoWeek:function(a){var b=G(this,1,4).week;return null==a?b:this.add("d",7*(a-b))},weekday:function(a){var b=(this._d.getDay()+7-this.lang()._week.dow)%7;return null==a?b:this.add("d",a-b)},isoWeekday:function(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)},get:function(a){return a=m(a),this[a.toLowerCase()]()},set:function(a,b){a=m(a),this[a.toLowerCase()](b)},lang:function(b){return b===a?this._lang:(this._lang=p(b),this)}}),M=0;M-0.00001?a+.5*a*a:Math.exp(a)-1},science.functor=function(a){return typeof a=="function"?a:function(){return a}},science.hypot=function(a,b){a=Math.abs(a),b=Math.abs(b);var c,d;a>b?(c=a,d=b):(c=b,d=a);var e=d/c;return c*Math.sqrt(1+e*e)},science.quadratic=function(){function b(b,c,d){var e=c*c-4*b*d;return e>0?(e=Math.sqrt(e)/(2*b),a?[{r:-c-e,i:0},{r:-c+e,i:0}]:[-c-e,-c+e]):e===0?(e=-c/(2*b),a?[{r:e,i:0}]:[e]):a?(e=Math.sqrt(-e)/(2*b),[{r:-c,i:-e},{r:-c,i:e}]):[]}var a=!1;return b.complex=function(c){return arguments.length?(a=c,b):a},b},science.zeroes=function(a){var b=-1,c=[];if(arguments.length===1)while(++b0;f--){var g=0,h=0;for(var i=0;i0&&(k=-k),b[f]=g*k,h-=j*k,a[f-1]=j-k;for(var e=0;ei){var k=0;do{k++;var l=a[i],m=(a[i+1]-l)/(2*b[i]),n=science.hypot(m,1);m<0&&(n=-n),a[i]=b[i]/(m+n),a[i+1]=b[i]*(m+n);var o=a[i+1],p=l-a[i];for(var e=i+2;e=i;e--){s=r,r=q,v=u,l=q*b[e],p=q*m,n=science.hypot(m,b[e]),b[e+1]=u*n,u=b[e]/n,q=m/n,m=q*a[e]-u*l,a[e+1]=p+u*(q*l+u*a[e]);for(var w=0;wh*g)}a[i]=a[i]+f,b[i]=0}for(var e=0;e=g;i--)d[i]=a[i][g-1]/h,j+=d[i]*d[i];var k=Math.sqrt(j);d[g]>0&&(k=-k),j-=d[g]*k,d[g]=d[g]-k;for(var l=g;l=g;i--)m+=d[i]*a[i][l];m/=j;for(var i=g;i<=f;i++)a[i][l]-=m*d[i]}for(var i=0;i<=f;i++){var m=0;for(var l=f;l>=g;l--)m+=d[l]*a[i][l];m/=j;for(var l=g;l<=f;l++)a[i][l]-=m*d[l]}d[g]=h*d[g],a[g][g-1]=h*k}}for(var i=0;i=e+1;g--)if(a[g][g-1]!==0){for(var i=g+1;i<=f;i++)d[i]=a[i][g-1];for(var l=g;l<=f;l++){var k=0;for(var i=g;i<=f;i++)k+=d[i]*b[i][l];k=k/d[g]/a[g][g-1];for(var i=g;i<=f;i++)b[i][l]+=k*d[i]}}}function e(a,b,c,d){var e=c.length,g=e-1,h=0,i=e-1,j=1e-12,k=0,l=0,m=0,n=0,o=0,p=0,q,r,s,t,u=0;for(var v=0;vi)a[v]=c[v][v],b[v]=0;for(var w=Math.max(v-1,0);w=h){var y=g;while(y>h){o=Math.abs(c[y-1][y-1])+Math.abs(c[y][y]),o===0&&(o=u);if(Math.abs(c[y][y-1])=0){p=l+(l>=0?p:-p),a[g-1]=s+p,a[g]=a[g-1],p!==0&&(a[g]=s-r/p),b[g-1]=0,b[g]=0,s=c[g][g-1],o=Math.abs(s)+Math.abs(p),l=s/o,m=p/o,n=Math.sqrt(l*l+m*m),l/=n,m/=n;for(var w=g-1;w0){o=Math.sqrt(o),t=y){p=c[z][z],n=s-p,o=t-p,l=(n*o-r)/c[z+1][z]+c[z][z+1],m=c[z+1][z+1]-p-n-o,n=c[z+2][z+1],o=Math.abs(l)+Math.abs(m)+Math.abs(n),l/=o,m/=o,n/=o;if(z==y)break;if(Math.abs(c[z][z-1])*(Math.abs(m)+Math.abs(n))z+2&&(c[v][v-3]=0);for(var A=z;A<=g-1;A++){var B=A!=g-1;A!=z&&(l=c[A][A-1],m=c[A+1][A-1],n=B?c[A+2][A-1]:0,s=Math.abs(l)+Math.abs(m)+Math.abs(n),s!=0&&(l/=s,m/=s,n/=s));if(s==0)break;o=Math.sqrt(l*l+m*m+n*n),l<0&&(o=-o);if(o!=0){A!=z?c[A][A-1]=-o*s:y!=z&&(c[A][A-1]=-c[A][A-1]),l+=o,s=l/o,t=m/o,p=n/o,m/=l,n/=l;for(var w=A;w=0;g--){l=a[g],m=b[g];if(m==0){var y=g;c[g][g]=1;for(var v=g-1;v>=0;v--){r=c[v][v]-l,n=0;for(var w=y;w<=g;w++)n+=c[v][w]*c[w][g];if(b[v]<0)p=r,o=n;else{y=v,b[v]===0?c[v][g]=-n/(r!==0?r:j*u):(s=c[v][v+1],t=c[v+1][v],m=(a[v]-l)*(a[v]-l)+b[v]*b[v],q=(s*o-p*n)/m,c[v][g]=q,Math.abs(s)>Math.abs(p)?c[v+1][g]=(-n-r*q)/s:c[v+1][g]=(-o-t*q)/p),q=Math.abs(c[v][g]);if(j*q*q>1)for(var w=v;w<=g;w++)c[w][g]=c[w][g]/q}}}else if(m<0){var y=g-1;if(Math.abs(c[g][g-1])>Math.abs(c[g-1][g]))c[g-1][g-1]=m/c[g][g-1],c[g-1][g]=-(c[g][g]-l)/c[g][g-1];else{var C=f(0,-c[g-1][g],c[g-1][g-1]-l,m);c[g-1][g-1]=C[0],c[g-1][g]=C[1]}c[g][g-1]=0,c[g][g]=1;for(var v=g-2;v>=0;v--){var D=0,E=0,F,G;for(var w=y;w<=g;w++)D+=c[v][w]*c[w][g-1],E+=c[v][w]*c[w][g];r=c[v][v]-l;if(b[v]<0)p=r,n=D,o=E;else{y=v;if(b[v]==0){var C=f(-D,-E,r,m);c[v][g-1]=C[0],c[v][g]=C[1]}else{s=c[v][v+1],t=c[v+1][v],F=(a[v]-l)*(a[v]-l)+b[v]*b[v]-m*m,G=(a[v]-l)*2*m,F==0&G==0&&(F=j*u*(Math.abs(r)+Math.abs(m)+Math.abs(s)+Math.abs(t)+Math.abs(p)));var C=f(s*n-p*D+m*E,s*o-p*E-m*D,F,G);c[v][g-1]=C[0],c[v][g]=C[1];if(Math.abs(s)>Math.abs(p)+Math.abs(m))c[v+1][g-1]=(-D-r*c[v][g-1]+m*c[v][g])/s,c[v+1][g]=(-E-r*c[v][g]-m*c[v][g-1])/s;else{var C=f(-n-t*c[v][g-1],-o-t*c[v][g],p,m);c[v+1][g-1]=C[0],c[v+1][g]=C[1]}}q=Math.max(Math.abs(c[v][g-1]),Math.abs(c[v][g]));if(j*q*q>1)for(var w=v;w<=g;w++)c[w][g-1]=c[w][g-1]/q,c[w][g]=c[w][g]/q}}}}for(var v=0;vi)for(var w=v;w=h;w--)for(var v=h;v<=i;v++){p=0;for(var A=h;A<=Math.min(w,i);A++)p+=d[v][A]*c[A][w];d[v][w]=p}}function f(a,b,c,d){if(Math.abs(c)>Math.abs(d)){var e=d/c,f=c+e*d;return[(a+e*b)/f,(b-e*a)/f]}var e=c/d,f=d+e*c;return[(e*a+b)/f,(e*b-a)/f]}science.lin={},science.lin.decompose=function(){function a(a){var f=a.length,g=[],h=[],i=[];for(var j=0;j0?j+1:j-1]=i[j]}return{D:n,V:g}}return a},science.lin.cross=function(a,b){return[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]]},science.lin.dot=function(a,b){var c=0,d=-1,e=Math.min(a.length,b.length);while(++dMath.abs(a[h][e])&&(h=f);var i=a[e];a[e]=a[h],a[h]=i;if(Math.abs(a[e][e])<=b)return!1;f=e;while(++f=0){var j=a[e][e];f=-1;while(++f=e)a[f][g]-=a[e][g]*a[f][e]/j}a[e][e]/=j,g=c-1;while(++gh[k][q]&&(h[q][j]=h[j][q]=h[k][q]);break;case"complete":h[j][q]0&&h(d,j,l,r);var t=r[0],u=r[1],v=d[l]-d[t]>d[u]-d[l]?t:u,w=0,x=0,y=0,z=0,A=0,B=Math.abs(1/(d[v]-s));for(var C=t;C<=u;++C){var D=d[C],E=i[C],F=C=1?0:(G=1-Q*Q)*G}return n}var a=.3,b=2,c=1e-12;return d.bandwidth=function(b){return arguments.length?(a=b,d):b},d.robustnessIterations=function(a){return arguments.length?(b=a,d):a},d.accuracy=function(a){return arguments.length?(c=a,d):a},d},science.stats.mean=function(a){var b=a.length;if(b===0)return NaN;var c=0,d=-1;while(++dd&&(d=h,c=[g]);if(c.length===1)return c[0]},science.stats.quantiles=function(a,b){a=a.slice().sort(science.ascending);var c=a.length-1;return b.map(function(b){if(b===0)return a[0];if(b===1)return a[c];var d=1+b*c,e=Math.floor(d),f=d-e,g=a[e-1];return f===0?g:g+f*(a[e]-g)})},science.stats.variance=function(a){var b=a.length;if(b<1)return NaN;if(b===1)return 0;var c=science.stats.mean(a),d=-1,e=0;while(++d=1||f===0);return b+c*d*Math.sqrt(-2*Math.log(f)/f)}var a=Math.random,b=0,c=1,d=1;return e.pdf=function(a){return a=(a-b)/c,science_stats_distribution_gaussianConstant*Math.exp(-0.5*a*a)/c},e.cdf=function(a){return a=(a-b)/c,.5*(1+science.stats.erf(a/Math.SQRT2))},e.mean=function(a){return arguments.length?(b=+a,e):b},e.variance=function(a){return arguments.length?(c=Math.sqrt(d=+a),e):d},e.random=function(b){return arguments.length?(a=b,e):a},e},science_stats_distribution_gaussianConstant=1/Math.sqrt(2*Math.PI)}(this)})(this); +/*jslint indent: 4, plusplus: true, nomen: true */ +/** + * MongoDB - distinct2.js + * + * Version: 1.5 + * Date: December 12, 2012 + * Project: http://skratchdot.com/projects/mongodb-distinct2/ + * Source Code: https://github.com/skratchdot/mongodb-distinct2/ + * Issues: https://github.com/skratchdot/mongodb-distinct2/issues/ + * Dependencies: MongoDB v1.8+ + * JSON2.js (https://github.com/douglascrockford/JSON-js) + * + * Copyright (c) 2012 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + 'use strict'; + + // config variables + var currentDate, + currentTick = (new Date()).getTime(), + previousTick = (new Date()).getTime(), + statusIntervalInMs = 10000, + // functions + isArray, + getFromKeyString, + getHashKey, + printStatus, + setStatusInterval; + + /** + * Same behavior as Array.isArray() + * @function + * @name isArray + * @private + * @param obj {*} The object to test + * @returns {boolean} Will return true of obj is an array, otherwise will return false + */ + isArray = function (obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; + }; + + /** + * @function + * @name getFromKeyString + * @private + * @param obj {object} The object to search + * @param keyString {string} A dot delimited string path + * @returns {object|undefined} If we find the path provide by keyString, we will return the value at that path + */ + getFromKeyString = function (obj, keyString) { + var arr, i; + if (typeof keyString === 'string') { + arr = keyString.split('.'); + for (i = 0; i < arr.length; i++) { + if (obj && typeof obj === 'object' && obj.hasOwnProperty(arr[i])) { + obj = obj[arr[i]]; + } else { + return; + } + } + return obj; + } + }; + + /** + * @function + * @name printStatus + * @private + * @param currentDocNum {number} - Number of the current document being processed + * @param numDocs {number} - Total number of documents being processed + * @param distinctCount {number} - Total number of distinct items found so far + */ + printStatus = function (currentDocNum, numDocs, distinctCount) { + // Output some debugging info if needed + if (statusIntervalInMs > 0) { + currentDate = new Date(); + currentTick = currentDate.getTime(); + if (currentTick - previousTick > statusIntervalInMs) { + print('Processed ' + currentDocNum + ' of ' + numDocs + ' document(s) and found ' + distinctCount + ' distinct items at ' + currentDate); + previousTick = currentTick; + } + } + }; + + /** + * @function + * @name setStatusInterval + * @private + * @param intervalInMs {number} Will print out a status message after this many + * milliseconds. If a non-positive number is passed in, + * then no status messages will be printed. + */ + setStatusInterval = function (intervalInMs) { + if (typeof intervalInMs === 'number') { + statusIntervalInMs = intervalInMs; + } + }; + + /** + * @function + * @name distinct2 + * @memberOf DBQuery + * @param keys {string|array} The array of dot delimited keys to get the distinct values for + * @param count {boolean} Whether or not to append + * @returns {array} If keys is a string, and count is false, then we behave like .distinct(). + * If keys is a positive sized array, we will return an array of arrays. + * If count is true, we will return an array of arrays where the last value is the count. + */ + DBQuery.prototype.distinct2 = function (keys, count) { + var i = 0, + currentDocNum = 0, + numDocs = this.size(), + distinctCount = 0, + returnArray = [], + tempArray = [], + arrayOfValues = false, + dataOrder = [], + data = {}; + + // if passed a string, convert it into an array + if (typeof keys === 'string') { + keys = [keys]; + } + + // if keys is not a positive sized array by now, do nothing + if (!isArray(keys) || keys.length === 0) { + return returnArray; + } + + // update tick for printing status line + previousTick = (new Date()).getTime(); + + // populate data object + this.forEach(function (obj) { + var i, values = [], key = '', isDefined = false; + for (i = 0; i < keys.length; i++) { + values[i] = getFromKeyString(obj, keys[i]); + if (typeof values[i] !== 'undefined') { + isDefined = true; + } + } + if (isDefined) { + key = getHashKey(values); + if (data.hasOwnProperty(key)) { + data[key].count = data[key].count + 1; + } else { + dataOrder.push(key); + data[key] = { + values : values, + count : 1 + }; + } + } + // print status info + printStatus(++currentDocNum, numDocs, dataOrder.length); + }); + + // should we return an array of values? + if (keys.length === 1 && !count) { + arrayOfValues = true; + } + + for (i = 0; i < dataOrder.length; i++) { + if (arrayOfValues) { // we return an array of values + returnArray.push(data[dataOrder[i]].values[0]); + } else { // we return an array of arrays + tempArray = data[dataOrder[i]].values; + if (count) { + tempArray.push(data[dataOrder[i]].count); + } + returnArray.push(tempArray); + } + } + + return returnArray; + }; + + /** + * @function + * @name distinct2 + * @memberOf DBCollection + * @param keys {string|array} The array of dot delimited keys to get the distinct values for + * @param count {boolean} Whether or not to append + * @returns {array} If keys is a string, and count is false, then we behave like .distinct(). + * If keys is a positive sized array, we will return an array of arrays. + * If count is true, we will return an array of arrays where the last value is the count. + */ + DBCollection.prototype.distinct2 = function (keys, count) { + var fields = {}, i, excludeId = true; + if (typeof keys === 'string') { + keys = [keys]; + } + if (!isArray(keys)) { + keys = []; + } + for (i = 0; i < keys.length; i++) { + fields[keys[i]] = 1; + if (keys[i] === '_id') { + excludeId = false; + } + } + if (!excludeId) { + fields._id = 0; + } + return this.find({}, fields).distinct2(keys, count); + }; + + // Attach setStatusInterval to both versions of distinct2 + DBQuery.prototype.distinct2.setStatusInterval = setStatusInterval; + DBCollection.prototype.distinct2.setStatusInterval = setStatusInterval; + + // set the correct getHashKey function + if (typeof JSON !== 'undefined' && typeof JSON.stringify === 'function') { + getHashKey = JSON.stringify; + } else if (typeof tojson === 'function') { + getHashKey = tojson; + } else { + getHashKey = function (obj) { + return obj; + }; + } +}()); +/*jslint devel: false, nomen: true, maxerr: 50, indent: 4 */ +/** + * MongoDB - distinct-types.js + * + * Version: 1.0 + * Date: April 29, 2012 + * Project: http://skratchdot.github.com/mongodb-distinct-types/ + * Source Code: https://github.com/skratchdot/mongodb-distinct-types/ + * Issues: https://github.com/skratchdot/mongodb-distinct-types/issues/ + * Dependencies: MongoDB v1.8+ + * + * Description: + * + * Similar to the db.myCollection.distinct() function, distinctTypes() will return + * "types" rather than "values". To accomplish this, it adds the following + * function to the DBCollection prototype: + * + * DBCollection.prototype.distinctTypes = function (keyString, query, limit, skip) {}; + * + * Usage: + * + * db.users.distinctTypes('name'); // we hope this would return ['bson'] not ['bson','string'] + * db.users.distinctTypes('name.first'); // should return ['string'] + * db.users.distinctTypes('address.phone'); // should return ['string'] + * db.users.distinctTypes('address.phone', {'name.first':'Bob'}); // only search documents that have { 'name.first' : 'Bob' } + * db.users.distinctTypes('address.phone', {}, 10); // only search the first 10 documents + * db.users.distinctTypes('address.phone', {}, 10, 5); // only search documents 10-15 + * + * Caveats: + * + * By design, distinctTypes() returns 'bson' rather than 'object'. + * It will return 'numberlong' rather than 'number', etc. + * + * Copyright (c) 2012 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + 'use strict'; + + var getType = function (obj) { + return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); + }, + getFromKeyString = function (obj, keyString) { + var returnValue = { + value : null, + found : false + }, + dotIndex = keyString.indexOf('.'), + currentKey = '', + newKeyString = ''; + if (dotIndex < 0) { + if (obj.hasOwnProperty(keyString)) { + returnValue = { + value : obj[keyString], + found : true + }; + } + } else { + currentKey = keyString.substr(0, dotIndex); + newKeyString = keyString.substr(dotIndex + 1); + if (obj.hasOwnProperty(currentKey)) { + returnValue = getFromKeyString(obj[currentKey], newKeyString); + } + } + return returnValue; + }; + + /** + * @function + * @name distinctTypes + * @memberOf DBCollection + * @param {string} keyString The key (using dot notation) to return distinct types for + * @param {object} query A mongo query in the same format that db.myCollection.find() accepts. + * @param {number} limit Limit the result set by this number. + * @param {number} skip The number of records to skip. + */ + DBCollection.prototype.distinctTypes = function (keyString, query, limit, skip) { + var fields = {}, + queryResult = null, + result = []; + if (typeof keyString !== 'string') { + keyString = ''; + } + fields[keyString] = 1; + queryResult = new DBQuery(this._mongo, this._db, this, this._fullName, + this._massageObject(query), fields, limit, skip).forEach(function (doc) { + var type = '', currentValue = getFromKeyString(doc, keyString); + if (currentValue.found) { + type = getType(currentValue.value); + if (result.indexOf(type) === -1) { + result.push(type); + } + } + }); + return result; + }; +}()); +/*jslint devel: false, unparam: true, nomen: true, maxerr: 50, indent: 4, plusplus: true */ +/** + * MongoDB - flatten.js + * + * Version: 1.3 + * Date: October 22, 2012 + * Project: http://skratchdot.com/projects/mongodb-flatten/ + * Source Code: https://github.com/skratchdot/mongodb-flatten/ + * Issues: https://github.com/skratchdot/mongodb-flatten/issues/ + * Dependencies: MongoDB v1.8+ + * + * Copyright (c) 2012 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + 'use strict'; + + var currentDb, emitKeys, insertKey, flatten, + statusDelayInMs = 10000, + currentId = null, currentDate = null, currentTick = null, previousTick = null; + + /** + * @function + * @name insertKey + * @memberOf anonymous + * @param {DBCollection} collection - the collection we are storing our flattened data in + * @param {ObjectId/object} id - the id of the document being flattened + * @param {string} key - the flattened key + * @param {any} value - the value of the flattened key + */ + insertKey = function (collection, id, key, value) { + // Increment our currentId + currentId = currentId + 1; + + // Insert document into our collection + collection.insert({ + '_id' : currentId, + 'i' : id, + 'k' : key, + 'v' : value + }); + }; + + /** + * @function + * @name emitKeys + * @memberOf anonymous + * @param {DBCollection} collection - the collection we are storing our flattened data in + * @param {ObjectId/object} id - the id of the document being flattened + * @param {object} node - the current node being flattened. initially this is the entire document + * @param {string} keyString - the current key/path. will be built recursively. initially an empty string. + */ + emitKeys = function (collection, id, node, keyString) { + var key, newKey, type = typeof (node); + if (type === 'object' || type === 'array') { + for (key in node) { + if (node.hasOwnProperty(key)) { + newKey = (keyString === '' ? key : keyString + '.' + key); + if (newKey === '_id') { + insertKey(collection, id, '_id', node[key]); + } else { + emitKeys(collection, id, node[key], newKey); + } + } + } + } else { + insertKey(collection, id, keyString, node); + } + }; + + /** + * @function + * @name flatten + * @memberOf anonymous + * @param {DBQuery} query - the current DBQuery object/cursor + * @param {string} collectionName - the name of the collection in which the results will be stored + */ + flatten = function (query, collectionName) { + var collection, i, numDocs = query.size(), currentDoc, currentDocNum; + + // If an invalid name is passed, create a temporary collection + if (typeof collectionName !== 'string' || collectionName.length === 0) { + collectionName = 'temp.flatten_' + new Date().getTime(); + } + + // Print some debug info + print('Flattening ' + numDocs + ' document(s) into the "' + collectionName + '" collection.'); + + // Get our collection + collection = query._db.getCollection(collectionName); + + // Empty our collection + collection.drop(); + + // Index our collection to speed up lookups + collection.ensureIndex({i : 1}); + collection.ensureIndex({k : 1}); + collection.ensureIndex({v : 1}); + + // Initialize some global counters/variables + previousTick = new Date().getTime(); + currentId = 0; + currentDocNum = 0; + + // Loop through all our objects, inserting records into our collection + while (query.hasNext()) { + // The current document we are processing + currentDoc = query.next(); + currentDocNum++; + + // Output some debugging info if needed + currentDate = new Date(); + currentTick = currentDate.getTime(); + if (currentTick - previousTick > statusDelayInMs) { + print('Flattened ' + currentDocNum + ' of ' + numDocs + ' document(s) and ' + currentId + ' key(s) at ' + currentDate); + previousTick = currentTick; + } + + // There's a chance documents don't have + // _id values (capped collections, internal collections) + if (!currentDoc.hasOwnProperty('_id')) { + currentDoc._id = 'unknown'; + } + + // Insert key/value pairs into our new collection + emitKeys(collection, currentDoc._id, currentDoc, ''); + } + + return collection; + }; + + /** + * @function + * @name flatten + * @memberOf DBQuery + * @param {string} collectionName - the name of the collection in which the results will be stored + */ + DBQuery.prototype.flatten = function (collectionName) { + return flatten(this, collectionName); + }; + + /** + * @function + * @name flatten + * @memberOf DBCollection + * @param {string} collectionName - the name of the collection in which the results will be stored + */ + DBCollection.prototype.flatten = function (collectionName) { + return this.find().flatten(collectionName); + }; + +}()); +/*jslint devel: false, nomen: true, unparam: true, plusplus: true, maxerr: 50, indent: 4 */ +/** + * MongoDB - schema.js + * + * Version: 1.1 + * Date: May 28, 2012 + * Project: http://skratchdot.github.com/mongodb-schema/ + * Source Code: https://github.com/skratchdot/mongodb-schema/ + * Issues: https://github.com/skratchdot/mongodb-schema/issues/ + * Dependencies: MongoDB v1.8+ + * + * Description: + * + * This is a schema analysis tool for MongoDB. It accomplishes this by + * extending the mongo shell, and providing a new function called schema() + * with the following signature: + * + * DBCollection.prototype.schema = function (optionsOrOutString) + * + * Usage: + * + * The schema() function accepts all the same parameters that the mapReduce() function + * does. It adds/modifies the following 4 parameters that can be used as well: + * + * wildcards - array (default: []) + * By using the $, you can combine report results. + * For instance: '$' will group all top level keys and + * 'foo.$.bar' will combine 'foo.baz.bar' and 'foo.bar.bar' + * + * arraysAreWildcards - boolean (default: true) + * When true, 'foo.0.bar' and 'foo.1.bar' will be + * combined into 'foo.$.bar' + * When false, all array keys will be reported + * + * fields - object (default: {}) + * Similar to the usage in find(). You can pick the + * fields to include or exclude. Currently, you cannot + * pass in nested structures, you need to pass in dot notation keys. + * + * limit - number (default: 50) + * Behaves the same as the limit in mapReduce(), but defaults to 50. + * You can pass in 0 or -1 to process all documents. + * + * Return schema results inline + * db.users.schema(); + * + * Create and store schema results in the 'users_schema' collection + * db.users.schema('users_schema'); // Option 1 + * db.users.schema({out:'users_schema'}); // Option 2 + * db.users.schema({out:{replace:'users_schema'}}); // Option 3 + * + * Only report on the key: 'name.first' + * db.users.schema({fields:{'name.first':1}}); + * + * Report on everything except 'name.first' + * db.users.schema({fields:{'name.first':-1}}); + * + * Combine the 'name.first' and 'name.last' keys into 'name.$' + * db.users.schema({wildcards:['name.$']}); + * + * Don't treat arrays as a wildcard + * db.users.schema({arraysAreWildcards:false}); + * + * Process 50 documents + * db.users.schema(); + * + * Process all documents + * db.users.schema({limit:-1}); + * + * Caveats: + * + * By design, schema() returns 'bson' rather than 'object'. + * It will return 'numberlong' rather than 'number', etc. + * + * Inspired by: + * + * Variety: https://github.com/JamesCropcho/variety + * + * Copyright (c) 2012 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + 'use strict'; + + /** + * You can pass in the same options object that mapReduce() accepts. Schema has the following + * defaults for options: + * + * options.out = { inline : 1 }; + * options.limit = 50; + * + * You can pass in an options.limit value of 0 or -1 to parse _all_ documents. + * + * @function + * @name flatten + * @memberOf DBCollection + * @param {object} optionsOrOutString This function accepts the same options as mapReduce + */ + DBCollection.prototype.schema = function (optionsOrOutString) { + var statCount = 0, wildcards = [], arraysAreWildcards = true, + field, fields = {}, usePositiveFields = false, useNegativeFields = false, + getType, getNewKeyString, getKeyInfo, map, reduce, finalize, options = { limit : 50 }; + + /** + * @function + * @name getType + * @private + * @param {object} obj The object to inspect + */ + getType = function (obj) { + return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); + }; + + /** + * @function + * @name getNewKeyString + * @private + * @param {string} key The current key + * @param {string} keyString The object to inspect + */ + getNewKeyString = function (key, keyString) { + var i, j, keyArray, newKeyString, success, wc; + newKeyString = (keyString === '' ? key : keyString + '.' + key); + if (wildcards.length > 0) { + keyArray = newKeyString.split('.'); + for (i = 0; i < wildcards.length; i++) { + wc = wildcards[i].split('.'); + if (keyArray.length === wc.length) { + success = true; + for (j = 0; success && j <= wc.length; j++) { + if (wc[j] !== '$' && wc[j] !== keyArray[j]) { + success = false; + } + } + if (success) { + return wildcards[i]; + } + } + } + } + return newKeyString; + }; + + /** + * @function + * @name getKeyInfo + * @private + * @param {object} node The node from which we generate our keys + * @param {string} keyString A string representing the current key 'path' + * @param {object} keyInfo The struct that contains all our 'paths' as the key, and a count for it's value + */ + getKeyInfo = function (node, keyString, keyInfo) { + var key, newKeyString, type, useArrayWildcard = false; + + // Store the mongo type. 'bson' instead of 'object', etc + type = getType(node); + + // We need to handle objects and arrays by calling getKeyInfo() recursively + if (['array', 'bson', 'object'].indexOf(type) >= 0) { + + // Set the flag to be used in our for loop below + if (type === 'array' && arraysAreWildcards === true) { + useArrayWildcard = true; + } + + // Loop through each key + for (key in node) { + if (node.hasOwnProperty(key)) { + if (useArrayWildcard) { + newKeyString = keyString + '.$'; + } else { + newKeyString = getNewKeyString(key, keyString); + } + keyInfo = getKeyInfo(node[key], newKeyString, keyInfo); + } + } + + } + + // We don't need to emit this key + // Using a long statement to pass jslint + // there are 3 parts to this: + // 1: empty key + // 2: usePostiveFields is true, and the current key is not valid + // 3: useNegativeFields is true, and the current key exists in fields (and is -1) + if (keyString === '' || (usePositiveFields && (!fields.hasOwnProperty(keyString) || fields[keyString] !== 1)) || (useNegativeFields && fields.hasOwnProperty(keyString) && fields[keyString] === -1)) { + return keyInfo; + } + + // We need to emit this key + if (keyInfo.hasOwnProperty(keyString) && keyInfo[keyString].hasOwnProperty(type)) { + keyInfo[keyString][type].perDoc += 1; + } else { + keyInfo[keyString] = {}; + keyInfo[keyString][type] = { + docs : 1, + coverage : 0, + perDoc : 1 + }; + } + + return keyInfo; + }; + + /** + * @function + * @name map + * @private + */ + map = function () { + var key, keyInfo, count, type; + + // Get our keyInfo struct + keyInfo = getKeyInfo(this, '', {}, [], true); + + // Loop through keys, emitting info + for (key in keyInfo) { + if (keyInfo.hasOwnProperty(key)) { + count = 0; + for (type in keyInfo[key]) { + if (keyInfo[key].hasOwnProperty(type)) { + count += keyInfo[key][type].perDoc; + } + } + keyInfo[key].all = { + docs : 1, + perDoc : count + }; + emit(key, keyInfo[key]); + } + } + }; + + /** + * @function + * @name reduce + * @private + * @param {string} key The key that was emitted from our map function + * @param {array} values An array of values that was emitted from our map function + */ + reduce = function (key, values) { + var result = {}; + values.forEach(function (value) { + var type; + for (type in value) { + if (value.hasOwnProperty(type)) { + if (!result.hasOwnProperty(type)) { + result[type] = { docs : 0, coverage : 0, perDoc : 0 }; + } + result[type].docs += value[type].docs; + result[type].perDoc += value[type].perDoc; + } + } + }); + return result; + }; + + /** + * @function + * @name finalize + * @private + * @param {string} key The key that was emitted/returned from our map/reduce functions + * @param {object} value The object that was returned from our reduce function + */ + finalize = function (key, value) { + var type, result = { + wildcard : (key.search(/^\$|\.\$/gi) >= 0), + types : [], + results : [{ + type : 'all', + docs : value.all.docs, + coverage : (value.all.docs / statCount) * 100, + perDoc : value.all.perDoc / value.all.docs + }] + }; + for (type in value) { + if (value.hasOwnProperty(type) && type !== 'all') { + result.types.push(type); + result.results.push({ + type : type, + docs : value[type].docs, + coverage : (value[type].docs / statCount) * 100, + perDoc : value[type].perDoc / value[type].docs + }); + } + } + return result; + }; + + // Start to setup our options struct + if (typeof optionsOrOutString === 'object') { + options = optionsOrOutString; + } else if (typeof optionsOrOutString === 'string') { + options.out = optionsOrOutString; + } + + // The default value for out is 'inline' + if (!options.hasOwnProperty('out')) { + options.out = { inline : 1 }; + } + + // Was a valid wildcards option passed in? + if (options.hasOwnProperty('wildcards') && getType(options.wildcards) === 'array') { + wildcards = options.wildcards; + } + + // Was a valid arraysAreWildcards option passed in? + if (options.hasOwnProperty('arraysAreWildcards') && typeof options.arraysAreWildcards === 'boolean') { + arraysAreWildcards = options.arraysAreWildcards; + } + + // Was a valid fields option passed in? + if (options.hasOwnProperty('fields') && getType(options.fields) === 'object' && Object.keySet(options.fields).length > 0) { + fields = options.fields; + for (field in fields) { + if (fields.hasOwnProperty(field)) { + if (fields[field] === 1 || fields[field] === true) { + fields[field] = 1; + usePositiveFields = true; + } else { + fields[field] = -1; + } + } + } + if (!usePositiveFields) { + useNegativeFields = true; + } + } + + // Store the total number of documents to be used in the finalize function + statCount = this.stats().count; + if (options.hasOwnProperty('limit') && typeof options.limit === 'number' && options.limit > 0 && options.limit < statCount) { + statCount = options.limit; + } else if (options.hasOwnProperty('limit')) { + delete options.limit; + } + + // Make sure to override certain options + options.map = map; + options.reduce = reduce; + options.finalize = finalize; + options.mapreduce = this._shortName; + options.scope = { + getType : getType, + getNewKeyString : getNewKeyString, + getKeyInfo : getKeyInfo, + statCount : statCount, + wildcards : wildcards, + arraysAreWildcards : arraysAreWildcards, + fields : fields, + usePositiveFields : usePositiveFields, + useNegativeFields : useNegativeFields + }; + + // Execute and return + print('Processing ' + statCount + ' document(s)...'); + return this.mapReduce(map, reduce, options); + }; + +}()); +/*jslint devel: false, nomen: true, maxerr: 50, indent: 4 */ +/** + * MongoDB - wild.js + * + * Version: 1.0 + * Date: April 29, 2012 + * Project: http://skratchdot.github.com/mongodb-wild/ + * Source Code: https://github.com/skratchdot/mongodb-wild/ + * Issues: https://github.com/skratchdot/mongodb-wild/issues/ + * Dependencies: MongoDB v1.8+ + * + * Description: + * + * Adds a wildcard search to the shell. You can run the new + * wild() function on a collection, or on a query result. + * The search is performed by converting each document to json, + * and then running a regex that json. + * + * Usage: + * + * // Search entire users collection for Bob + * db.users.wild('Bob'); + * db.users.wild(/Bob/gi); + * db.users.find().wild('Bob'); + * + * // Search for exact values of 'Bob' + * db.users.wild(': "Bob"'); + * + * // Search for exact keys called 'Bob' + * db.users.wild('"Bob" :'); + * + * // Search for documents containing 'Bob', filtering by last name of 'Smith' + * db.users.wild('Bob', {'name.last' : 'Smith'}); + * db.users.find({'name.last' : 'Smith'}).wild('Bob'); + * + * Copyright (c) 2012 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + 'use strict'; + + /** + * @function + * @name wild + * @memberOf DBQuery + * @param {String|RegExp} regex The regular expression to filter the query by + */ + DBQuery.prototype.wild = function (regex) { + var doc, result = []; + + // Ensure we have a valid regex + if (typeof regex === 'string') { + regex = new RegExp(regex, 'gi'); + } + if (regex instanceof RegExp === false) { + regex = new RegExp(); + } + + // Build our result set. + while (this.hasNext()) { + doc = this.next(); + if (tojson(doc).search(regex) >= 0) { + result.push(doc); + } + } + + return result; + }; + + /** + * @function + * @name wild + * @memberOf DBCollection + * @param {String|RegExp} regex The regular expression to filter the query by + * @param {object} query This value will be passed through to the .find() function + * @param {object} fields This value will be passed through to the .find() function + * @param {number} limit This value will be passed through to the .find() function + * @param {number} skip This value will be passed through to the .find() function + * @param {number} batchSize This value will be passed through to the .find() function + * @param {object} options This value will be passed through to the .find() function + */ + DBCollection.prototype.wild = function (regex, query, fields, limit, skip, batchSize, options) { + return this.find(query, fields, limit, skip, batchSize, options).wild(regex); + }; + +}()); +/** + * MongoDB - mesh.idrange.js + * Version: 1.0 + * Date: September 25, 2013 + * Description: + * + * Search collections for documents with ids created between 2 datetimes. + * + * Example Usage: + * + * // method 1: search the users collection for users created on 3/20/2013 + * var query = mesh.idrange('3/20/2013', '3/21/2013'); + * db.users.find(query); + * + * // method 2: search the users collection for users created on 3/20/2013 + * db.users.idrange('3/20/2013', '3/21/2013'); + * + * // search the users collection for users with first name "Bob" created in March + * db.users.idrange('3/1/2013', '4/1/2013', {"name.first": "Bob"}); + * + * Copyright (c) 2013 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + 'use strict'; + var idrange, toMoment; + + /** + * @function + * @name idrange + * @private + * + * Convert input to a valid moment object + */ + toMoment = function (input) { + input = moment(input); + if (!input || !input.isValid || !input.isValid()) { + input = moment(); + } + return input; + }; + + /** + * @function + * @name idrange + * @private + */ + idrange = function (one, two, properties) { + var result = {_id:{}}, moments, prop; + + // create our moments + moments = [toMoment(one), toMoment(two)]; + + // put them in the right order + moments.sort(function (a, b) { + return a.diff(b); + }); + + // setup our result + if (typeof properties === 'object') { + for (prop in properties) { + if (properties.hasOwnProperty(prop)) { + result[prop] = properties[prop]; + } + } + } + + // add moments to our result, and return + result._id.$gte = mesh.tid(moments[0]); + result._id.$lt = mesh.tid(moments[1]); + return result; + }; + + /** + * @function + * @name idrange + * @memberOf DBCollection + */ + DBCollection.prototype.idrange = function (one, two, properties) { + return this.find(idrange(one, two, properties)); + }; + + // store idrange on the mesh object + mesh.idrange = idrange; +}()); + +/*global mesh */ + +// http://docs.mongodb.org/manual/reference/operator/ +mesh.ops = {}; + +mesh.ops._query = { + "addToSet" : "$addToSet", + "all" : "$all", + "and" : "$and", + "bit" : "$bit", + "box" : "$box", + "center" : "$center", + "centerSphere" : "$centerSphere", + "comment" : "$comment", + "each" : "$each", + "elemMatch" : "$elemMatch", + "exists" : "$exists", + "explain" : "$explain", + "gt" : "$gt", + "gte" : "$gte", + "hint" : "$hint", + "in" : "$in", + "inc" : "$inc", + "isolated" : "$isolated", + "lt" : "$lt", + "lte" : "$lte", + "max" : "$max", + "maxDistance" : "$maxDistance", + "maxScan" : "$maxScan", + "min" : "$min", + "mod" : "$mod", + "natural" : "$natural", + "ne" : "$ne", + "near" : "$near", + "nearSphere" : "$nearSphere", + "nin" : "$nin", + "nor" : "$nor", + "not" : "$not", + "or" : "$or", + "orderby" : "$orderby", + "polygon" : "$polygon", + "pop" : "$pop", + "$" : "$", + "pull" : "$pull", + "pullAll" : "$pullAll", + "push" : "$push", + "pushAll" : "$pushAll", + "query" : "$query", + "regex" : "$regex", + "rename" : "$rename", + "returnKey" : "$returnKey", + "set" : "$set", + "setOnInsert" : "$setOnInsert", + "showDiskLoc" : "$showDiskLoc", + "size" : "$size", + "snapshot" : "$snapshot", + "type" : "$type", + "uniqueDocs" : "$uniqueDocs", + "unset" : "$unset", + "where" : "$where", + "within" : "$within" +}; + +mesh.ops._projection = { + "elemMatch" : "$elemMatch", + "$" : "$", + "slice" : "$slice" +}; + +mesh.ops._aggregation = { + "add" : "$add", + "addToSet" : "$addToSet", + "and" : "$and", + "avg" : "$avg", + "cmp" : "$cmp", + "cond" : "$cond", + "dayOfMonth" : "$dayOfMonth", + "dayOfWeek" : "$dayOfWeek", + "dayOfYear" : "$dayOfYear", + "divide" : "$divide", + "eq" : "$eq", + "first" : "$first", + "group" : "$group", + "gt" : "$gt", + "gte" : "$gte", + "hour" : "$hour", + "ifNull" : "$ifNull", + "last" : "$last", + "limit" : "$limit", + "lt" : "$lt", + "lte" : "$lte", + "match" : "$match", + "max" : "$max", + "min" : "$min", + "minute" : "$minute", + "mod" : "$mod", + "month" : "$month", + "multiply" : "$multiply", + "ne" : "$ne", + "not" : "$not", + "or" : "$or", + "project" : "$project", + "push" : "$push", + "second" : "$second", + "skip" : "$skip", + "sort" : "$sort", + "strcasecmp" : "$strcasecmp", + "substr" : "$substr", + "subtract" : "$subtract", + "sum" : "$sum", + "toLower" : "$toLower", + "toUpper" : "$toUpper", + "unwind" : "$unwind", + "week" : "$week", + "year" : "$year" +}; + +// build out ops +["_query", "_projection", "_aggregation"].forEach(function (section) { + 'use strict'; + var key; + for (key in mesh.ops[section]) { + if (mesh.ops[section].hasOwnProperty(key)) { + mesh.ops[key] = mesh.ops[section][key]; + } + } +}); + +/** + * MongoDB - mesh.sizeinfo.js + * Version: 1.0 + * Date: September 25, 2013 + * Description: + * + * Get the size stats for the given query/collection. Reports count/sum/avg/max/min of all bson sizes. + * + * Example Usage: + * + * // method 1: get the size stats for all documents in the users collection with first name "Bob" + * db.users.sizeinfo({"first.name": "Bob"}); + * + * // method 2: get the size stats for all documents in the users collection with first name "Bob" + * db.users.find({"first.name": "Bob"}).sizeinfo(); + * + * Copyright (c) 2013 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + var sizeinfo; + + /** + * @function + * @name sizeinfo + * @private + */ + sizeinfo = function (cursor) { + var doc, size, count = 0, sum = 0, max, min; + while (cursor.hasNext()) { + doc = cursor.next(); + size = Object.bsonsize(doc); + count += 1; + sum += size; + if (typeof max !== 'number' || max < size) { + max = size; + } + if (typeof min !== 'number' || min > size) { + min = size; + } + } + return { + count: count, + sum: sum, + max: max, + min: min, + avg: count > 0 ? sum / count : 0 + }; + }; + + /** + * @function + * @name sizeinfo + * @memberOf DBCollection + */ + DBQuery.prototype.sizeinfo = function () { + return sizeinfo(this); + }; + + /** + * @function + * @name sizeinfo + * @memberOf DBCollection + */ + DBCollection.prototype.sizeinfo = function (query, fields, limit, skip, batchSize, options) { + return this.find(query, fields, limit, skip, batchSize, options).sizeinfo(); + }; + +}()); + +/*global _, DBCollection, print */ +/** + * Insert an array of objects into a collection. + * + * This will loop through the array, calling DBCollection.insert() on each object. + * + * Example usage: + * + * // insert 2 items into myCollection + * var myArray = [{_id:1,test:1}, {_id:2,test:"foo"}]; + * db.myCollection.insertArray(myArray); + * + * // transfer a few items from collection1 into collection2 + * db.collection2.insertArray(db.collection1.find().limit(10).toArray()); + * + * @function + * @name insertArray + * @memberOf DBCollection + * @param {array} arr - The array of objects to insert. + * @param {object} options - pass through to DBCollection.prototype.insert() + * @param {boolean} _allow_dot - pass through to DBCollection.prototype.insert() + * @throws {Exception} - when arr is not an Array. + */ +DBCollection.prototype.insertArray = function (arr, options, _allow_dot) { + 'use strict'; + var i, obj; + if (_.isArray(arr)) { + for (i = 0; i < arr.length; i++) { + obj = arr[i]; + if (_.isObject(obj) && !_.isFunction(obj)) { + this.insert(obj, options, _allow_dot); + } else { + print('Cannot insert a non-object, so skipping: ' + obj); + } + } + } else { + throw 'first argument is not an array!'; + } +}; + +/*global _ : true, JSON : true */ + +_.mixin({ + aggregate : function (list, numericKey, keys) { + 'use strict'; + + var i = 0, + item = {}, + returnArray = [], + dataOrder = [], + data = {}, + AggregateError; + + // declare our AggregateError class + AggregateError = function (msg) { + this.name = 'AggregateError'; + this.message = msg || 'An error occurred while trying to perform aggregation'; + }; + AggregateError.prototype = new Error(); + AggregateError.prototype.constructor = AggregateError; + + // _.deepPluck is required + if (!_ || !_.deepPluck) { + throw new AggregateError("_.deepPluck is required for _.aggregate() to work."); + } + + // JSON.stringify is required + if (!JSON || !JSON.stringify) { + throw new AggregateError("JSON.stringify() is required for _.aggregate() to work."); + } + + // keys can be a single key (string), or an array of keys. + // we always want to deal with arrays though + if (typeof keys === 'string') { + keys = [keys]; + } + + // make sure keys is an array + if (!_.isArray(keys)) { + keys = []; + } + + _.each(list, function (obj) { + // declare some variables + var groupedValues = [], aggregationKey = '', numericValue; + + // get all our groupedValues + for (i = 0; i < keys.length; i++) { + groupedValues[i] = _.deepPluck([obj], keys[i])[0]; + } + + // create a key for our aggregations + aggregationKey = JSON.stringify(groupedValues); + + // get our current numeric value + numericValue = parseInt(_.deepPluck([obj], numericKey)[0], 10) || 0; + + if (data.hasOwnProperty(aggregationKey)) { + // count + data[aggregationKey].count = data[aggregationKey].count + 1; + // sum + data[aggregationKey].sum = data[aggregationKey].sum + numericValue; + // max + if (numericValue > data[aggregationKey].max) { + data[aggregationKey].max = numericValue; + } + // min + if (numericValue < data[aggregationKey].min) { + data[aggregationKey].min = numericValue; + } + // avg is calculated when building our return array + } else { + dataOrder.push(aggregationKey); + data[aggregationKey] = { + count : 1, + sum : numericValue, + max : numericValue, + min : numericValue, + avg : numericValue, + group : groupedValues + }; + } + + }); + + for (i = 0; i < dataOrder.length; i++) { + item = data[dataOrder[i]]; + item.avg = item.sum / item.count; + returnArray.push(item); + } + + return returnArray; + } +}); +/*global _:true */ + +_.mixin({ + avg : function (obj, iterator, context) { + 'use strict'; + var sum = _.sum(obj, iterator, context), + size = _.size(obj); + return size ? sum / size : 0; + } +}); +/*global _:true */ + +_.mixin({ + deepExtend : function (obj) { + 'use strict'; + _.each(Array.prototype.slice.call(arguments, 1), function (source) { + var key; + if (_.isObject(obj) && _.isObject(source) && !_.isArray(obj) && !_.isArray(source)) { + for (key in source) { + if (source.hasOwnProperty(key)) { + if (obj.hasOwnProperty(key)) { + obj[key] = _.deepExtend(obj[key], source[key]); + } else { + obj[key] = source[key]; + } + } + } + } else { + obj = source; + } + }); + return obj; + } +}); + +/*global _:true */ + +_.mixin({ + deepPluck : (function () { + 'use strict'; + + // declare some variables + var defaultDelimiter = '.', deepPluck; + + // implement the deepPluck function + deepPluck = function (obj, key, delimiter) { + if (typeof delimiter !== 'string') { + delimiter = defaultDelimiter; + } + return _.map(obj, function (value) { + var arr, i; + if (typeof key === 'string') { + arr = key.split(delimiter); + for (i = 0; i < arr.length; i++) { + if (value && typeof value === 'object' && value.hasOwnProperty(arr[i])) { + value = value[arr[i]]; + } else { + return; + } + } + return value; + } + }); + }; + + // allow the default delimiter to be overridden + // you may want to do this if you actually use dots in your keys + deepPluck.setDelimiter = function (delimiter) { + defaultDelimiter = delimiter; + }; + + return deepPluck; + }()) +}); +/*global _:true */ + +_.mixin({ + keyToObject : (function () { + 'use strict'; + + // declare some variables + var defaultDelimiter = '.', keyToObject; + + keyToObject = function (key, value, delimiter) { + var obj = {}, arr = []; + if (typeof delimiter !== 'string') { + delimiter = defaultDelimiter; + } + if (typeof key === 'string') { + arr = key.split(delimiter); + key = arr[0]; + if (arr.length > 1) { + arr.shift(); + obj[key] = keyToObject(arr.join(delimiter), value, delimiter); + } else { + obj[key] = value; + } + } + return obj; + }; + + // allow the default delimiter to be overridden + keyToObject.setDelimiter = function (delimiter) { + defaultDelimiter = delimiter; + }; + + return keyToObject; + }()) +}); +/*global _:true */ + +_.mixin({ + stdev : function (obj, iterator, context) { + 'use strict'; + return Math.sqrt(_.variance(obj, iterator, context)); + } +}); +/*global _:true */ + +_.mixin({ + sum : function (obj, iterator, context) { + 'use strict'; + var result = 0; + if (!iterator && _.isEmpty(obj)) { + return 0; + } + _.each(obj, function (value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + result += computed; + }); + return result; + } +}); +/*global _:true */ + +_.mixin({ + variance : function (obj, iterator, context) { + 'use strict'; + var result = 0, size = _.size(obj), mean; + if (size === 0) { + return 0; + } + // set mean + mean = _.avg(obj, iterator, context); + _.each(obj, function (value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value, + diff = computed - mean; + result += diff * diff; + }); + return result / size; + } +}); +// Mix in non-conflicting functions to the Underscore namespace +_.mixin(_.str.exports()); + +// Output the current version number when starting the shell. +mesh.version(); diff --git a/tools/sql2mongo/sql2mongo.js b/tools/sql2mongo/sql2mongo.js new file mode 100644 index 0000000..c9a437e --- /dev/null +++ b/tools/sql2mongo/sql2mongo.js @@ -0,0 +1,352 @@ +var _ = require('underscore') +sqlKeywords = ['select', 'top', 'from', 'join', 'where', 'groupby', 'orderby', 'having']; // keep "top x" in mind +logicalOperators = ['!=', '<=', '>=', '<', '>', '=', '!in', 'in', 'like']; + +var hasTop, hasWhere, hasOrderBy, processed = [], whereValsWithSpaces, hasOr, filterFields, operators, sqlishFilter, filter; +parseOperatorsInArray = function(equation){ + var completeArr = [], tmpArr = []; + sqlKeywords.forEach(function (e, k) { // for each operator + if (completeArr.length === 0) { // if empty, split equation and do first load to completeArr. + tmpArr = equation.split(e); + spliceOperatorIntoTmpArr(tmpArr, e); // adds operator between every item in array + tmpArr = tmpArr.filter(function (item) { return item.length > 0; }); + tmpArr.forEach(function (e, k) { + + if (e.indexOf('where') > -1){ + buildWhere(e); + } + completeArr.push(e.replace(/\s/g, '')); + }); + } else { + for (var n = 0; n < completeArr.length; n++) { + if (completeArr[n].indexOf(e) > -1 && completeArr[n].length > 1) { + var idx = n; + tmpArr = completeArr[n].split(e); + spliceOperatorIntoTmpArr(tmpArr, e); + tmpArr = tmpArr.filter(function (item) { return item.length > 0; }); + completeArr.splice(idx, 1); // remove old text element + for (var x = 0; x < tmpArr.length ; x++) { + var newIdx = (idx + x); + completeArr.splice(newIdx, 0, tmpArr[x]); + } + } + } + } + }); + return completeArr; +}; + +spliceOperatorIntoTmpArr = function(tmpArr, e){ + var tmpLen = tmpArr.length + (tmpArr.length - 1); + for (var i = 1; i < tmpLen; i++) { + tmpArr.splice(i, 0, e); + i++; + } +}; + +buildWhere = function(e){ + + var originalWhere = hasOrderBy ? e.substring(e.indexOf('where'), e.indexOf(' order by')) : e.substring(e.indexOf('where'), e.length); + var splitWhere = originalWhere.split(' '), splitLength = splitWhere.length; + var isRightSide = false, isOperator = false, isKeyword = false, filterValsToPush = []; + + splitWhere.forEach(function(el, idx){ + + isKeyword = ((sqlKeywords.indexOf(el) > -1) || el === 'and' || el === 'or'); + isOperator = (logicalOperators.indexOf(el) > -1); // true if operator + + if (isKeyword){ + isRightSide = false; // false if sql keyword + } + + if (isOperator){ + operators.push(el); + isRightSide = true; + } + + if (!isOperator && !isKeyword){ + if (isRightSide){ + filterValsToPush.push(el); + } else { + filterFields.push(el); + } + } + + if ((el === 'and' || el === 'or' || idx === (splitLength - 1)) && filterValsToPush.length > 0){ + var preservedVal = filterValsToPush.join(' '); + whereValsWithSpaces.push(preservedVal); + filterValsToPush = []; + } + }); + + for (var i = 0; i < filterFields.length; i++){ + sqlishFilter.push(({ field: filterFields[i], operator: operators[i], value: whereValsWithSpaces[i] })); + } +}; + +getNext = function(arr, howMany){ + howMany = howMany ? howMany : 1; + if (arr.length > 0){ + + var lastIn = arr.splice(0, howMany); + processed.push(lastIn); + return lastIn; + } +}; + +getLimit = function(arr){ + var topN = arr[0].replace(/[^0-9.]/g, ''); + // remove top n from fields portion of arr + arr[0] = arr[0].replace(/\d+/g, ''); + return parseInt(topN); +}; + +getProjection = function(arr){ + var projection = {}, selectFields = _.first(getNext(arr)); + if (selectFields !== '*'){ + selectFields.replace(/\s/g, '').split(',').forEach(function(e, k){ + var show = 1; + if (e.substr(0,1) === '!'){ + show = 0; + e = e.substr(1,1000); + } + projection[e] = show; + }); + } + return projection; +}; + +processFilter = function(filterObj, filter){ + var field = filterObj['field']; + var operator = filterObj['operator']; + var val = !isNaN(filterObj['value']) ? parseFloat(filterObj['value']) : filterObj['value']; + + switch (operator){ + case '=': + filter[field] = val; + break; + case '!=': + filter[field] = { $ne: val }; + break; + case '>': + filter[field] = { $gt: val }; + break; + case '<': + filter[field] = { $lt: val }; + break; + case '>=': + filter[field] = { $gte: val }; + break; + case '<=': + filter[field] = { $lte: val }; + break; + case 'in': + filter[field] = { $in: val.split(',') }; + break; + case '!in': + filter[field] = { $nin: val.split(',') }; + break; + case 'like': + filter[field] = { $regex: '^' + val + '.*' }; + break; + case '!like': + filter[field] = { $not: (new RegExp('/' + val + '/')) }; + break; + } + return filter; +}; + +getSort = function(arr){ + var sort = {}, sortFields = getNext(arr)[0], field, order, val; + sortFields.split(',').forEach(function(e, k){ + if (e.substring(e.length - 4, e.length) === 'desc'){ + field = e.substring(0, e.length - 4); + val = -1; + } else if (e.substring(e.length - 3, e.length) === 'asc'){ + field = e.substring(0, e.length - 3); + val = 1; + } else { + field = e; + val = 1; + } + + sort[field] = val; + }); + return sort; +}; + +validateCollection = function(collection){ + return _.contains(collections,collection) ? collection : 'Invalid Collection.'; +}; + +// ######## Start of custom auto-complete code ######## +function interceptAutoComplete(prefix, global, parts){ + if (prefix.length === 0){ // space only + return ["')"]; + } + + var first = parts[0].toLowerCase(); + var expandToText = snippetMap[first]; + var lastChar = first.substring(first.length - 1, first.length); + var lastTwoChars = first.substring(first.length - 2, first.length); + + if (first === 'sel'){ + sqlQuery = "db.sql('select * from "; + return [sqlQuery]; + } else if (expandToText){ + return [expandToText]; + } else if (!queryHasCollection && isNaN(lastChar)) { + return printCollections(first); + } else if (!queryHasCollection) { + return selectCollection(lastTwoChars, lastChar); + } else if (queryHasCollection && isNaN(lastChar)) { + return printFields(first); + } else { + return selectField(lastTwoChars, lastChar) + } +} + +function printMatches(isField){ + if (matches.length > 0){ + print('\n'); + matches.forEach(function(m, i){ + var str = i + ': ' + m + print(colorize(str, 'green', true, false)); + }); + } else { + resetGlobalVars(); + return ['']; + } +} + +function printCollections(first){ + // No collection has been selected yet, and user isn't passing number for selection... + if (_.contains(collections, first)){ + selectedCollection = first; + sqlQuery += selectedCollection; + + return [selectedCollection]; + } + + matches = _.filter(collections, function(c){ + return c.toLowerCase().substring(0, (first.length)) === first; + }); + + printMatches(); +} + +function selectCollection(lastTwoChars, lastChar){ + // no collection is selected yet, but user is passing number for selection... + var num = !isNaN(lastTwoChars) ? lastTwoChars : lastChar; + selectedCollection = matches[num]; + queryHasCollection = true; + print('\n'); + generateFieldTable(selectedCollection); + + if (sqlQuery === ''){ + sqlQuery = "db.sql('select * from " + selectedCollection; + return [sqlQuery]; + } + + sqlQuery += selectedCollection; + return [selectedCollection]; +} + +function printFields(first){ + // collection has been selected and user is trying to select field based on initial string + var collection = collectionFields[selectedCollection]; + var filteredFields = _.filter(collection, function(c){ + return c.field.toLowerCase().substring(0, (first.length)) === first; + }); + matches = _.map(_.sortBy(filteredFields, 'field'), function(d, i) { + return d.field; + }); + + printMatches(); +} + +function selectField(lastTwoChars, lastChar){ + // collection has been selected, as well as field string, now user is passing number to select one... + var num = !isNaN(lastTwoChars) ? lastTwoChars : lastChar; + var field = matches[num]; + + return [field]; +} + +function showCollections(){ + return db.getCollectionNames(); +} + +function resetGlobalVars (){ + queryHasCollection = false; + sqlQuery = ''; + matches = null; + selectedCollection = ''; +} + +function generateFieldTable(collection){ + var table = new AsciiTable(collection); + table.setHeading('#', 'Field', 'Types'); + + var fields = collectionFields[collection]; + _.map(_.sortBy(fields, 'field'), function(d, i) { + return table.addRow(i, d.field, d.types) + }); + return print(colorize(table, 'cyan', true, false)); +} +module.exports = { + parseSQL : function(sql){ + sql = sql.replace(/NOT LIKE/g,'!like').toLowerCase() + whereValsWithSpaces = [], filterFields = [], operators = [], sqlishFilter = [], filter = {}; + hasTop = (sql.indexOf(' top ') > -1), hasWhere = (sql.indexOf('where') > -1), hasOrderBy = (sql.indexOf('order by') > -1), hasOr = (sql.indexOf(' or ') > -1); + var limit, join, sort; + var arr = parseOperatorsInArray(sql); + + +// getNext(arr); // remove Select + + if (hasTop){ + getNext(arr); // remove top + limit = getLimit(arr); + } + console.log(sql) + console.log(arr) + var projection = getProjection(arr); + + getNext(arr); // remove From + + + if (hasWhere){ + var orObj = {}, orArr = []; + sqlishFilter.forEach(function(f, fk){ + if (hasOr){ + orArr.push(processFilter(f, {})); + } else { + processFilter(f, filter); + } + }); + + if (hasOr){ + filter = { $or: orArr }; + } + + getNext(arr, 2); // remove where and clause, since its handled earlier + } + + if (hasOrderBy){ + getNext(arr); // remove order by + sort = getSort(arr); + } + + + var ret = { + projection: projection, + filter: filter, + sort: sort || {}, + limit: limit || 20 + }; + + console.log('Converted Command: ' + 'db.' + ret.collection + '.find(' + JSON.stringify(ret.filter) + ', ' + JSON.stringify(ret.projection) + ').sort(' + JSON.stringify(ret.sort) + ').limit(' + ret.limit + ')'); + return ret; + } +} \ No newline at end of file diff --git a/tools/translateDefinitionFile.js b/tools/translateDefinitionFile.js new file mode 100644 index 0000000..8fc8ed4 --- /dev/null +++ b/tools/translateDefinitionFile.js @@ -0,0 +1,84 @@ +console.log('This translation tool uses Yandex.') +if(!process.argv[2]||!process.argv[3]||!process.argv[4]){ + console.log('You must input arguments.') + console.log('# node translateLanguageFile.js ') + console.log('Example:') + console.log('# node translateLanguageFile.js en_US en ar') + return +} +var defDir='../definitions/' +var fs=require('fs'); +var https = require('https'); +var jsonfile=require('jsonfile'); +var source=require(defDir+process.argv[2]+'.json') +var list = Object.keys(source) +console.log(list.length) +var extra = '' +var current = 1 +var currentItem = list[0] +var chosenFile = defDir+process.argv[4]+'.json' +try{ + newList=require(chosenFile) +}catch(err){ + console.log(chosenFile) + var newList={} +} +var newListAlphabetical={} +var goNext=function(){ + ++current + currentItem = list[current] + if(list.length===current){ + console.log('complete checking.. please wait') + Object.keys(newList).sort().forEach(function(y,t){ + newListAlphabetical[y]=newList[y] + }) + jsonfile.writeFile(chosenFile,newListAlphabetical,{spaces: 2},function(){ + console.log('complete writing') + }) + }else{ + next(currentItem) + } +} +var next=function(v){ + if(v===undefined){return false} + //trnsl.1.1.20170718T033617Z.a9bbd3b739ca59df.7f89b7474ec69812afd0014b5e338328ebf3fc39 + if(newList[v]&&newList[v]!==source[v]){ + goNext() + return + } + if(/<[a-z][\s\S]*>/i.test(source[v])===true){ + extra+='&format=html' + } + var url = 'https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20160311T042953Z.341f2f63f38bdac6.c7e5c01fff7f57160141021ca61b60e36ff4d379'+extra+'&lang='+process.argv[3]+'-'+process.argv[4]+'&text='+source[v] + https.request(url, function(data) { + data.setEncoding('utf8'); + var chunks=''; + data.on('data', (chunk) => { + chunks+=chunk; + }); + data.on('end', () => { + try{ + chunks=JSON.parse(chunks) + if(chunks.html){ + if(chunks.html[0]){ + var translation=chunks.html[0] + }else{ + var translation=chunks.html + } + + }else{ + var translation=chunks.text[0] + } + }catch(err){ + var translation=source[v] + } + newList[v]=translation; + console.log(current+'/'+list.length+','+v+' ---> '+translation) + goNext() + }); + }).on('error', function(e) { + console.log('ERROR : 500 '+v) + res.sendStatus(500); + }).end(); +} +next(currentItem) \ No newline at end of file diff --git a/tools/translateLanguageFile.js b/tools/translateLanguageFile.js new file mode 100644 index 0000000..418de20 --- /dev/null +++ b/tools/translateLanguageFile.js @@ -0,0 +1,84 @@ +console.log('This translation tool uses Yandex.') +if(!process.argv[2]||!process.argv[3]||!process.argv[4]){ + console.log('You must input arguments.') + console.log('# node translateLanguageFile.js ') + console.log('Example:') + console.log('# node translateLanguageFile.js en_US en ar') + return +} +var langDir='../languages/' +var fs=require('fs'); +var https = require('https'); +var jsonfile=require('jsonfile'); +var source=require(langDir+process.argv[2]+'.json') +var list = Object.keys(source) +console.log(list.length) +var extra = '' +var current = 1 +var currentItem = list[0] +var chosenFile = langDir+process.argv[4]+'.json' +try{ + newList=require(chosenFile) +}catch(err){ + console.log(chosenFile) + var newList={} +} +var newListAlphabetical={} +var goNext=function(){ + ++current + currentItem = list[current] + if(list.length===current){ + console.log('complete checking.. please wait') + Object.keys(newList).sort().forEach(function(y,t){ + newListAlphabetical[y]=newList[y] + }) + jsonfile.writeFile(chosenFile,newListAlphabetical,{spaces: 2},function(){ + console.log('complete writing') + }) + }else{ + next(currentItem) + } +} +var next=function(v){ + if(v===undefined){return false} + //trnsl.1.1.20170718T033617Z.a9bbd3b739ca59df.7f89b7474ec69812afd0014b5e338328ebf3fc39 + if(newList[v]&&newList[v]!==source[v]){ + goNext() + return + } + if(/<[a-z][\s\S]*>/i.test(source[v])===true){ + extra+='&format=html' + } + var url = 'https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20160311T042953Z.341f2f63f38bdac6.c7e5c01fff7f57160141021ca61b60e36ff4d379'+extra+'&lang='+process.argv[3]+'-'+process.argv[4]+'&text='+source[v] + https.request(url, function(data) { + data.setEncoding('utf8'); + var chunks=''; + data.on('data', (chunk) => { + chunks+=chunk; + }); + data.on('end', () => { + try{ + chunks=JSON.parse(chunks) + if(chunks.html){ + if(chunks.html[0]){ + var translation=chunks.html[0] + }else{ + var translation=chunks.html + } + + }else{ + var translation=chunks.text[0] + } + }catch(err){ + var translation=source[v] + } + newList[v]=translation; + console.log(current+'/'+list.length+','+v+' ---> '+translation) + goNext() + }); + }).on('error', function(e) { + console.log('ERROR : 500 '+v) + res.sendStatus(500); + }).end(); +} +next(currentItem) \ No newline at end of file diff --git a/web/libs/.gitignore b/web/libs/.gitignore new file mode 100644 index 0000000..efd261b --- /dev/null +++ b/web/libs/.gitignore @@ -0,0 +1 @@ +demo \ No newline at end of file diff --git a/web/libs/audio/alert.mp3 b/web/libs/audio/alert.mp3 new file mode 100644 index 0000000..4936bba Binary files /dev/null and b/web/libs/audio/alert.mp3 differ diff --git a/web/libs/audio/pop.mp3 b/web/libs/audio/pop.mp3 new file mode 100644 index 0000000..cbd35cc Binary files /dev/null and b/web/libs/audio/pop.mp3 differ diff --git a/web/libs/css/bootstrap-table.min.css b/web/libs/css/bootstrap-table.min.css new file mode 100644 index 0000000..d72d065 --- /dev/null +++ b/web/libs/css/bootstrap-table.min.css @@ -0,0 +1 @@ +.fixed-table-container .bs-checkbox,.fixed-table-container .no-records-found{text-align:center}.fixed-table-body thead th .th-inner,.table td,.table th{box-sizing:border-box}.bootstrap-table .table{margin-bottom:0!important;border-bottom:1px solid #ddd;border-collapse:collapse!important;border-radius:1px}.bootstrap-table .table:not(.table-condensed),.bootstrap-table .table:not(.table-condensed)>tbody>tr>td,.bootstrap-table .table:not(.table-condensed)>tbody>tr>th,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>td,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>th,.bootstrap-table .table:not(.table-condensed)>thead>tr>td{padding:8px}.bootstrap-table .table.table-no-bordered>tbody>tr>td,.bootstrap-table .table.table-no-bordered>thead>tr>th{border-right:2px solid transparent}.bootstrap-table .table.table-no-bordered>tbody>tr>td:last-child{border-right:none}.fixed-table-container{position:relative;clear:both;border:1px solid #ddd;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px}.fixed-table-container.table-no-bordered{border:1px solid transparent}.fixed-table-footer,.fixed-table-header{overflow:hidden}.fixed-table-footer{border-top:1px solid #ddd}.fixed-table-body{overflow-x:auto;overflow-y:auto;height:100%}.fixed-table-container table{width:100%}.fixed-table-container thead th{height:0;padding:0;margin:0;border-left:1px solid #ddd}.fixed-table-container thead th:focus{outline:transparent solid 0}.fixed-table-container thead th:first-child{border-left:none;border-top-left-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px}.fixed-table-container tbody td .th-inner,.fixed-table-container thead th .th-inner{padding:8px;line-height:24px;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fixed-table-container thead th .sortable{cursor:pointer;background-position:right;background-repeat:no-repeat;padding-right:30px}.fixed-table-container thead th .both{background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC')}.fixed-table-container thead th .asc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==)}.fixed-table-container thead th .desc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII=)}.fixed-table-container th.detail{width:30px}.fixed-table-container tbody td{border-left:1px solid #ddd}.fixed-table-container tbody tr:first-child td{border-top:none}.fixed-table-container tbody td:first-child{border-left:none}.fixed-table-container tbody .selected td{background-color:#f5f5f5}.fixed-table-container .bs-checkbox .th-inner{padding:8px 0}.fixed-table-container input[type=radio],.fixed-table-container input[type=checkbox]{margin:0 auto!important}.fixed-table-pagination .pagination-detail,.fixed-table-pagination div.pagination{margin-top:10px;margin-bottom:10px}.fixed-table-pagination div.pagination .pagination{margin:0}.fixed-table-pagination .pagination a{padding:6px 12px;line-height:1.428571429}.fixed-table-pagination .pagination-info{line-height:34px;margin-right:5px}.fixed-table-pagination .btn-group{position:relative;display:inline-block;vertical-align:middle}.fixed-table-pagination .dropup .dropdown-menu{margin-bottom:0}.fixed-table-pagination .page-list{display:inline-block}.fixed-table-toolbar .columns-left{margin-right:5px}.fixed-table-toolbar .columns-right{margin-left:5px}.fixed-table-toolbar .columns label{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429}.fixed-table-toolbar .bs-bars,.fixed-table-toolbar .columns,.fixed-table-toolbar .search{position:relative;margin-top:10px;margin-bottom:10px;line-height:34px}.fixed-table-pagination li.disabled a{pointer-events:none;cursor:default}.fixed-table-loading{display:none;position:absolute;top:42px;right:0;bottom:0;left:0;z-index:99;background-color:#fff;text-align:center}.fixed-table-body .card-view .title{font-weight:700;display:inline-block;min-width:30%;text-align:left!important}.table td,.table th{vertical-align:middle}.fixed-table-toolbar .dropdown-menu{text-align:left;max-height:300px;overflow:auto}.fixed-table-toolbar .btn-group>.btn-group{display:inline-block;margin-left:-1px!important}.fixed-table-toolbar .btn-group>.btn-group>.btn{border-radius:0}.fixed-table-toolbar .btn-group>.btn-group:first-child>.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.fixed-table-toolbar .btn-group>.btn-group:last-child>.btn{border-top-right-radius:4px;border-bottom-right-radius:4px}.bootstrap-table .table>thead>tr>th{vertical-align:bottom;border-bottom:1px solid #ddd}.bootstrap-table .table thead>tr>th{padding:0;margin:0}.bootstrap-table .fixed-table-footer tbody>tr>td{padding:0!important}.bootstrap-table .fixed-table-footer .table{border-bottom:none;border-radius:0;padding:0!important}.pull-right .dropdown-menu{right:0;left:auto}p.fixed-table-scroll-inner{width:100%;height:200px}div.fixed-table-scroll-outer{top:0;left:0;visibility:hidden;width:200px;height:150px;overflow:hidden} \ No newline at end of file diff --git a/web/libs/css/bootstrap-theme.css b/web/libs/css/bootstrap-theme.css new file mode 100644 index 0000000..31d8882 --- /dev/null +++ b/web/libs/css/bootstrap-theme.css @@ -0,0 +1,587 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +.btn-default, +.btn-primary, +.btn-success, +.btn-info, +.btn-warning, +.btn-danger { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); +} +.btn-default:active, +.btn-primary:active, +.btn-success:active, +.btn-info:active, +.btn-warning:active, +.btn-danger:active, +.btn-default.active, +.btn-primary.active, +.btn-success.active, +.btn-info.active, +.btn-warning.active, +.btn-danger.active { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-default.disabled, +.btn-primary.disabled, +.btn-success.disabled, +.btn-info.disabled, +.btn-warning.disabled, +.btn-danger.disabled, +.btn-default[disabled], +.btn-primary[disabled], +.btn-success[disabled], +.btn-info[disabled], +.btn-warning[disabled], +.btn-danger[disabled], +fieldset[disabled] .btn-default, +fieldset[disabled] .btn-primary, +fieldset[disabled] .btn-success, +fieldset[disabled] .btn-info, +fieldset[disabled] .btn-warning, +fieldset[disabled] .btn-danger { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-default .badge, +.btn-primary .badge, +.btn-success .badge, +.btn-info .badge, +.btn-warning .badge, +.btn-danger .badge { + text-shadow: none; +} +.btn:active, +.btn.active { + background-image: none; +} +.btn-default { + text-shadow: 0 1px 0 #fff; + background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); + background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #dbdbdb; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus { + background-color: #e0e0e0; + background-position: 0 -15px; +} +.btn-default:active, +.btn-default.active { + background-color: #e0e0e0; + border-color: #dbdbdb; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #e0e0e0; + background-image: none; +} +.btn-primary { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); + background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #245580; +} +.btn-primary:hover, +.btn-primary:focus { + background-color: #265a88; + background-position: 0 -15px; +} +.btn-primary:active, +.btn-primary.active { + background-color: #265a88; + border-color: #245580; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #265a88; + background-image: none; +} +.btn-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #3e8f3e; +} +.btn-success:hover, +.btn-success:focus { + background-color: #419641; + background-position: 0 -15px; +} +.btn-success:active, +.btn-success.active { + background-color: #419641; + border-color: #3e8f3e; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #419641; + background-image: none; +} +.btn-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #28a4c9; +} +.btn-info:hover, +.btn-info:focus { + background-color: #2aabd2; + background-position: 0 -15px; +} +.btn-info:active, +.btn-info.active { + background-color: #2aabd2; + border-color: #28a4c9; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #2aabd2; + background-image: none; +} +.btn-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #e38d13; +} +.btn-warning:hover, +.btn-warning:focus { + background-color: #eb9316; + background-position: 0 -15px; +} +.btn-warning:active, +.btn-warning.active { + background-color: #eb9316; + border-color: #e38d13; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #eb9316; + background-image: none; +} +.btn-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #b92c28; +} +.btn-danger:hover, +.btn-danger:focus { + background-color: #c12e2a; + background-position: 0 -15px; +} +.btn-danger:active, +.btn-danger.active { + background-color: #c12e2a; + border-color: #b92c28; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #c12e2a; + background-image: none; +} +.thumbnail, +.img-thumbnail { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #e8e8e8; + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + background-color: #2e6da4; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; +} +.navbar-default { + background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); + background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); + background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); +} +.navbar-brand, +.navbar-nav > li > a { + text-shadow: 0 1px 0 rgba(255, 255, 255, .25); +} +.navbar-inverse { + background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); + background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); + background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); +} +.navbar-inverse .navbar-brand, +.navbar-inverse .navbar-nav > li > a { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); +} +.navbar-static-top, +.navbar-fixed-top, +.navbar-fixed-bottom { + border-radius: 0; +} +@media (max-width: 767px) { + .navbar .navbar-nav .open .dropdown-menu > .active > a, + .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; + } +} +.alert { + text-shadow: 0 1px 0 rgba(255, 255, 255, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); +} +.alert-success { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); + background-repeat: repeat-x; + border-color: #b2dba1; +} +.alert-info { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); + background-repeat: repeat-x; + border-color: #9acfea; +} +.alert-warning { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); + background-repeat: repeat-x; + border-color: #f5e79e; +} +.alert-danger { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); + background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); + background-repeat: repeat-x; + border-color: #dca7a7; +} +.progress { + background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); + background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.list-group { + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + text-shadow: 0 -1px 0 #286090; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); + background-repeat: repeat-x; + border-color: #2b669a; +} +.list-group-item.active .badge, +.list-group-item.active:hover .badge, +.list-group-item.active:focus .badge { + text-shadow: none; +} +.panel { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: 0 1px 2px rgba(0, 0, 0, .05); +} +.panel-default > .panel-heading { + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.panel-primary > .panel-heading { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; +} +.panel-success > .panel-heading { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); + background-repeat: repeat-x; +} +.panel-info > .panel-heading { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); + background-repeat: repeat-x; +} +.panel-warning > .panel-heading { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); + background-repeat: repeat-x; +} +.panel-danger > .panel-heading { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); + background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); + background-repeat: repeat-x; +} +.well { + background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; + border-color: #dcdcdc; + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); +} +/*# sourceMappingURL=bootstrap-theme.css.map */ diff --git a/web/libs/css/bootstrap-theme.css.map b/web/libs/css/bootstrap-theme.css.map new file mode 100644 index 0000000..d876f60 --- /dev/null +++ b/web/libs/css/bootstrap-theme.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["bootstrap-theme.css","less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"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","file":"bootstrap-theme.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file diff --git a/web/libs/css/bootstrap-theme.min.css b/web/libs/css/bootstrap-theme.min.css new file mode 100644 index 0000000..5e39401 --- /dev/null +++ b/web/libs/css/bootstrap-theme.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} +/*# sourceMappingURL=bootstrap-theme.min.css.map */ \ No newline at end of file diff --git a/web/libs/css/bootstrap-theme.min.css.map b/web/libs/css/bootstrap-theme.min.css.map new file mode 100644 index 0000000..94813e9 --- /dev/null +++ b/web/libs/css/bootstrap-theme.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file diff --git a/web/libs/css/bootstrap.css b/web/libs/css/bootstrap.css new file mode 100644 index 0000000..6167622 --- /dev/null +++ b/web/libs/css/bootstrap.css @@ -0,0 +1,6757 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background-color: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + margin: .67em 0; + font-size: 2em; +} +mark { + color: #000; + background: #ff0; +} +small { + font-size: 80%; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -.5em; +} +sub { + bottom: -.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + height: 0; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + margin: 0; + font: inherit; + color: inherit; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} +legend { + padding: 0; + border: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-spacing: 0; + border-collapse: collapse; +} +td, +th { + padding: 0; +} +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ +@media print { + *, + *:before, + *:after { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + .navbar { + display: none; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\002a"; +} +.glyphicon-plus:before { + content: "\002b"; +} +.glyphicon-euro:before, +.glyphicon-eur:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +.glyphicon-cd:before { + content: "\e201"; +} +.glyphicon-save-file:before { + content: "\e202"; +} +.glyphicon-open-file:before { + content: "\e203"; +} +.glyphicon-level-up:before { + content: "\e204"; +} +.glyphicon-copy:before { + content: "\e205"; +} +.glyphicon-paste:before { + content: "\e206"; +} +.glyphicon-alert:before { + content: "\e209"; +} +.glyphicon-equalizer:before { + content: "\e210"; +} +.glyphicon-king:before { + content: "\e211"; +} +.glyphicon-queen:before { + content: "\e212"; +} +.glyphicon-pawn:before { + content: "\e213"; +} +.glyphicon-bishop:before { + content: "\e214"; +} +.glyphicon-knight:before { + content: "\e215"; +} +.glyphicon-baby-formula:before { + content: "\e216"; +} +.glyphicon-tent:before { + content: "\26fa"; +} +.glyphicon-blackboard:before { + content: "\e218"; +} +.glyphicon-bed:before { + content: "\e219"; +} +.glyphicon-apple:before { + content: "\f8ff"; +} +.glyphicon-erase:before { + content: "\e221"; +} +.glyphicon-hourglass:before { + content: "\231b"; +} +.glyphicon-lamp:before { + content: "\e223"; +} +.glyphicon-duplicate:before { + content: "\e224"; +} +.glyphicon-piggy-bank:before { + content: "\e225"; +} +.glyphicon-scissors:before { + content: "\e226"; +} +.glyphicon-bitcoin:before { + content: "\e227"; +} +.glyphicon-btc:before { + content: "\e227"; +} +.glyphicon-xbt:before { + content: "\e227"; +} +.glyphicon-yen:before { + content: "\00a5"; +} +.glyphicon-jpy:before { + content: "\00a5"; +} +.glyphicon-ruble:before { + content: "\20bd"; +} +.glyphicon-rub:before { + content: "\20bd"; +} +.glyphicon-scale:before { + content: "\e230"; +} +.glyphicon-ice-lolly:before { + content: "\e231"; +} +.glyphicon-ice-lolly-tasted:before { + content: "\e232"; +} +.glyphicon-education:before { + content: "\e233"; +} +.glyphicon-option-horizontal:before { + content: "\e234"; +} +.glyphicon-option-vertical:before { + content: "\e235"; +} +.glyphicon-menu-hamburger:before { + content: "\e236"; +} +.glyphicon-modal-window:before { + content: "\e237"; +} +.glyphicon-oil:before { + content: "\e238"; +} +.glyphicon-grain:before { + content: "\e239"; +} +.glyphicon-sunglasses:before { + content: "\e240"; +} +.glyphicon-text-size:before { + content: "\e241"; +} +.glyphicon-text-color:before { + content: "\e242"; +} +.glyphicon-text-background:before { + content: "\e243"; +} +.glyphicon-object-align-top:before { + content: "\e244"; +} +.glyphicon-object-align-bottom:before { + content: "\e245"; +} +.glyphicon-object-align-horizontal:before { + content: "\e246"; +} +.glyphicon-object-align-left:before { + content: "\e247"; +} +.glyphicon-object-align-vertical:before { + content: "\e248"; +} +.glyphicon-object-align-right:before { + content: "\e249"; +} +.glyphicon-triangle-right:before { + content: "\e250"; +} +.glyphicon-triangle-left:before { + content: "\e251"; +} +.glyphicon-triangle-bottom:before { + content: "\e252"; +} +.glyphicon-triangle-top:before { + content: "\e253"; +} +.glyphicon-console:before { + content: "\e254"; +} +.glyphicon-superscript:before { + content: "\e255"; +} +.glyphicon-subscript:before { + content: "\e256"; +} +.glyphicon-menu-left:before { + content: "\e257"; +} +.glyphicon-menu-right:before { + content: "\e258"; +} +.glyphicon-menu-down:before { + content: "\e259"; +} +.glyphicon-menu-up:before { + content: "\e260"; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #337ab7; + text-decoration: none; +} +a:hover, +a:focus { + color: #23527c; + text-decoration: underline; +} +a:focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + display: inline-block; + max-width: 100%; + height: auto; + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +[role="button"] { + cursor: pointer; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #777; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 30px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 14px; +} +h6, +.h6 { + font-size: 12px; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 300; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} +small, +.small { + font-size: 85%; +} +mark, +.mark { + padding: .2em; + background-color: #fcf8e3; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-nowrap { + white-space: nowrap; +} +.text-lowercase { + text-transform: lowercase; +} +.text-uppercase { + text-transform: uppercase; +} +.text-capitalize { + text-transform: capitalize; +} +.text-muted { + color: #777; +} +.text-primary { + color: #337ab7; +} +a.text-primary:hover, +a.text-primary:focus { + color: #286090; +} +.text-success { + color: #3c763d; +} +a.text-success:hover, +a.text-success:focus { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover, +a.text-info:focus { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover, +a.text-warning:focus { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover, +a.text-danger:focus { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #337ab7; +} +a.bg-primary:hover, +a.bg-primary:focus { + background-color: #286090; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover, +a.bg-success:focus { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover, +a.bg-info:focus { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover, +a.bg-warning:focus { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover, +a.bg-danger:focus { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + margin-left: -5px; + list-style: none; +} +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #777; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + text-align: right; + border-right: 5px solid #eee; + border-left: 0; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.42857143; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + -webkit-box-shadow: none; + box-shadow: none; +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +.row { + margin-right: -15px; + margin-left: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0; + } +} +table { + background-color: transparent; +} +caption { + padding-top: 8px; + padding-bottom: 8px; + color: #777; + text-align: left; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + display: table-column; + float: none; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + display: table-cell; + float: none; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +.table-responsive { + min-height: .01%; + overflow-x: auto; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857143; + color: #555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); +} +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999; +} +.form-control::-webkit-input-placeholder { + color: #999; +} +.form-control::-ms-expand { + background-color: transparent; + border: 0; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + background-color: #eee; + opacity: 1; +} +.form-control[disabled], +fieldset[disabled] .form-control { + cursor: not-allowed; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"].form-control, + input[type="time"].form-control, + input[type="datetime-local"].form-control, + input[type="month"].form-control { + line-height: 34px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm, + .input-group-sm input[type="date"], + .input-group-sm input[type="time"], + .input-group-sm input[type="datetime-local"], + .input-group-sm input[type="month"] { + line-height: 30px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg, + .input-group-lg input[type="date"], + .input-group-lg input[type="time"], + .input-group-lg input[type="datetime-local"], + .input-group-lg input[type="month"] { + line-height: 46px; + } +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: 4px \9; + margin-left: -20px; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + min-height: 34px; + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-right: 0; + padding-left: 0; +} +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.form-group-sm select.form-control { + height: 30px; + line-height: 30px; +} +.form-group-sm textarea.form-control, +.form-group-sm select[multiple].form-control { + height: auto; +} +.form-group-sm .form-control-static { + height: 30px; + min-height: 32px; + padding: 6px 10px; + font-size: 12px; + line-height: 1.5; +} +.input-lg { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-lg { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.form-group-lg select.form-control { + height: 46px; + line-height: 46px; +} +.form-group-lg textarea.form-control, +.form-group-lg select[multiple].form-control { + height: auto; +} +.form-group-lg .form-control-static { + height: 46px; + min-height: 38px; + padding: 11px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; + pointer-events: none; +} +.input-lg + .form-control-feedback, +.input-group-lg + .form-control-feedback, +.form-group-lg .form-control + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} +.input-sm + .form-control-feedback, +.input-group-sm + .form-control-feedback, +.form-group-sm .form-control + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; +} +.has-error .form-control-feedback { + color: #a94442; +} +.has-feedback label ~ .form-control-feedback { + top: 25px; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + padding-top: 7px; + margin-bottom: 0; + text-align: right; + } +} +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 11px; + font-size: 18px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + font-size: 12px; + } +} +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #333; + text-decoration: none; +} +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; + opacity: .65; +} +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:focus, +.btn-default.focus { + color: #333; + background-color: #e6e6e6; + border-color: #8c8c8c; +} +.btn-default:hover { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active:hover, +.btn-default.active:hover, +.open > .dropdown-toggle.btn-default:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.open > .dropdown-toggle.btn-default:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn-default.focus { + color: #333; + background-color: #d4d4d4; + border-color: #8c8c8c; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus { + background-color: #fff; + border-color: #ccc; +} +.btn-default .badge { + color: #fff; + background-color: #333; +} +.btn-primary { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary:focus, +.btn-primary.focus { + color: #fff; + background-color: #286090; + border-color: #122b40; +} +.btn-primary:hover { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active:hover, +.btn-primary.active:hover, +.open > .dropdown-toggle.btn-primary:hover, +.btn-primary:active:focus, +.btn-primary.active:focus, +.open > .dropdown-toggle.btn-primary:focus, +.btn-primary:active.focus, +.btn-primary.active.focus, +.open > .dropdown-toggle.btn-primary.focus { + color: #fff; + background-color: #204d74; + border-color: #122b40; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus { + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary .badge { + color: #337ab7; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:focus, +.btn-success.focus { + color: #fff; + background-color: #449d44; + border-color: #255625; +} +.btn-success:hover { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active:hover, +.btn-success.active:hover, +.open > .dropdown-toggle.btn-success:hover, +.btn-success:active:focus, +.btn-success.active:focus, +.open > .dropdown-toggle.btn-success:focus, +.btn-success:active.focus, +.btn-success.active.focus, +.open > .dropdown-toggle.btn-success.focus { + color: #fff; + background-color: #398439; + border-color: #255625; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:focus, +.btn-info.focus { + color: #fff; + background-color: #31b0d5; + border-color: #1b6d85; +} +.btn-info:hover { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active:hover, +.btn-info.active:hover, +.open > .dropdown-toggle.btn-info:hover, +.btn-info:active:focus, +.btn-info.active:focus, +.open > .dropdown-toggle.btn-info:focus, +.btn-info:active.focus, +.btn-info.active.focus, +.open > .dropdown-toggle.btn-info.focus { + color: #fff; + background-color: #269abc; + border-color: #1b6d85; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:focus, +.btn-warning.focus { + color: #fff; + background-color: #ec971f; + border-color: #985f0d; +} +.btn-warning:hover { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active:hover, +.btn-warning.active:hover, +.open > .dropdown-toggle.btn-warning:hover, +.btn-warning:active:focus, +.btn-warning.active:focus, +.open > .dropdown-toggle.btn-warning:focus, +.btn-warning:active.focus, +.btn-warning.active.focus, +.open > .dropdown-toggle.btn-warning.focus { + color: #fff; + background-color: #d58512; + border-color: #985f0d; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:focus, +.btn-danger.focus { + color: #fff; + background-color: #c9302c; + border-color: #761c19; +} +.btn-danger:hover { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active:hover, +.btn-danger.active:hover, +.open > .dropdown-toggle.btn-danger:hover, +.btn-danger:active:focus, +.btn-danger.active:focus, +.open > .dropdown-toggle.btn-danger:focus, +.btn-danger:active.focus, +.btn-danger.active.focus, +.open > .dropdown-toggle.btn-danger.focus { + color: #fff; + background-color: #ac2925; + border-color: #761c19; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #337ab7; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link.active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-timing-function: ease; + -o-transition-timing-function: ease; + transition-timing-function: ease; + -webkit-transition-duration: .35s; + -o-transition-duration: .35s; + transition-duration: .35s; + -webkit-transition-property: height, visibility; + -o-transition-property: height, visibility; + transition-property: height, visibility; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid \9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + text-align: left; + list-style: none; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + background-color: #337ab7; + outline: 0; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #777; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + right: 0; + left: auto; +} +.dropdown-menu-left { + right: auto; + left: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #777; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + content: ""; + border-top: 0; + border-bottom: 4px dashed; + border-bottom: 4px solid \9; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } + .navbar-right .dropdown-menu-left { + right: auto; + left: 0; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn, +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + display: table-cell; + float: none; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group .form-control:focus { + z-index: 3; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + z-index: 2; + margin-left: -1px; +} +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li.disabled > a { + color: #777; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #777; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eee; + border-color: #337ab7; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eee #eee #ddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #fff; + background-color: #337ab7; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + height: 50px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +.navbar-brand > img { + display: block; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -15px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777; +} +.navbar-default .navbar-nav > li > a { + color: #777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #ddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #888; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555; + background-color: #e7e7e7; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777; +} +.navbar-default .navbar-link:hover { + color: #333; +} +.navbar-default .btn-link { + color: #777; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #333; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #ccc; +} +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #9d9d9d; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + color: #fff; + background-color: #080808; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #9d9d9d; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #9d9d9d; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.navbar-inverse .btn-link { + color: #9d9d9d; +} +.navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link:focus { + color: #fff; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #444; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + padding: 0 5px; + color: #ccc; + content: "/\00a0"; +} +.breadcrumb > .active { + color: #777; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.42857143; + color: #337ab7; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + z-index: 2; + color: #23527c; + background-color: #eee; + border-color: #ddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 3; + color: #fff; + cursor: default; + background-color: #337ab7; + border-color: #337ab7; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #777; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eee; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #777; + cursor: not-allowed; + background-color: #fff; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #777; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #5e5e5e; +} +.label-primary { + background-color: #337ab7; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #286090; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: middle; + background-color: #777; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge, +.btn-group-xs > .btn .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #337ab7; + background-color: #fff; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding-top: 30px; + padding-bottom: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #eee; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; +} +.jumbotron > hr { + border-top-color: #d5d5d5; +} +.container .jumbotron, +.container-fluid .jumbotron { + padding-right: 15px; + padding-left: 15px; + border-radius: 6px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: border .2s ease-in-out; + -o-transition: border .2s ease-in-out; + transition: border .2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-right: auto; + margin-left: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #337ab7; +} +.thumbnail .caption { + padding: 9px; + color: #333; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #337ab7; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + -webkit-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #5cb85c; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media-body { + width: 10000px; +} +.media-object { + display: block; +} +.media-object.img-thumbnail { + max-width: none; +} +.media-right, +.media > .pull-right { + padding-left: 10px; +} +.media-left, +.media > .pull-left { + padding-right: 10px; +} +.media-left, +.media-right, +.media-body { + display: table-cell; + vertical-align: top; +} +.media-middle { + vertical-align: middle; +} +.media-bottom { + vertical-align: bottom; +} +.media-heading { + margin-top: 0; + margin-bottom: 5px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + padding-left: 0; + margin-bottom: 20px; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +a.list-group-item, +button.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading, +button.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, +button.list-group-item:hover, +a.list-group-item:focus, +button.list-group-item:focus { + color: #555; + text-decoration: none; + background-color: #f5f5f5; +} +button.list-group-item { + width: 100%; + text-align: left; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + color: #777; + cursor: not-allowed; + background-color: #eee; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #777; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #c7ddef; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success, +button.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading, +button.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +button.list-group-item-success:hover, +a.list-group-item-success:focus, +button.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +button.list-group-item-success.active, +a.list-group-item-success.active:hover, +button.list-group-item-success.active:hover, +a.list-group-item-success.active:focus, +button.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info, +button.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading, +button.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +button.list-group-item-info:hover, +a.list-group-item-info:focus, +button.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +button.list-group-item-info.active, +a.list-group-item-info.active:hover, +button.list-group-item-info.active:hover, +a.list-group-item-info.active:focus, +button.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning, +button.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading, +button.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +button.list-group-item-warning:hover, +a.list-group-item-warning:focus, +button.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +button.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +button.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus, +button.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger, +button.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading, +button.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +button.list-group-item-danger:hover, +a.list-group-item-danger:focus, +button.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +button.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +button.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus, +button.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a, +.panel-title > small, +.panel-title > .small, +.panel-title > small > a, +.panel-title > .small > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group, +.panel > .panel-collapse > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item, +.panel > .panel-collapse > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child, +.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child, +.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table caption, +.panel > .table-responsive > .table caption, +.panel > .panel-collapse > .table caption { + padding-right: 15px; + padding-left: 15px; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive, +.panel > .table + .panel-body, +.panel > .table-responsive + .panel-body { + border-top: 1px solid #ddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + margin-bottom: 0; + border: 0; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body, +.panel-group .panel-heading + .panel-collapse > .list-group { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default > .panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ddd; +} +.panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #337ab7; +} +.panel-primary > .panel-heading { + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #337ab7; +} +.panel-primary > .panel-heading .badge { + color: #337ab7; + background-color: #fff; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #337ab7; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-heading .badge { + color: #dff0d8; + background-color: #3c763d; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-heading .badge { + color: #d9edf7; + background-color: #31708f; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #bce8f1; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-heading .badge { + color: #fcf8e3; + background-color: #8a6d3b; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-heading .badge { + color: #f2dede; + background-color: #a94442; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ebccd1; +} +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} +.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.embed-responsive-4by3 { + padding-bottom: 75%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, .15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: .2; +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + filter: alpha(opacity=50); + opacity: .5; +} +button.close { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + filter: alpha(opacity=0); + opacity: 0; +} +.modal-backdrop.in { + filter: alpha(opacity=50); + opacity: .5; +} +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 15px; +} +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; + font-style: normal; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + filter: alpha(opacity=0); + opacity: 0; + + line-break: auto; +} +.tooltip.in { + filter: alpha(opacity=90); + opacity: .9; +} +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-left .tooltip-arrow { + right: 5px; + bottom: 0; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-right .tooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + + line-break: auto; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + content: ""; + border-width: 10px; +} +.popover.top > .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, .25); + border-bottom-width: 0; +} +.popover.top > .arrow:after { + bottom: 1px; + margin-left: -10px; + content: " "; + border-top-color: #fff; + border-bottom-width: 0; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, .25); + border-left-width: 0; +} +.popover.right > .arrow:after { + bottom: -10px; + left: 1px; + content: " "; + border-right-color: #fff; + border-left-width: 0; +} +.popover.bottom > .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, .25); +} +.popover.bottom > .arrow:after { + top: 1px; + margin-left: -10px; + content: " "; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, .25); +} +.popover.left > .arrow:after { + right: 1px; + bottom: -10px; + content: " "; + border-right-width: 0; + border-left-color: #fff; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +@media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .item { + -webkit-transition: -webkit-transform .6s ease-in-out; + -o-transition: -o-transform .6s ease-in-out; + transition: transform .6s ease-in-out; + + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + perspective: 1000px; + } + .carousel-inner > .item.next, + .carousel-inner > .item.active.right { + left: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + .carousel-inner > .item.prev, + .carousel-inner > .item.active.left { + left: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + .carousel-inner > .item.next.left, + .carousel-inner > .item.prev.right, + .carousel-inner > .item.active { + left: 0; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + background-color: rgba(0, 0, 0, 0); + filter: alpha(opacity=50); + opacity: .5; +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control:hover, +.carousel-control:focus { + color: #fff; + text-decoration: none; + filter: alpha(opacity=90); + outline: 0; + opacity: .9; +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + margin-top: -10px; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + font-family: serif; + line-height: 1; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; +} +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -10px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -10px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -10px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-header:before, +.modal-header:after, +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-header:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +/*# sourceMappingURL=bootstrap.css.map */ diff --git a/web/libs/css/bootstrap.css.map b/web/libs/css/bootstrap.css.map new file mode 100644 index 0000000..f010c82 --- /dev/null +++ b/web/libs/css/bootstrap.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"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AW,iBAAA;CHsR9C;AGrRmC;EAAW,iBAAA;CHwR9C;AGvRmC;EAAW,iBAAA;CH0R9C;AGzRmC;EAAW,iBAAA;CH4R9C;AG3RmC;EAAW,iBAAA;CH8R9C;AG7RmC;EAAW,iBAAA;CHgS9C;AG/RmC;EAAW,iBAAA;CHkS9C;AGjSmC;EAAW,iBAAA;CHoS9C;AGnSmC;EAAW,iBAAA;CHsS9C;AGrSmC;EAAW,iBAAA;CHwS9C;AGvSmC;EAAW,iBAAA;CH0S9C;AGzSmC;EAAW,iBAAA;CH4S9C;AG3SmC;EAAW,iBAAA;CH8S9C;AG7SmC;EAAW,iBAAA;CHgT9C;AG/SmC;EAAW,iBAAA;CHkT9C;AGjTmC;EAAW,iBAAA;CHoT9C;AGnTmC;EAAW,iBAAA;CHsT9C;AGrTmC;EAAW,iBAAA;CHwT9C;AGvTmC;EAAW,iBAAA;CH0T9C;AGzTmC;EAAW,iBAAA;CH4T9C;AG3TmC;EAAW,iBAAA;CH8T9C;AG7TmC;EAAW,iBAAA;CHgU9C;AG/TmC;EAAW,iBAAA;CHkU9C;AGjUmC;EAAW,iBAAA;CHoU9C;AGnUmC;EAAW,iBAAA;CHsU9C;AGrUmC;EAAW,iBAAA;CHwU9C;AGvUmC;EAAW,iBAAA;CH0U9C;AGzUmC;EAAW,iBAAA;CH4U9C;AG3UmC;EAAW,iBAAA;CH8U9C;AG7UmC;EAAW,iBAAA;CHgV9C;AG/UmC;EAAW,iBAAA;CHkV9C;AGjVmC;EAAW,iBAAA;CHoV9C;AGnVmC;EAAW,iBAAA;CHsV9C;AGrVmC;EAAW,iBAAA;CHwV9C;AGvVmC;EAAW,iBAAA;CH0V9C;AGzVmC;EAAW,iBAAA;CH4V9C;AG3VmC;EAAW,iBAAA;CH8V9C;AG7VmC;EAAW,iBAAA;CHgW9C;AG/VmC;EAAW,iBAAA;CHkW9C;AGjWmC;EAAW,iBAAA;CHoW9C;AGnWmC;EAAW,iBAAA;CHsW9C;AGrWmC;EAAW,iBAAA;CHwW9C;AGvWmC;EAAW,iBAAA;CH0W9C;AGzWmC;EAAW,iBAAA;CH4W9C;AG3WmC;EAAW,iBAAA;CH8W9C;AG7WmC;EAAW,iBAAA;CHgX9C;AG/WmC;EAAW,iBAAA;CHkX9C;AGjXmC;EAAW,iBAAA;CHoX9C;AGnXmC;EAAW,iBAAA;CHsX9C;AGrXmC;EAAW,iBAAA;CHwX9C;AGvXmC;EAAW,iBAAA;CH0X9C;AGzXmC;EAAW,iBAAA;CH4X9C;AG3XmC;EAAW,iBAAA;CH8X9C;AG7XmC;EAAW,iBAAA;CHgY9C;AG/XmC;EAAW,iBAAA;CHkY9C;AGjYmC;EAAW,iBAAA;CHoY9C;AGnYmC;EAAW,iBAAA;CHsY9C;AGrYmC;EAAW,iBAAA;CHwY9C;AGvYmC;EAAW,iBAAA;CH0Y9C;AGzYmC;EAAW,iBAAA;CH4Y9C;AG3YmC;EAAW,iBAAA;CH8Y9C;AG7YmC;EAAW,iBAAA;CHgZ9C;AG/YmC;EAAW,iBAAA;CHkZ9C;AGjZmC;EAAW,iBAAA;CHoZ9C;AGnZmC;EAAW,iBAAA;CHsZ9C;AGrZmC;EAAW,iBAAA;CHwZ9C;AGvZmC;EAAW,iBAAA;CH0Z9C;AGzZmC;EAAW,iBAAA;CH4Z9C;AG3ZmC;EAAW,iBAAA;CH8Z9C;AG7ZmC;EAAW,iBAAA;CHga9C;AG/ZmC;EAAW,iBAAA;CHka9C;AGjamC;EAAW,iBAAA;CHoa9C;AGnamC;EAAW,iBAAA;CHsa9C;AGramC;EAAW,iBAAA;CHwa9C;AGvamC;EAAW,iBAAA;CH0a9C;AGzamC;EAAW,iBAAA;CH4a9C;AG3amC;EAAW,iBAAA;CH8a9C;AG7amC;EAAW,iBAAA;CHgb9C;AG/amC;EAAW,iBAAA;CHkb9C;AGjbmC;EAAW,iBAAA;CHob9C;AGnbmC;EAAW,iBAAA;CHsb9C;AGrbmC;EAAW,iBAAA;CHwb9C;AGvbmC;EAAW,iBAAA;CH0b9C;AGzbmC;EAAW,iBAAA;CH4b9C;AG3bmC;EAAW,iBAAA;CH8b9C;AG7bmC;EAAW,iBAAA;CHgc9C;AG/bmC;EAAW,iBAAA;CHkc9C;AGjcmC;EAAW,iBAAA;CHoc9C;AGncmC;EAAW,iBAAA;CHsc9C;AGrcmC;EAAW,iBAAA;CHwc9C;AGvcmC;EAAW,iBAAA;CH0c9C;AGzcmC;EAAW,iBAAA;CH4c9C;AG3cmC;EAAW,iBAAA;CH8c9C;AG7cmC;EAAW,iBAAA;CHgd9C;AG/cmC;EAAW,iBAAA;CHkd9C;AGjdmC;EAAW,iBAAA;CHod9C;AGndmC;EAAW,iBAAA;CHsd9C;AGrdmC;EAAW,iBAAA;CHwd9C;AGvdmC;EAAW,iBAAA;CH0d9C;AGzdmC;EAAW,iBAAA;CH4d9C;AG3dmC;EAAW,iBAAA;CH8d9C;AG7dmC;EAAW,iBAAA;CHge9C;AG/dmC;EAAW,iBAAA;CHke9C;AGjemC;EAAW,iBAAA;CHoe9C;AGnemC;EAAW,iBAAA;CHse9C;AGremC;EAAW,iBAAA;CHwe9C;AGvemC;EAAW,iBAAA;CH0e9C;AGzemC;EAAW,iBAAA;CH4e9C;AG3emC;EAAW,iBAAA;CH8e9C;AG7emC;EAAW,iBAAA;CHgf9C;AG/emC;EAAW,iBAAA;CHkf9C;AGjfmC;EAAW,iBAAA;CHof9C;AGnfmC;EAAW,iBAAA;CHsf9C;AGrfmC;EAAW,iBAAA;CHwf9C;AGvfmC;EAAW,iBAAA;CH0f9C;AGzfmC;EAAW,iBAAA;CH4f9C;AG3fmC;EAAW,iBAAA;CH8f9C;AG7fmC;EAAW,iBAAA;CHggB9C;AG/fmC;EAAW,iBAAA;CHkgB9C;AGjgBmC;EAAW,iBAAA;CHogB9C;AGngBmC;EAAW,iBAAA;CHsgB9C;AGrgBmC;EAAW,iBAAA;CHwgB9C;AGvgBmC;EAAW,iBAAA;CH0gB9C;AGzgBmC;EAAW,iBAAA;CH4gB9C;AG3gBmC;EAAW,iBAAA;CH8gB9C;AG7gBmC;EAAW,iBAAA;CHghB9C;AG/gBmC;EAAW,iBAAA;CHkhB9C;AGjhBmC;EAAW,iBAAA;CHohB9C;AGnhBmC;EAAW,iBAAA;CHshB9C;AGrhBmC;EAAW,iBAAA;CHwhB9C;AGvhBmC;EAAW,iBAAA;CH0hB9C;AGzhBmC;EAAW,iBAAA;CH4hB9C;AG3hBmC;EAAW,iBAAA;CH8hB9C;AG7hBmC;EAAW,iBAAA;CHgiB9C;AG/hBmC;EAAW,iBAAA;CHkiB9C;AGjiBmC;EAAW,iBAAA;CHoiB9C;AGniBmC;EAAW,iBAAA;CHsiB9C;AGriBmC;EAAW,iBAAA;CHwiB9C;AGviBmC;EAAW,iBAAA;CH0iB9C;AGziBmC;EAAW,iBAAA;CH4iB9C;AG3iBmC;EAAW,iBAAA;CH8iB9C;AG7iBmC;EAAW,iBAAA;CHgjB9C;AG/iBmC;EAAW,iBAAA;CHkjB9C;AGjjBmC;EAAW,iBAAA;CHojB9C;AGnjBmC;EAAW,iBAAA;CHsjB9C;AGrjBmC;EAAW,iBAAA;CHwjB9C;AGvjBmC;EAAW,iBAAA;CH0jB9C;AGzjBmC;EAAW,iBAAA;CH4jB9C;AG3jBmC;EAAW,iBAAA;CH8jB9C;AG7jBmC;EAAW,iBAAA;CHgkB9C;AG/jBmC;EAAW,iBAAA;CHkkB9C;AGjkBmC;EAAW,iBAAA;CHokB9C;AGnkBmC;EAAW,iBAAA;CHskB9C;AGrkBmC;EAAW,iBAAA;CHwkB9C;AGvkBmC;EAAW,iBAAA;CH0kB9C;AGzkBmC;EAAW,iBAAA;CH4kB9C;AG3kBmC;EAAW,iBAAA;CH8kB9C;AG7kBmC;EAAW,iBAAA;CHglB9C;AG/kBmC;EAAW,iBAAA;CHklB9C;AGjlBmC;EAAW,iBAAA;CHolB9C;AGnlBmC;EAAW,iBAAA;CHslB9C;AGrlBmC;EAAW,iBAAA;CHwlB9C;AGvlBmC;EAAW,iBAAA;CH0lB9C;AGzlBmC;EAAW,iBAAA;CH4lB9C;AG3lBmC;EAAW,iBAAA;CH8lB9C;AG7lBmC;EAAW,iBAAA;CHgmB9C;AG/lBmC;EAAW,iBAAA;CHkmB9C;AGjmBmC;EAAW,iBAAA;CHomB9C;AGnmBmC;EAAW,iBAAA;CHsmB9C;AGrmBmC;EAAW,iBAAA;CHwmB9C;AGvmBmC;EAAW,iBAAA;CH0mB9C;AGzmBmC;EAAW,iBAAA;CH4mB9C;AG3mBmC;EAAW,iBAAA;CH8mB9C;AG7mBmC;EAAW,iBAAA;CHgnB9C;AG/mBmC;EAAW,iBAAA;CHknB9C;AGjnBmC;EAAW,iBAAA;CHonB9C;AGnnBmC;EAAW,iBAAA;CHsnB9C;AGrnBmC;EAAW,iBAAA;CHwnB9C;AGvnBmC;EAAW,iBAAA;CH0nB9C;AGznBmC;EAAW,iBAAA;CH4nB9C;AG3nBmC;EAAW,iBAAA;CH8nB9C;AG7nBmC;EAAW,iBAAA;CHgoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AGvoBmC;EAAW,iBAAA;CH0oB9C;AGzoBmC;EAAW,iBAAA;CH4oB9C;AG3oBmC;EAAW,iBAAA;CH8oB9C;AG7oBmC;EAAW,iBAAA;CHgpB9C;AG/oBmC;EAAW,iBAAA;CHkpB9C;AGjpBmC;EAAW,iBAAA;CHopB9C;AGnpBmC;EAAW,iBAAA;CHspB9C;AGrpBmC;EAAW,iBAAA;CHwpB9C;AGvpBmC;EAAW,iBAAA;CH0pB9C;AGzpBmC;EAAW,iBAAA;CH4pB9C;AG3pBmC;EAAW,iBAAA;CH8pB9C;AG7pBmC;EAAW,iBAAA;CHgqB9C;AG/pBmC;EAAW,iBAAA;CHkqB9C;AGjqBmC;EAAW,iBAAA;CHoqB9C;AGnqBmC;EAAW,iBAAA;CHsqB9C;AGrqBmC;EAAW,iBAAA;CHwqB9C;AGvqBmC;EAAW,iBAAA;CH0qB9C;AGzqBmC;EAAW,iBAAA;CH4qB9C;AG3qBmC;EAAW,iBAAA;CH8qB9C;AG7qBmC;EAAW,iBAAA;CHgrB9C;AG/qBmC;EAAW,iBAAA;CHkrB9C;AGjrBmC;EAAW,iBAAA;CHorB9C;AGnrBmC;EAAW,iBAAA;CHsrB9C;AGrrBmC;EAAW,iBAAA;CHwrB9C;AGvrBmC;EAAW,iBAAA;CH0rB9C;AGzrBmC;EAAW,iBAAA;CH4rB9C;AG3rBmC;EAAW,iBAAA;CH8rB9C;AG7rBmC;EAAW,iBAAA;CHgsB9C;AG/rBmC;EAAW,iBAAA;CHksB9C;AGjsBmC;EAAW,iBAAA;CHosB9C;AGnsBmC;EAAW,iBAAA;CHssB9C;AGrsBmC;EAAW,iBAAA;CHwsB9C;AGvsBmC;EAAW,iBAAA;CH0sB9C;AGzsBmC;EAAW,iBAAA;CH4sB9C;AG3sBmC;EAAW,iBAAA;CH8sB9C;AG7sBmC;EAAW,iBAAA;CHgtB9C;AG/sBmC;EAAW,iBAAA;CHktB9C;AGjtBmC;EAAW,iBAAA;CHotB9C;AGntBmC;EAAW,iBAAA;CHstB9C;AGrtBmC;EAAW,iBAAA;CHwtB9C;AGvtBmC;EAAW,iBAAA;CH0tB9C;AGztBmC;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ukDH;AexkDC;EACE,oBAAA;Cf0kDH;Ae3kDC;EACE,WAAA;Cf6kDH;Ae9kDC;EACE,oBAAA;CfglDH;AejlDC;EACE,mBAAA;CfmlDH;Ae/kDC;EACE,YAAA;CfilDH;AejmDC;EACE,WAAA;CfmmDH;AepmDC;EACE,mBAAA;CfsmDH;AevmDC;EACE,mBAAA;CfymDH;Ae1mDC;EACE,UAAA;Cf4mDH;Ae7mDC;EACE,mBAAA;Cf+mDH;AehnDC;EACE,mBAAA;CfknDH;AennDC;EACE,UAAA;CfqnDH;AetnDC;EACE,mBAAA;CfwnDH;AeznDC;EACE,mBAAA;Cf2nDH;Ae5nDC;EACE,UAAA;Cf8nDH;Ae/nDC;EACE,mBAAA;CfioDH;AeloDC;EACE,kBAAA;CfooDH;AehoDC;EACE,WAAA;CfkoDH;AepnDC;EACE,kBAAA;CfsnDH;AevnDC;EACE,0BAAA;CfynDH;Ae1nDC;EACE,0BAAA;Cf4nDH;Ae7nDC;EACE,iBAAA;Cf+nDH;AehoDC;EACE,0BAAA;CfkoDH;AenoDC;EACE,0BAAA;CfqoDH;AetoDC;EACE,iBAAA;CfwoDH;AezoDC;EACE,0BAAA;Cf2oDH;Ae5oDC;EACE,0BAAA;Cf8oDH;Ae/oDC;EACE,iBAAA;CfipDH;AelpDC;EACE,0BAAA;CfopDH;AerpDC;EACE,yBAAA;CfupDH;AexpDC;EACE,gBAAA;Cf0pDH;Aa1pDD;EElCI;IACE,YAAA;Gf+rDH;EexrDD;IACE,YAAA;Gf0rDD;Ee3rDD;IACE,oBAAA;Gf6rDD;Ee9rDD;IACE,oBAAA;GfgsDD;EejsDD;IACE,WAAA;GfmsDD;EepsDD;IACE,oBAAA;GfssDD;EevsDD;IACE,oBAAA;GfysDD;Ee1sDD;IACE,WAAA;Gf4sDD;Ee7sDD;IACE,oBAAA;Gf+sDD;EehtDD;IACE,oBAAA;GfktDD;EentDD;IACE,WAAA;GfqtDD;EettDD;IACE,oBAAA;GfwtDD;EeztDD;IACE,mBAAA;Gf2tDD;Ee7sDD;IACE,YAAA;Gf+sDD;EehtDD;IACE,oBAAA;GfktDD;EentDD;IACE,oBAAA;GfqtDD;EettDD;IACE,WAAA;GfwtDD;EeztDD;IACE,oBAAA;Gf2tDD;Ee5tDD;IACE,oBAAA;Gf8tDD;Ee/tDD;IACE,WAAA;GfiuDD;EeluDD;IACE,oBAAA;GfouDD;EeruDD;IACE,oBAAA;GfuuDD;EexuDD;IACE,WAAA;Gf0uDD;Ee3uDD;IACE,oBAAA;Gf6uDD;Ee9uDD;IACE,mBAAA;GfgvDD;Ee5uDD;IACE,YAAA;Gf8uDD;Ee9vDD;IACE,WAAA;GfgwDD;EejwDD;IACE,mBAAA;GfmwDD;EepwDD;IACE,mBAAA;GfswDD;EevwDD;IACE,UAAA;GfywDD;Ee1wDD;IACE,mBAAA;Gf4wDD;Ee7wDD;IACE,mBAAA;Gf+wDD;EehxDD;IACE,UAAA;GfkxDD;EenxDD;IACE,mBAAA;GfqxDD;EetxDD;IACE,mBAAA;GfwxDD;EezxDD;IACE,UAAA;Gf2xDD;Ee5xDD;IACE,mBAAA;Gf8xDD;Ee/xDD;IACE,kBAAA;GfiyDD;Ee7xDD;IACE,WAAA;Gf+xDD;EejxDD;IACE,kBAAA;GfmxDD;EepxDD;IACE,0BAAA;GfsxDD;EevxDD;IACE,0BAAA;GfyxDD;Ee1xDD;IACE,iBAAA;Gf4xDD;Ee7xDD;IACE,0BAAA;Gf+xDD;EehyDD;IACE,0BAAA;GfkyDD;EenyDD;IACE,iBAAA;GfqyDD;EetyDD;IACE,0BAAA;GfwyDD;EezyDD;IACE,0BAAA;Gf2yDD;Ee5yDD;IACE,iBAAA;Gf8yDD;Ee/yDD;IACE,0BAAA;GfizDD;EelzDD;IACE,yBAAA;GfozDD;EerzDD;IACE,gBAAA;GfuzDD;CACF;Aa/yDD;EE3CI;IACE,YAAA;Gf61DH;Eet1DD;IACE,YAAA;Gfw1DD;Eez1DD;IACE,oBAAA;Gf21DD;Ee51DD;IACE,oBAAA;Gf81DD;Ee/1DD;IACE,WAAA;Gfi2DD;Eel2DD;IACE,oBAAA;Gfo2DD;Eer2DD;IACE,oBAAA;Gfu2DD;Eex2DD;IACE,WAAA;Gf02DD;Ee32DD;IACE,oBAAA;Gf62DD;Ee92DD;IACE,oBAAA;Gfg3DD;Eej3DD;IACE,WAAA;Gfm3DD;Eep3DD;IACE,oBAAA;Gfs3DD;Eev3DD;IACE,mBAAA;Gfy3DD;Ee32DD;IACE,YAAA;Gf62DD;Ee92DD;IACE,oBAAA;Gfg3DD;Eej3DD;IACE,oBAAA;Gfm3DD;Eep3DD;IACE,WAAA;Gfs3DD;Eev3DD;IACE,oBAAA;Gfy3DD;Ee13DD;IACE,oBAAA;Gf43DD;Ee73DD;IACE,WAAA;Gf+3DD;Eeh4DD;IACE,oBAAA;Gfk4DD;Een4DD;IACE,oBAAA;Gfq4DD;Eet4DD;IACE,WAAA;Gfw4DD;Eez4DD;IACE,oBAAA;Gf24DD;Ee54DD;IACE,mBAAA;Gf84DD;Ee14DD;IACE,YAAA;Gf44DD;Ee55DD;IACE,WAAA;Gf85DD;Ee/5DD;IACE,mBAAA;Gfi6DD;Eel6DD;IACE,mBAAA;Gfo6DD;Eer6DD;IACE,UAAA;Gfu6DD;Eex6DD;IACE,mBAAA;Gf06DD;Ee36DD;IACE,mBAAA;Gf66DD;Ee96DD;IACE,UAAA;Gfg7DD;Eej7DD;IACE,mBAAA;Gfm7DD;Eep7DD;IACE,mBAAA;Gfs7DD;Eev7DD;IACE,UAAA;Gfy7DD;Ee17DD;IACE,mBAAA;Gf47DD;Ee77DD;IACE,kBAAA;Gf+7DD;Ee37DD;IACE,WAAA;Gf67DD;Ee/6DD;IACE,kBAAA;Gfi7DD;Eel7DD;IACE,0BAAA;Gfo7DD;Eer7DD;IACE,0BAAA;Gfu7DD;Eex7DD;IACE,iBAAA;Gf07DD;Ee37DD;IACE,0BAAA;Gf67DD;Ee97DD;IACE,0BAAA;Gfg8DD;Eej8DD;IACE,iBAAA;Gfm8DD;Eep8DD;IACE,0BAAA;Gfs8DD;Eev8DD;IACE,0BAAA;Gfy8DD;Ee18DD;IACE,iBAAA;Gf48DD;Ee78DD;IACE,0BAAA;Gf+8DD;Eeh9DD;IACE,yBAAA;Gfk9DD;Een9DD;IACE,gBAAA;Gfq9DD;CACF;Aa18DD;EE9CI;IACE,YAAA;Gf2/DH;Eep/DD;IACE,YAAA;Gfs/DD;Eev/DD;IACE,oBAAA;Gfy/DD;Ee1/DD;IACE,oBAAA;Gf4/DD;Ee7/DD;IACE,WAAA;Gf+/DD;EehgED;IACE,oBAAA;GfkgED;EengED;IACE,oBAAA;GfqgED;EetgED;IACE,WAAA;GfwgED;EezgED;IACE,oBAAA;Gf2gED;Ee5gED;IACE,oBAAA;Gf8gED;Ee/gED;IACE,WAAA;GfihED;EelhED;IACE,oBAAA;GfohED;EerhED;IACE,mBAAA;GfuhED;EezgED;IACE,YAAA;Gf2gED;Ee5gED;IACE,oBAAA;Gf8gED;Ee/gED;IACE,oBAAA;GfihED;EelhED;IACE,WAAA;GfohED;EerhED;IACE,oBAAA;GfuhED;EexhED;IACE,oBAAA;Gf0hED;Ee3hED;IACE,WAAA;Gf6hED;Ee9hED;IACE,oBAAA;GfgiED;EejiED;IACE,oBAAA;GfmiED;EepiED;IACE,WAAA;GfsiED;EeviED;IACE,oBAAA;GfyiED;Ee1iED;IACE,mBAAA;Gf4iED;EexiED;IACE,YAAA;Gf0iED;Ee1jED;IACE,WAAA;Gf4jED;Ee7jED;IACE,mBAAA;Gf+jED;EehkED;IACE,mBAAA;GfkkED;EenkED;IACE,UAAA;GfqkED;EetkED;IACE,mBAAA;GfwkED;EezkED;IACE,mBAAA;Gf2kED;Ee5kED;IACE,UAAA;Gf8kED;Ee/kED;IACE,mBAAA;GfilED;EellED;IACE,mBAAA;GfolED;EerlED;IACE,UAAA;GfulED;EexlED;IACE,mBAAA;Gf0lED;Ee3lED;IACE,kBAAA;Gf6lED;EezlED;IACE,WAAA;Gf2lED;Ee7kED;IACE,kBAAA;Gf+kED;EehlED;IACE,0BAAA;GfklED;EenlED;IACE,0BAAA;GfqlED;EetlED;IACE,iBAAA;GfwlED;EezlED;IACE,0BAAA;Gf2lED;Ee5lED;IACE,0BAAA;Gf8lED;Ee/lED;IACE,iBAAA;GfimED;EelmED;IACE,0BAAA;GfomED;EermED;IACE,0BAAA;GfumED;EexmED;IACE,iBAAA;Gf0mED;Ee3mED;IACE,0BAAA;Gf6mED;Ee9mED;IACE,yBAAA;GfgnED;EejnED;IACE,gBAAA;GfmnED;CACF;AgBvrED;EACE,8BAAA;ChByrED;AgBvrED;EACE,iBAAA;EACA,oBAAA;EACA,eAAA;EACA,iBAAA;ChByrED;AgBvrED;EACE,iBAAA;ChByrED;AgBnrED;EACE,YAAA;EACA,gBA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","file":"bootstrap.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n border: 0;\n background-color: transparent;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n min-height: 34px;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #fff;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #fff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #ccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #fff;\n border: 1px solid #ddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #fff;\n border-color: #ddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #fff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #fff;\n line-height: 1;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n text-decoration: none;\n color: #555;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 12px;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 14px;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #fff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #fff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #fff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #fff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #fff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\002a\"; } }\n.glyphicon-plus { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // WebKit-specific. Other browsers will keep their default outline style.\n // (Initially tried to also force default via `outline: initial`,\n // but that seems to erroneously remove the outline in Firefox altogether.)\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @dl-horizontal-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: floor((@gutter / 2));\n padding-right: ceil((@gutter / 2));\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: ceil((@gutter / -2));\n margin-right: floor((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: ceil((@grid-gutter-width / 2));\n padding-right: floor((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius; // Note: This has no effect on s in CSS.\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Unstyle the caret on ``\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n display: inline-block;\n margin-bottom: 0; // For input.btn\n font-weight: @btn-font-weight;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n white-space: nowrap;\n .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base);\n .user-select(none);\n\n &,\n &:active,\n &.active {\n &:focus,\n &.focus {\n .tab-focus();\n }\n }\n\n &:hover,\n &:focus,\n &.focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n .opacity(.65);\n .box-shadow(none);\n }\n\n a& {\n &.disabled,\n fieldset[disabled] & {\n pointer-events: none; // Future-proof disabling of clicks on `` elements\n }\n }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n border-radius: 0;\n\n &,\n &:active,\n &.active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large);\n}\n.btn-sm {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n.btn-xs {\n .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 25%);\n }\n &:hover {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n\n &:hover,\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 17%);\n border-color: darken(@border, 25%);\n }\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus,\n &.focus {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n\n &.in { display: block; }\n tr&.in { display: table-row; }\n tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition-property(~\"height, visibility\");\n .transition-duration(.35s);\n .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base dashed;\n border-top: @caret-width-base solid ~\"\\9\"; // IE8\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropup,\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n //\n // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n\n // Nuke hover/focus effects\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: @cursor-disabled;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n left: auto; // Reset the default from `.dropdown-menu`\n right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n border-top: 0;\n border-bottom: @caret-width-base dashed;\n border-bottom: @caret-width-base solid ~\"\\9\"; // IE8\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .dropdown-menu-right();\n }\n // Necessary for overrides of the default right aligned menu.\n // Will remove come v4 in all likelihood.\n .dropdown-menu-left {\n .dropdown-menu-left();\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n margin-left: -5px; // Offset the first child's margin\n &:extend(.clearfix all);\n\n .btn,\n .btn-group,\n .input-group {\n float: left;\n }\n > .btn,\n > .btn-group,\n > .input-group {\n margin-left: 5px;\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n .box-shadow(none);\n }\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group,\n > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n &:extend(.clearfix all);\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n .border-top-radius(@btn-border-radius-base);\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n .border-top-radius(0);\n .border-bottom-radius(@btn-border-radius-base);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n > .btn,\n > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n }\n > .btn-group .btn {\n width: 100%;\n }\n\n > .btn-group .dropdown-menu {\n left: auto;\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n > .btn,\n > .btn-group > .btn {\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0,0,0,0);\n pointer-events: none;\n }\n }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n // Ensure that the input is always above the *appended* addon button for\n // proper border colors.\n position: relative;\n z-index: 2;\n\n // IE9 fubars the placeholder attribute in text inputs and the arrows on\n // select elements in input groups. To fix it, we float the input. Details:\n // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n float: left;\n\n width: 100%;\n margin-bottom: 0;\n\n &:focus {\n z-index: 3;\n }\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n color: @input-color;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @input-border-radius;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @input-border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @input-border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n // Jankily prevent input button groups from wrapping with `white-space` and\n // `font-size` in combination with `inline-block` on buttons.\n font-size: 0;\n white-space: nowrap;\n\n // Negative margin for spacing, position for bringing hovered/focused/actived\n // element above the siblings.\n > .btn {\n position: relative;\n + .btn {\n margin-left: -1px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active {\n z-index: 2;\n }\n }\n\n // Negative margin to only have a 1px border between the two\n &:first-child {\n > .btn,\n > .btn-group {\n margin-right: -1px;\n }\n }\n &:last-child {\n > .btn,\n > .btn-group {\n z-index: 2;\n margin-left: -1px;\n }\n }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n margin-bottom: 0;\n padding-left: 0; // Override default ul/ol\n list-style: none;\n &:extend(.clearfix all);\n\n > li {\n position: relative;\n display: block;\n\n > a {\n position: relative;\n display: block;\n padding: @nav-link-padding;\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @nav-link-hover-bg;\n }\n }\n\n // Disabled state sets text to gray and nukes hover/tab effects\n &.disabled > a {\n color: @nav-disabled-link-color;\n\n &:hover,\n &:focus {\n color: @nav-disabled-link-hover-color;\n text-decoration: none;\n background-color: transparent;\n cursor: @cursor-disabled;\n }\n }\n }\n\n // Open dropdowns\n .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @nav-link-hover-bg;\n border-color: @link-color;\n }\n }\n\n // Nav dividers (deprecated with v3.0.1)\n //\n // This should have been removed in v3 with the dropping of `.nav-list`, but\n // we missed it. We don't currently support this anywhere, but in the interest\n // of maintaining backward compatibility in case you use it, it's deprecated.\n .nav-divider {\n .nav-divider();\n }\n\n // Prevent IE8 from misplacing imgs\n //\n // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n > li > a > img {\n max-width: none;\n }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n border-bottom: 1px solid @nav-tabs-border-color;\n > li {\n float: left;\n // Make the list-items overlay the bottom border\n margin-bottom: -1px;\n\n // Actual tabs (as links)\n > a {\n margin-right: 2px;\n line-height: @line-height-base;\n border: 1px solid transparent;\n border-radius: @border-radius-base @border-radius-base 0 0;\n &:hover {\n border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n }\n }\n\n // Active state, and its :hover to override normal :hover\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-tabs-active-link-hover-color;\n background-color: @nav-tabs-active-link-hover-bg;\n border: 1px solid @nav-tabs-active-link-hover-border-color;\n border-bottom-color: transparent;\n cursor: default;\n }\n }\n }\n // pulling this in mainly for less shorthand\n &.nav-justified {\n .nav-justified();\n .nav-tabs-justified();\n }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n > li {\n float: left;\n\n // Links rendered as pills\n > a {\n border-radius: @nav-pills-border-radius;\n }\n + li {\n margin-left: 2px;\n }\n\n // Active state\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-pills-active-link-hover-color;\n background-color: @nav-pills-active-link-hover-bg;\n }\n }\n }\n}\n\n\n// Stacked pills\n.nav-stacked {\n > li {\n float: none;\n + li {\n margin-top: 2px;\n margin-left: 0; // no need for this gap between nav items\n }\n }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n width: 100%;\n\n > li {\n float: none;\n > a {\n text-align: center;\n margin-bottom: 5px;\n }\n }\n\n > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n }\n\n @media (min-width: @screen-sm-min) {\n > li {\n display: table-cell;\n width: 1%;\n > a {\n margin-bottom: 0;\n }\n }\n }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n border-bottom: 0;\n\n > li > a {\n // Override margin from .nav-tabs\n margin-right: 0;\n border-radius: @border-radius-base;\n }\n\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border: 1px solid @nav-tabs-justified-link-border-color;\n }\n\n @media (min-width: @screen-sm-min) {\n > li > a {\n border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n border-radius: @border-radius-base @border-radius-base 0 0;\n }\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border-bottom-color: @nav-tabs-justified-active-link-border-color;\n }\n }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n // make dropdown border overlap tab border\n margin-top: -1px;\n // Remove the top rounded corners here since there is a hard edge above the menu\n .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n margin-bottom: @navbar-margin-bottom;\n border: 1px solid transparent;\n\n // Prevent floats from breaking the navbar\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: @navbar-border-radius;\n }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n overflow-x: visible;\n padding-right: @navbar-padding-horizontal;\n padding-left: @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n &:extend(.clearfix all);\n -webkit-overflow-scrolling: touch;\n\n &.in {\n overflow-y: auto;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border-top: 0;\n box-shadow: none;\n\n &.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0; // Override default setting\n overflow: visible !important;\n }\n\n &.in {\n overflow-y: visible;\n }\n\n // Undo the collapse side padding for navbars with containers to ensure\n // alignment of right-aligned contents.\n .navbar-fixed-top &,\n .navbar-static-top &,\n .navbar-fixed-bottom & {\n padding-left: 0;\n padding-right: 0;\n }\n }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n .navbar-collapse {\n max-height: @navbar-collapse-max-height;\n\n @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n max-height: 200px;\n }\n }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n > .navbar-header,\n > .navbar-collapse {\n margin-right: -@navbar-padding-horizontal;\n margin-left: -@navbar-padding-horizontal;\n\n @media (min-width: @grid-float-breakpoint) {\n margin-right: 0;\n margin-left: 0;\n }\n }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n z-index: @zindex-navbar;\n border-width: 0 0 1px;\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: @zindex-navbar-fixed;\n\n // Undo the rounded corners\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0; // override .navbar defaults\n border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n float: left;\n padding: @navbar-padding-vertical @navbar-padding-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-computed;\n height: @navbar-height;\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n\n > img {\n display: block;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n .navbar > .container &,\n .navbar > .container-fluid & {\n margin-left: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: @navbar-padding-horizontal;\n padding: 9px 10px;\n .navbar-vertical-align(34px);\n background-color: transparent;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n\n // We remove the `outline` here, but later compensate by attaching `:hover`\n // styles to `:focus`.\n &:focus {\n outline: 0;\n }\n\n // Bars\n .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n }\n .icon-bar + .icon-bar {\n margin-top: 4px;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n display: none;\n }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: @line-height-computed;\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n > li > a,\n .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n > li > a {\n line-height: @line-height-computed;\n &:hover,\n &:focus {\n background-image: none;\n }\n }\n }\n }\n\n // Uncollapse the nav\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin: 0;\n\n > li {\n float: left;\n > a {\n padding-top: @navbar-padding-vertical;\n padding-bottom: @navbar-padding-vertical;\n }\n }\n }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n margin-left: -@navbar-padding-horizontal;\n margin-right: -@navbar-padding-horizontal;\n padding: 10px @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n\n // Mixin behavior for optimum display\n .form-inline();\n\n .form-group {\n @media (max-width: @grid-float-breakpoint-max) {\n margin-bottom: 5px;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n }\n\n // Vertically center in expanded, horizontal navbar\n .navbar-vertical-align(@input-height-base);\n\n // Undo 100% width for pull classes\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n .box-shadow(none);\n }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n .border-top-radius(@navbar-border-radius);\n .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n .navbar-vertical-align(@input-height-base);\n\n &.btn-sm {\n .navbar-vertical-align(@input-height-small);\n }\n &.btn-xs {\n .navbar-vertical-align(22);\n }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n .navbar-vertical-align(@line-height-computed);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin-left: @navbar-padding-horizontal;\n margin-right: @navbar-padding-horizontal;\n }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-left { .pull-left(); }\n .navbar-right {\n .pull-right();\n margin-right: -@navbar-padding-horizontal;\n\n ~ .navbar-right {\n margin-right: 0;\n }\n }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n background-color: @navbar-default-bg;\n border-color: @navbar-default-border;\n\n .navbar-brand {\n color: @navbar-default-brand-color;\n &:hover,\n &:focus {\n color: @navbar-default-brand-hover-color;\n background-color: @navbar-default-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-default-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-default-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n\n .navbar-toggle {\n border-color: @navbar-default-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-default-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-default-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: @navbar-default-border;\n }\n\n // Dropdown menu items\n .navbar-nav {\n // Remove background color from open dropdown\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-default-link-active-bg;\n color: @navbar-default-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n > li > a {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n }\n }\n\n\n // Links in navbars\n //\n // Add a class to ensure links outside the navbar nav are colored correctly.\n\n .navbar-link {\n color: @navbar-default-link-color;\n &:hover {\n color: @navbar-default-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n }\n }\n }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n background-color: @navbar-inverse-bg;\n border-color: @navbar-inverse-border;\n\n .navbar-brand {\n color: @navbar-inverse-brand-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-brand-hover-color;\n background-color: @navbar-inverse-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-inverse-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-inverse-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n\n // Darken the responsive nav toggle\n .navbar-toggle {\n border-color: @navbar-inverse-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-inverse-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-inverse-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: darken(@navbar-inverse-bg, 7%);\n }\n\n // Dropdowns\n .navbar-nav {\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-inverse-link-active-bg;\n color: @navbar-inverse-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display\n .open .dropdown-menu {\n > .dropdown-header {\n border-color: @navbar-inverse-border;\n }\n .divider {\n background-color: @navbar-inverse-border;\n }\n > li > a {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n }\n }\n\n .navbar-link {\n color: @navbar-inverse-link-color;\n &:hover {\n color: @navbar-inverse-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n }\n }\n }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n .clearfix();\n}\n.center-block {\n .center-block();\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n display: none !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n\n > li {\n display: inline-block;\n\n + li:before {\n content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: @line-height-computed 0;\n border-radius: @border-radius-base;\n\n > li {\n display: inline; // Remove list-style and block-level defaults\n > a,\n > span {\n position: relative;\n float: left; // Collapse white-space\n padding: @padding-base-vertical @padding-base-horizontal;\n line-height: @line-height-base;\n text-decoration: none;\n color: @pagination-color;\n background-color: @pagination-bg;\n border: 1px solid @pagination-border;\n margin-left: -1px;\n }\n &:first-child {\n > a,\n > span {\n margin-left: 0;\n .border-left-radius(@border-radius-base);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius-base);\n }\n }\n }\n\n > li > a,\n > li > span {\n &:hover,\n &:focus {\n z-index: 2;\n color: @pagination-hover-color;\n background-color: @pagination-hover-bg;\n border-color: @pagination-hover-border;\n }\n }\n\n > .active > a,\n > .active > span {\n &,\n &:hover,\n &:focus {\n z-index: 3;\n color: @pagination-active-color;\n background-color: @pagination-active-bg;\n border-color: @pagination-active-border;\n cursor: default;\n }\n }\n\n > .disabled {\n > span,\n > span:hover,\n > span:focus,\n > a,\n > a:hover,\n > a:focus {\n color: @pagination-disabled-color;\n background-color: @pagination-disabled-bg;\n border-color: @pagination-disabled-border;\n cursor: @cursor-disabled;\n }\n }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @line-height-computed 0;\n list-style: none;\n text-align: center;\n &:extend(.clearfix all);\n li {\n display: inline;\n > a,\n > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: @pager-bg;\n border: 1px solid @pager-border;\n border-radius: @pager-border-radius;\n }\n\n > a:hover,\n > a:focus {\n text-decoration: none;\n background-color: @pager-hover-bg;\n }\n }\n\n .next {\n > a,\n > span {\n float: right;\n }\n }\n\n .previous {\n > a,\n > span {\n float: left;\n }\n }\n\n .disabled {\n > a,\n > a:hover,\n > a:focus,\n > span {\n color: @pager-disabled-color;\n background-color: @pager-bg;\n cursor: @cursor-disabled;\n }\n }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n a& {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for labels in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n background-color: @color;\n\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for badges in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n\n .btn-xs &,\n .btn-group-xs > .btn & {\n top: 0;\n padding: 1px 5px;\n }\n\n // Hover state, but only for links\n a& {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Account for badges in navs\n .list-group-item.active > &,\n .nav-pills > .active > a > & {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n }\n\n .list-group-item > & {\n float: right;\n }\n\n .list-group-item > & + & {\n margin-right: 5px;\n }\n\n .nav-pills > li > a > & {\n margin-left: 3px;\n }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding-top: @jumbotron-padding;\n padding-bottom: @jumbotron-padding;\n margin-bottom: @jumbotron-padding;\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1,\n .h1 {\n color: @jumbotron-heading-color;\n }\n\n p {\n margin-bottom: (@jumbotron-padding / 2);\n font-size: @jumbotron-font-size;\n font-weight: 200;\n }\n\n > hr {\n border-top-color: darken(@jumbotron-bg, 10%);\n }\n\n .container &,\n .container-fluid & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n\n .container {\n max-width: 100%;\n }\n\n @media screen and (min-width: @screen-sm-min) {\n padding-top: (@jumbotron-padding * 1.6);\n padding-bottom: (@jumbotron-padding * 1.6);\n\n .container &,\n .container-fluid & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1,\n .h1 {\n font-size: @jumbotron-heading-font-size;\n }\n }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n display: block;\n padding: @thumbnail-padding;\n margin-bottom: @line-height-computed;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(border .2s ease-in-out);\n\n > img,\n a > img {\n &:extend(.img-responsive);\n margin-left: auto;\n margin-right: auto;\n }\n\n // Add a hover state for linked versions only\n a&:hover,\n a&:focus,\n a&.active {\n border-color: @link-color;\n }\n\n // Image captions\n .caption {\n padding: @thumbnail-caption-padding;\n color: @thumbnail-caption-color;\n }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headings-color\n color: inherit;\n }\n\n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n\n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n overflow: hidden;\n height: @line-height-computed;\n margin-bottom: @line-height-computed;\n background-color: @progress-bg;\n border-radius: @progress-border-radius;\n .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: @font-size-small;\n line-height: @line-height-computed;\n color: @progress-bar-color;\n text-align: center;\n background-color: @progress-bar-bg;\n .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n #gradient > .striped();\n background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n background-color: @color;\n\n // Deprecated parent class requirement as of v3.2.0\n .progress-striped & {\n #gradient > .striped();\n }\n}\n",".media {\n // Proper spacing between instances of .media\n margin-top: 15px;\n\n &:first-child {\n margin-top: 0;\n }\n}\n\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n\n.media-body {\n width: 10000px;\n}\n\n.media-object {\n display: block;\n\n // Fix collapse in webkit from max-width: 100% and display: table-cell.\n &.img-thumbnail {\n max-width: none;\n }\n}\n\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n\n.media-middle {\n vertical-align: middle;\n}\n\n.media-bottom {\n vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on