commit 45338b40cd98e4199aa0abd01ad6992d3c33eb6f
Author: chinosk <2248589280@qq.com>
Date: Mon Mar 17 21:53:55 2025 +0000
初始适配
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..504e4fd
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,159 @@
+### Windows
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msm
+*.msp
+
+# Shortcuts
+*.lnk
+
+### OSX
+
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear on external disk
+.Spotlight-V100
+.Trashes
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### Visual Studio
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+build
+
+# Visual Studio 2015 cache/options directory
+.vs/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+### IDA
+*.id0
+*.id1
+*.id2
+*.nam
+*.til
+
+### Custom user files
+# User scripts
+user*.bat
+
+# Premake binary
+#premake5.exe
+
+# text_dumper tmp files
+resources/text_dumper/obj
+resources/text_dumper/bin
+
+.cache/
+.vscode/
+/backend
+/utils/events.br
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..26f1d42
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "deps/minhook"]
+ path = deps/minhook
+ url = https://github.com/TsudaKageyu/minhook.git
+[submodule "deps/rapidjson"]
+ path = deps/rapidjson
+ url = https://github.com/Tencent/rapidjson.git
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f288702
--- /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
+.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e980ef6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# gkms-localify-dmm
+- Gakumas Localify DMM Version
diff --git a/conanfile.txt b/conanfile.txt
new file mode 100644
index 0000000..6a91ebe
--- /dev/null
+++ b/conanfile.txt
@@ -0,0 +1,11 @@
+[requires]
+cpprestsdk/2.10.18
+minizip/1.2.11
+zlib/1.2.12
+msgpack/3.3.0
+sqlite3/3.39.2
+nlohmann_json/3.11.2
+fmt/11.0.2
+
+[generators]
+premake
diff --git a/deps/minhook.lua b/deps/minhook.lua
new file mode 100644
index 0000000..396d4d3
--- /dev/null
+++ b/deps/minhook.lua
@@ -0,0 +1,31 @@
+minhook = {
+ source = path.join(dependencies.basePath, "minhook"),
+}
+
+function minhook.import()
+ links { "minhook" }
+ minhook.includes()
+end
+
+function minhook.includes()
+ includedirs {
+ path.join(minhook.source, "include")
+ }
+end
+
+function minhook.project()
+ project "minhook"
+ language "C"
+
+ minhook.includes()
+
+ files {
+ path.join(minhook.source, "src/**.h"),
+ path.join(minhook.source, "src/**.c"),
+ }
+
+ warnings "Off"
+ kind "StaticLib"
+end
+
+table.insert(dependencies, minhook)
diff --git a/deps/minhook/.editorconfig b/deps/minhook/.editorconfig
new file mode 100644
index 0000000..36c09e6
--- /dev/null
+++ b/deps/minhook/.editorconfig
@@ -0,0 +1,22 @@
+# EditorConfig is awesome: http://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Windows-style newlines with a newline ending every file
+[*]
+end_of_line = crlf
+insert_final_newline = true
+
+# 4 space indentation
+[*.{c,h,def}]
+indent_style = space
+indent_size = 4
+
+# Trim trailing whitespaces
+[*.{c,h,def,txt}]
+trim_trailing_whitespace = true
+
+# UTF-8 with BOM
+[*.{c,h,def,txt}]
+charset=utf-8-bom
diff --git a/deps/minhook/.gitignore b/deps/minhook/.gitignore
new file mode 100644
index 0000000..ad165d5
--- /dev/null
+++ b/deps/minhook/.gitignore
@@ -0,0 +1,44 @@
+#OS junk files
+[Tt]humbs.db
+*.DS_Store
+
+#Visual Studio files
+*.[Oo]bj
+*.user
+*.aps
+*.pch
+*.vspscc
+*.vssscc
+*_i.c
+*_p.c
+*.ncb
+*.suo
+*.tlb
+*.tlh
+*.bak
+*.[Cc]ache
+*.ilk
+*.log
+*.sbr
+*.sdf
+*.opensdf
+*.unsuccessfulbuild
+ipch/
+obj/
+[Ll]ib
+[Bb]in
+[Dd]ebug*/
+[Rr]elease*/
+Ankh.NoLoad
+*.VC.db
+.vs/
+
+#GCC files
+*.o
+*.d
+*.res
+*.dll
+*.a
+
+#Visual Studio Code files
+.vscode/
diff --git a/deps/minhook/AUTHORS.txt b/deps/minhook/AUTHORS.txt
new file mode 100644
index 0000000..ebef1a6
--- /dev/null
+++ b/deps/minhook/AUTHORS.txt
@@ -0,0 +1,8 @@
+Tsuda Kageyu
+ Creator, maintainer
+
+Michael Maltsev
+ Added "Queue" functions. A lot of bug fixes.
+
+Andrey Unis
+ Rewrote the hook engine in plain C.
diff --git a/deps/minhook/CMakeLists.txt b/deps/minhook/CMakeLists.txt
new file mode 100644
index 0000000..df947af
--- /dev/null
+++ b/deps/minhook/CMakeLists.txt
@@ -0,0 +1,141 @@
+# MinHook - The Minimalistic API Hooking Library for x64/x86
+# Copyright (C) 2009-2017 Tsuda Kageyu.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 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.
+
+cmake_minimum_required(VERSION 3.0)
+
+project(minhook LANGUAGES C)
+
+include(CMakePackageConfigHelpers)
+
+set(MINHOOK_MAJOR_VERSION 1)
+set(MINHOOK_MINOR_VERSION 3)
+set(MINHOOK_PATCH_VERSION 3)
+set(MINHOOK_VERSION ${MINHOOK_MAJOR_VERSION}.${MINHOOK_MINOR_VERSION}.${MINHOOK_PATCH_VERSION})
+
+################
+# BUILD #
+################
+
+option(BUILD_SHARED_LIBS "build shared version" OFF)
+
+set(SOURCES_MINHOOK
+ "src/buffer.c"
+ "src/hook.c"
+ "src/trampoline.c"
+)
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(SOURCES_HDE "src/hde/hde64.c")
+else()
+ set(SOURCES_HDE "src/hde/hde32.c")
+endif()
+
+if(BUILD_SHARED_LIBS)
+ set(RESOURCES
+ "dll_resources/minhook.rc"
+ "dll_resources/minhook.def"
+ )
+endif()
+
+add_library(minhook ${SOURCES_MINHOOK} ${SOURCES_HDE} ${RESOURCES})
+
+target_include_directories(minhook PUBLIC
+ $
+ $
+)
+
+target_include_directories(minhook PRIVATE "src/")
+target_include_directories(minhook PRIVATE "src/hde/")
+
+if(WIN32)
+ set_target_properties(minhook PROPERTIES PREFIX "")
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set_target_properties(minhook PROPERTIES DEBUG_POSTFIX ".x64d")
+ set_target_properties(minhook PROPERTIES RELEASE_POSTFIX ".x64")
+ set_target_properties(minhook PROPERTIES RELWITHDEBINFO_POSTFIX ".x64")
+ set_target_properties(minhook PROPERTIES MINSIZEREL_POSTFIX ".x64")
+ else()
+ set_target_properties(minhook PROPERTIES DEBUG_POSTFIX ".x32d")
+ set_target_properties(minhook PROPERTIES RELEASE_POSTFIX ".x32")
+ set_target_properties(minhook PROPERTIES RELWITHDEBINFO_POSTFIX ".x32")
+ set_target_properties(minhook PROPERTIES MINSIZEREL_POSTFIX ".x64")
+ endif()
+else()
+ set_target_properties(minhook PROPERTIES PREFIX "lib")
+ set_target_properties(minhook PROPERTIES POSTFIX "")
+ set_target_properties(minhook PROPERTIES DEBUG_POSTFIX "d")
+endif()
+
+################
+# CMAKE CONFIG #
+################
+
+configure_package_config_file(
+ "cmake/minhook-config.cmake.in"
+ "minhook-config.cmake"
+ INSTALL_DESTINATION
+ "lib/minhook"
+)
+
+write_basic_package_version_file(
+ "minhook-config-version.cmake"
+VERSION
+ ${MINHOOK_VERSION}
+COMPATIBILITY
+ AnyNewerVersion
+)
+
+install(
+ FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/minhook-config.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/minhook-config-version.cmake"
+ DESTINATION
+ "lib/minhook"
+)
+
+###################
+# INSTALL #
+###################
+
+install(TARGETS minhook
+ EXPORT minhook-targets
+ RUNTIME DESTINATION "bin"
+ ARCHIVE DESTINATION "lib"
+ LIBRARY DESTINATION "lib"
+)
+
+install(
+ EXPORT
+ minhook-targets
+ NAMESPACE
+ minhook::
+ DESTINATION
+ "lib/minhook"
+)
+
+install(
+ DIRECTORY include DESTINATION .
+)
diff --git a/deps/minhook/LICENSE.txt b/deps/minhook/LICENSE.txt
new file mode 100644
index 0000000..74dea27
--- /dev/null
+++ b/deps/minhook/LICENSE.txt
@@ -0,0 +1,81 @@
+MinHook - The Minimalistic API Hooking Library for x64/x86
+Copyright (C) 2009-2017 Tsuda Kageyu.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+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.
+
+================================================================================
+Portions of this software are Copyright (c) 2008-2009, Vyacheslav Patkov.
+================================================================================
+Hacker Disassembler Engine 32 C
+Copyright (c) 2008-2009, Vyacheslav Patkov.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+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 REGENTS 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.
+
+-------------------------------------------------------------------------------
+Hacker Disassembler Engine 64 C
+Copyright (c) 2008-2009, Vyacheslav Patkov.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+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 REGENTS 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/deps/minhook/README.md b/deps/minhook/README.md
new file mode 100644
index 0000000..21cc7d5
--- /dev/null
+++ b/deps/minhook/README.md
@@ -0,0 +1,87 @@
+# MinHook
+
+[](https://opensource.org/licenses/BSD-2-Clause)
+
+The Minimalistic x86/x64 API Hooking Library for Windows
+
+http://www.codeproject.com/KB/winsdk/LibMinHook.aspx
+
+### Version history
+
+- **v1.3.3 - 8 Jan 2017**
+ * Added a helper function ```MH_CreateHookApiEx```. (Thanks to asm256)
+ * Support Visual Studio 2017 RC.
+
+- **v1.3.2.1 - 9 Nov 2015** (Nuget package only)
+ * Fixed an insufficient support for Visual Studio 2015.
+
+- **v1.3.2 - 1 Nov 2015**
+ * Support Visual Studio 2015.
+ * Support MinGW.
+
+- **v1.3.2-beta3 - 21 Jul 2015** (Nuget package only)
+ * Support MinGW. (Experimental)
+
+- **v1.3.2-beta2 - 18 May 2015**
+ * Fixed some subtle bugs. (Thanks to RaMMicHaeL)
+ * Added a helper function ```MH_StatusToString```. (Thanks to Jan Klass)
+
+- **v1.3.2-beta - 12 May 2015**
+ * Fixed a possible thread deadlock in x64 mode. (Thanks to Aleh Kazakevich)
+ * Reduced the footprint a little more.
+ * Support Visual Studio 2015 RC. (Experimental)
+
+- **v1.3.1.1 - 7 Apr 2015** (Nuget package only)
+ * Support for WDK8.0 and 8.1.
+
+- **v1.3.1 - 19 Mar 2015**
+ * No major changes from v1.3.1-beta.
+
+- **v1.3.1-beta - 11 Mar 2015**
+ * Added a helper function ```MH_CreateHookApi```. (Thanks to uniskz).
+ * Fixed a false memory leak reported by some tools.
+ * Fixed a degradated compatibility issue.
+
+- **v1.3 - 13 Sep 2014**
+ * No major changes from v1.3-beta3.
+
+- **v1.3-beta3 - 31 Jul 2014**
+ * Fixed some small bugs.
+ * Improved the memory management.
+
+- **v1.3-beta2 - 21 Jul 2014**
+ * Changed the parameters to Windows-friendly types. (void* to LPVOID)
+ * Fixed some small bugs.
+ * Reorganized the source files.
+ * Reduced the footprint a little more.
+
+- **v1.3-beta - 17 Jul 2014**
+ * Rewrote in plain C to reduce the footprint and memory usage. (suggested by Andrey Unis)
+ * Simplified the overall code base to make it more readable and maintainable.
+ * Changed the license from 3-clause to 2-clause BSD License.
+
+- **v1.2 - 28 Sep 2013**
+ * Removed boost dependency ([jarredholman](https://github.com/jarredholman/minhook)).
+ * Fixed a small bug in the GetRelativeBranchDestination function ([pillbug99](http://www.codeproject.com/Messages/4058892/Small-Bug-Found.aspx)).
+ * Added the ```MH_RemoveHook``` function, which removes a hook created with the ```MH_CreateHook``` function.
+ * Added the following functions to enable or disable multiple hooks in one go: ```MH_QueueEnableHook```, ```MH_QueueDisableHook```, ```MH_ApplyQueued```. This is the preferred way of handling multiple hooks as every call to `MH_EnableHook` or `MH_DisableHook` suspends and resumes all threads.
+ * Made the functions ```MH_EnableHook``` and ```MH_DisableHook``` enable/disable all created hooks when the ```MH_ALL_HOOKS``` parameter is passed. This, too, is an efficient way of handling multiple hooks.
+ * If the target function is too small to be patched with a jump, MinHook tries to place the jump above the function. If that fails as well, the ```MH_CreateHook``` function returns ```MH_ERROR_UNSUPPORTED_FUNCTION```. This fixes an issue of hooking the LoadLibraryExW function on Windows 7 x64 ([reported by Obble](http://www.codeproject.com/Messages/4578613/Re-Bug-LoadLibraryExW-hook-fails-on-windows-2008-r.aspx)).
+
+- **v1.1 - 26 Nov 2009**
+ * Changed the interface to create a hook and a trampoline function in one go to prevent the detour function from being called before the trampoline function is created. ([reported by xliqz](http://www.codeproject.com/Messages/3280374/Unsafe.aspx))
+ * Shortened the function names from ```MinHook_*``` to ```MH_*``` to make them handier.
+
+- **v1.0 - 22 Nov 2009**
+ * Initial release.
+
+### Building MinHook - Using vcpkg
+
+You can download and install MinHook using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
+
+ git clone https://github.com/microsoft/vcpkg
+ .\vcpkg\bootstrap-vcpkg.bat
+ .\vcpkg\vcpkg integrate install
+ .\vcpkg\vcpkg install minhook
+
+The MinHook port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
diff --git a/deps/minhook/cmake/minhook-config.cmake.in b/deps/minhook/cmake/minhook-config.cmake.in
new file mode 100644
index 0000000..14e6463
--- /dev/null
+++ b/deps/minhook/cmake/minhook-config.cmake.in
@@ -0,0 +1,39 @@
+# MinHook - The Minimalistic API Hooking Library for x64/x86
+# Copyright (C) 2009-2017 Tsuda Kageyu.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 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.
+
+set(MINHOOK_MAJOR_VERSION "@MINHOOK_MAJOR_VERSION@")
+set(MINHOOK_MINOR_VERSION "@MINHOOK_MINOR_VERSION@")
+set(MINHOOK_PATCH_VERSION "@MINHOOK_PATCH_VERSION@")
+set(MINHOOK_VERSION "@MINHOOK_VERSION@")
+
+@PACKAGE_INIT@
+
+set(MINHOOK_FOUND ON)
+
+set_and_check(MINHOOK_INCLUDE_DIRS "${PACKAGE_PREFIX_DIR}/include/")
+set_and_check(MINHOOK_LIBRARY_DIRS "${PACKAGE_PREFIX_DIR}/lib")
+
+include("${PACKAGE_PREFIX_DIR}/lib/minhook/minhook-targets.cmake")
diff --git a/deps/minhook/dll_resources/MinHook.def b/deps/minhook/dll_resources/MinHook.def
new file mode 100644
index 0000000..c6af698
--- /dev/null
+++ b/deps/minhook/dll_resources/MinHook.def
@@ -0,0 +1,14 @@
+EXPORTS
+ MH_Initialize
+ MH_Uninitialize
+
+ MH_CreateHook
+ MH_CreateHookApi
+ MH_CreateHookApiEx
+ MH_RemoveHook
+ MH_EnableHook
+ MH_DisableHook
+ MH_QueueEnableHook
+ MH_QueueDisableHook
+ MH_ApplyQueued
+ MH_StatusToString
diff --git a/deps/minhook/dll_resources/MinHook.rc b/deps/minhook/dll_resources/MinHook.rc
new file mode 100644
index 0000000..7cbacb7
--- /dev/null
+++ b/deps/minhook/dll_resources/MinHook.rc
@@ -0,0 +1,32 @@
+1 VERSIONINFO
+ FILEVERSION 1,3,3,0
+ PRODUCTVERSION 1,3,3,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Tsuda Kageyu"
+ VALUE "FileDescription", "MinHook - The Minimalistic API Hook Library for x64/x86"
+ VALUE "FileVersion", "1.3.3.0"
+ VALUE "InternalName", "MinHookD"
+ VALUE "LegalCopyright", "Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved."
+ VALUE "LegalTrademarks", "Tsuda Kageyu"
+ VALUE "ProductName", "MinHook DLL"
+ VALUE "ProductVersion", "1.3.3.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/deps/minhook/include/MinHook.h b/deps/minhook/include/MinHook.h
new file mode 100644
index 0000000..492d83f
--- /dev/null
+++ b/deps/minhook/include/MinHook.h
@@ -0,0 +1,185 @@
+/*
+ * MinHook - The Minimalistic API Hooking Library for x64/x86
+ * Copyright (C) 2009-2017 Tsuda Kageyu.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#pragma once
+
+#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__)
+ #error MinHook supports only x86 and x64 systems.
+#endif
+
+#include
+
+// MinHook Error Codes.
+typedef enum MH_STATUS
+{
+ // Unknown error. Should not be returned.
+ MH_UNKNOWN = -1,
+
+ // Successful.
+ MH_OK = 0,
+
+ // MinHook is already initialized.
+ MH_ERROR_ALREADY_INITIALIZED,
+
+ // MinHook is not initialized yet, or already uninitialized.
+ MH_ERROR_NOT_INITIALIZED,
+
+ // The hook for the specified target function is already created.
+ MH_ERROR_ALREADY_CREATED,
+
+ // The hook for the specified target function is not created yet.
+ MH_ERROR_NOT_CREATED,
+
+ // The hook for the specified target function is already enabled.
+ MH_ERROR_ENABLED,
+
+ // The hook for the specified target function is not enabled yet, or already
+ // disabled.
+ MH_ERROR_DISABLED,
+
+ // The specified pointer is invalid. It points the address of non-allocated
+ // and/or non-executable region.
+ MH_ERROR_NOT_EXECUTABLE,
+
+ // The specified target function cannot be hooked.
+ MH_ERROR_UNSUPPORTED_FUNCTION,
+
+ // Failed to allocate memory.
+ MH_ERROR_MEMORY_ALLOC,
+
+ // Failed to change the memory protection.
+ MH_ERROR_MEMORY_PROTECT,
+
+ // The specified module is not loaded.
+ MH_ERROR_MODULE_NOT_FOUND,
+
+ // The specified function is not found.
+ MH_ERROR_FUNCTION_NOT_FOUND
+}
+MH_STATUS;
+
+// Can be passed as a parameter to MH_EnableHook, MH_DisableHook,
+// MH_QueueEnableHook or MH_QueueDisableHook.
+#define MH_ALL_HOOKS NULL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ // Initialize the MinHook library. You must call this function EXACTLY ONCE
+ // at the beginning of your program.
+ MH_STATUS WINAPI MH_Initialize(VOID);
+
+ // Uninitialize the MinHook library. You must call this function EXACTLY
+ // ONCE at the end of your program.
+ MH_STATUS WINAPI MH_Uninitialize(VOID);
+
+ // Creates a hook for the specified target function, in disabled state.
+ // Parameters:
+ // pTarget [in] A pointer to the target function, which will be
+ // overridden by the detour function.
+ // pDetour [in] A pointer to the detour function, which will override
+ // the target function.
+ // ppOriginal [out] A pointer to the trampoline function, which will be
+ // used to call the original target function.
+ // This parameter can be NULL.
+ MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal);
+
+ // Creates a hook for the specified API function, in disabled state.
+ // Parameters:
+ // pszModule [in] A pointer to the loaded module name which contains the
+ // target function.
+ // pszProcName [in] A pointer to the target function name, which will be
+ // overridden by the detour function.
+ // pDetour [in] A pointer to the detour function, which will override
+ // the target function.
+ // ppOriginal [out] A pointer to the trampoline function, which will be
+ // used to call the original target function.
+ // This parameter can be NULL.
+ MH_STATUS WINAPI MH_CreateHookApi(
+ LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal);
+
+ // Creates a hook for the specified API function, in disabled state.
+ // Parameters:
+ // pszModule [in] A pointer to the loaded module name which contains the
+ // target function.
+ // pszProcName [in] A pointer to the target function name, which will be
+ // overridden by the detour function.
+ // pDetour [in] A pointer to the detour function, which will override
+ // the target function.
+ // ppOriginal [out] A pointer to the trampoline function, which will be
+ // used to call the original target function.
+ // This parameter can be NULL.
+ // ppTarget [out] A pointer to the target function, which will be used
+ // with other functions.
+ // This parameter can be NULL.
+ MH_STATUS WINAPI MH_CreateHookApiEx(
+ LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget);
+
+ // Removes an already created hook.
+ // Parameters:
+ // pTarget [in] A pointer to the target function.
+ MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget);
+
+ // Enables an already created hook.
+ // Parameters:
+ // pTarget [in] A pointer to the target function.
+ // If this parameter is MH_ALL_HOOKS, all created hooks are
+ // enabled in one go.
+ MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget);
+
+ // Disables an already created hook.
+ // Parameters:
+ // pTarget [in] A pointer to the target function.
+ // If this parameter is MH_ALL_HOOKS, all created hooks are
+ // disabled in one go.
+ MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget);
+
+ // Queues to enable an already created hook.
+ // Parameters:
+ // pTarget [in] A pointer to the target function.
+ // If this parameter is MH_ALL_HOOKS, all created hooks are
+ // queued to be enabled.
+ MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget);
+
+ // Queues to disable an already created hook.
+ // Parameters:
+ // pTarget [in] A pointer to the target function.
+ // If this parameter is MH_ALL_HOOKS, all created hooks are
+ // queued to be disabled.
+ MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget);
+
+ // Applies all queued changes in one go.
+ MH_STATUS WINAPI MH_ApplyQueued(VOID);
+
+ // Translates the MH_STATUS to its name as a string.
+ const char * WINAPI MH_StatusToString(MH_STATUS status);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/minhook/src/buffer.c b/deps/minhook/src/buffer.c
new file mode 100644
index 0000000..55412b0
--- /dev/null
+++ b/deps/minhook/src/buffer.c
@@ -0,0 +1,312 @@
+/*
+ * MinHook - The Minimalistic API Hooking Library for x64/x86
+ * Copyright (C) 2009-2017 Tsuda Kageyu.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include
+#include "buffer.h"
+
+// Size of each memory block. (= page size of VirtualAlloc)
+#define MEMORY_BLOCK_SIZE 0x1000
+
+// Max range for seeking a memory block. (= 1024MB)
+#define MAX_MEMORY_RANGE 0x40000000
+
+// Memory protection flags to check the executable address.
+#define PAGE_EXECUTE_FLAGS \
+ (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)
+
+// Memory slot.
+typedef struct _MEMORY_SLOT
+{
+ union
+ {
+ struct _MEMORY_SLOT *pNext;
+ UINT8 buffer[MEMORY_SLOT_SIZE];
+ };
+} MEMORY_SLOT, *PMEMORY_SLOT;
+
+// Memory block info. Placed at the head of each block.
+typedef struct _MEMORY_BLOCK
+{
+ struct _MEMORY_BLOCK *pNext;
+ PMEMORY_SLOT pFree; // First element of the free slot list.
+ UINT usedCount;
+} MEMORY_BLOCK, *PMEMORY_BLOCK;
+
+//-------------------------------------------------------------------------
+// Global Variables:
+//-------------------------------------------------------------------------
+
+// First element of the memory block list.
+PMEMORY_BLOCK g_pMemoryBlocks;
+
+//-------------------------------------------------------------------------
+VOID InitializeBuffer(VOID)
+{
+ // Nothing to do for now.
+}
+
+//-------------------------------------------------------------------------
+VOID UninitializeBuffer(VOID)
+{
+ PMEMORY_BLOCK pBlock = g_pMemoryBlocks;
+ g_pMemoryBlocks = NULL;
+
+ while (pBlock)
+ {
+ PMEMORY_BLOCK pNext = pBlock->pNext;
+ VirtualFree(pBlock, 0, MEM_RELEASE);
+ pBlock = pNext;
+ }
+}
+
+//-------------------------------------------------------------------------
+#if defined(_M_X64) || defined(__x86_64__)
+static LPVOID FindPrevFreeRegion(LPVOID pAddress, LPVOID pMinAddr, DWORD dwAllocationGranularity)
+{
+ ULONG_PTR tryAddr = (ULONG_PTR)pAddress;
+
+ // Round down to the allocation granularity.
+ tryAddr -= tryAddr % dwAllocationGranularity;
+
+ // Start from the previous allocation granularity multiply.
+ tryAddr -= dwAllocationGranularity;
+
+ while (tryAddr >= (ULONG_PTR)pMinAddr)
+ {
+ MEMORY_BASIC_INFORMATION mbi;
+ if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0)
+ break;
+
+ if (mbi.State == MEM_FREE)
+ return (LPVOID)tryAddr;
+
+ if ((ULONG_PTR)mbi.AllocationBase < dwAllocationGranularity)
+ break;
+
+ tryAddr = (ULONG_PTR)mbi.AllocationBase - dwAllocationGranularity;
+ }
+
+ return NULL;
+}
+#endif
+
+//-------------------------------------------------------------------------
+#if defined(_M_X64) || defined(__x86_64__)
+static LPVOID FindNextFreeRegion(LPVOID pAddress, LPVOID pMaxAddr, DWORD dwAllocationGranularity)
+{
+ ULONG_PTR tryAddr = (ULONG_PTR)pAddress;
+
+ // Round down to the allocation granularity.
+ tryAddr -= tryAddr % dwAllocationGranularity;
+
+ // Start from the next allocation granularity multiply.
+ tryAddr += dwAllocationGranularity;
+
+ while (tryAddr <= (ULONG_PTR)pMaxAddr)
+ {
+ MEMORY_BASIC_INFORMATION mbi;
+ if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0)
+ break;
+
+ if (mbi.State == MEM_FREE)
+ return (LPVOID)tryAddr;
+
+ tryAddr = (ULONG_PTR)mbi.BaseAddress + mbi.RegionSize;
+
+ // Round up to the next allocation granularity.
+ tryAddr += dwAllocationGranularity - 1;
+ tryAddr -= tryAddr % dwAllocationGranularity;
+ }
+
+ return NULL;
+}
+#endif
+
+//-------------------------------------------------------------------------
+static PMEMORY_BLOCK GetMemoryBlock(LPVOID pOrigin)
+{
+ PMEMORY_BLOCK pBlock;
+#if defined(_M_X64) || defined(__x86_64__)
+ ULONG_PTR minAddr;
+ ULONG_PTR maxAddr;
+
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ minAddr = (ULONG_PTR)si.lpMinimumApplicationAddress;
+ maxAddr = (ULONG_PTR)si.lpMaximumApplicationAddress;
+
+ // pOrigin ± 512MB
+ if ((ULONG_PTR)pOrigin > MAX_MEMORY_RANGE && minAddr < (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE)
+ minAddr = (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE;
+
+ if (maxAddr > (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE)
+ maxAddr = (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE;
+
+ // Make room for MEMORY_BLOCK_SIZE bytes.
+ maxAddr -= MEMORY_BLOCK_SIZE - 1;
+#endif
+
+ // Look the registered blocks for a reachable one.
+ for (pBlock = g_pMemoryBlocks; pBlock != NULL; pBlock = pBlock->pNext)
+ {
+#if defined(_M_X64) || defined(__x86_64__)
+ // Ignore the blocks too far.
+ if ((ULONG_PTR)pBlock < minAddr || (ULONG_PTR)pBlock >= maxAddr)
+ continue;
+#endif
+ // The block has at least one unused slot.
+ if (pBlock->pFree != NULL)
+ return pBlock;
+ }
+
+#if defined(_M_X64) || defined(__x86_64__)
+ // Alloc a new block above if not found.
+ {
+ LPVOID pAlloc = pOrigin;
+ while ((ULONG_PTR)pAlloc >= minAddr)
+ {
+ pAlloc = FindPrevFreeRegion(pAlloc, (LPVOID)minAddr, si.dwAllocationGranularity);
+ if (pAlloc == NULL)
+ break;
+
+ pBlock = (PMEMORY_BLOCK)VirtualAlloc(
+ pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ if (pBlock != NULL)
+ break;
+ }
+ }
+
+ // Alloc a new block below if not found.
+ if (pBlock == NULL)
+ {
+ LPVOID pAlloc = pOrigin;
+ while ((ULONG_PTR)pAlloc <= maxAddr)
+ {
+ pAlloc = FindNextFreeRegion(pAlloc, (LPVOID)maxAddr, si.dwAllocationGranularity);
+ if (pAlloc == NULL)
+ break;
+
+ pBlock = (PMEMORY_BLOCK)VirtualAlloc(
+ pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ if (pBlock != NULL)
+ break;
+ }
+ }
+#else
+ // In x86 mode, a memory block can be placed anywhere.
+ pBlock = (PMEMORY_BLOCK)VirtualAlloc(
+ NULL, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+#endif
+
+ if (pBlock != NULL)
+ {
+ // Build a linked list of all the slots.
+ PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBlock + 1;
+ pBlock->pFree = NULL;
+ pBlock->usedCount = 0;
+ do
+ {
+ pSlot->pNext = pBlock->pFree;
+ pBlock->pFree = pSlot;
+ pSlot++;
+ } while ((ULONG_PTR)pSlot - (ULONG_PTR)pBlock <= MEMORY_BLOCK_SIZE - MEMORY_SLOT_SIZE);
+
+ pBlock->pNext = g_pMemoryBlocks;
+ g_pMemoryBlocks = pBlock;
+ }
+
+ return pBlock;
+}
+
+//-------------------------------------------------------------------------
+LPVOID AllocateBuffer(LPVOID pOrigin)
+{
+ PMEMORY_SLOT pSlot;
+ PMEMORY_BLOCK pBlock = GetMemoryBlock(pOrigin);
+ if (pBlock == NULL)
+ return NULL;
+
+ // Remove an unused slot from the list.
+ pSlot = pBlock->pFree;
+ pBlock->pFree = pSlot->pNext;
+ pBlock->usedCount++;
+#ifdef _DEBUG
+ // Fill the slot with INT3 for debugging.
+ memset(pSlot, 0xCC, sizeof(MEMORY_SLOT));
+#endif
+ return pSlot;
+}
+
+//-------------------------------------------------------------------------
+VOID FreeBuffer(LPVOID pBuffer)
+{
+ PMEMORY_BLOCK pBlock = g_pMemoryBlocks;
+ PMEMORY_BLOCK pPrev = NULL;
+ ULONG_PTR pTargetBlock = ((ULONG_PTR)pBuffer / MEMORY_BLOCK_SIZE) * MEMORY_BLOCK_SIZE;
+
+ while (pBlock != NULL)
+ {
+ if ((ULONG_PTR)pBlock == pTargetBlock)
+ {
+ PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBuffer;
+#ifdef _DEBUG
+ // Clear the released slot for debugging.
+ memset(pSlot, 0x00, sizeof(MEMORY_SLOT));
+#endif
+ // Restore the released slot to the list.
+ pSlot->pNext = pBlock->pFree;
+ pBlock->pFree = pSlot;
+ pBlock->usedCount--;
+
+ // Free if unused.
+ if (pBlock->usedCount == 0)
+ {
+ if (pPrev)
+ pPrev->pNext = pBlock->pNext;
+ else
+ g_pMemoryBlocks = pBlock->pNext;
+
+ VirtualFree(pBlock, 0, MEM_RELEASE);
+ }
+
+ break;
+ }
+
+ pPrev = pBlock;
+ pBlock = pBlock->pNext;
+ }
+}
+
+//-------------------------------------------------------------------------
+BOOL IsExecutableAddress(LPVOID pAddress)
+{
+ MEMORY_BASIC_INFORMATION mi;
+ VirtualQuery(pAddress, &mi, sizeof(mi));
+
+ return (mi.State == MEM_COMMIT && (mi.Protect & PAGE_EXECUTE_FLAGS));
+}
diff --git a/deps/minhook/src/buffer.h b/deps/minhook/src/buffer.h
new file mode 100644
index 0000000..204d551
--- /dev/null
+++ b/deps/minhook/src/buffer.h
@@ -0,0 +1,42 @@
+/*
+ * MinHook - The Minimalistic API Hooking Library for x64/x86
+ * Copyright (C) 2009-2017 Tsuda Kageyu.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#pragma once
+
+// Size of each memory slot.
+#if defined(_M_X64) || defined(__x86_64__)
+ #define MEMORY_SLOT_SIZE 64
+#else
+ #define MEMORY_SLOT_SIZE 32
+#endif
+
+VOID InitializeBuffer(VOID);
+VOID UninitializeBuffer(VOID);
+LPVOID AllocateBuffer(LPVOID pOrigin);
+VOID FreeBuffer(LPVOID pBuffer);
+BOOL IsExecutableAddress(LPVOID pAddress);
diff --git a/deps/minhook/src/hde/hde32.c b/deps/minhook/src/hde/hde32.c
new file mode 100644
index 0000000..eb6af9b
--- /dev/null
+++ b/deps/minhook/src/hde/hde32.c
@@ -0,0 +1,324 @@
+/*
+ * Hacker Disassembler Engine 32 C
+ * Copyright (c) 2008-2009, Vyacheslav Patkov.
+ * All rights reserved.
+ *
+ */
+
+#if defined(_M_IX86) || defined(__i386__)
+
+#include
+#include "hde32.h"
+#include "table32.h"
+
+unsigned int hde32_disasm(const void *code, hde32s *hs)
+{
+ uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0;
+ uint8_t *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0;
+
+ memset(hs, 0, sizeof(hde32s));
+
+ for (x = 16; x; x--)
+ switch (c = *p++) {
+ case 0xf3:
+ hs->p_rep = c;
+ pref |= PRE_F3;
+ break;
+ case 0xf2:
+ hs->p_rep = c;
+ pref |= PRE_F2;
+ break;
+ case 0xf0:
+ hs->p_lock = c;
+ pref |= PRE_LOCK;
+ break;
+ case 0x26: case 0x2e: case 0x36:
+ case 0x3e: case 0x64: case 0x65:
+ hs->p_seg = c;
+ pref |= PRE_SEG;
+ break;
+ case 0x66:
+ hs->p_66 = c;
+ pref |= PRE_66;
+ break;
+ case 0x67:
+ hs->p_67 = c;
+ pref |= PRE_67;
+ break;
+ default:
+ goto pref_done;
+ }
+ pref_done:
+
+ hs->flags = (uint32_t)pref << 23;
+
+ if (!pref)
+ pref |= PRE_NONE;
+
+ if ((hs->opcode = c) == 0x0f) {
+ hs->opcode2 = c = *p++;
+ ht += DELTA_OPCODES;
+ } else if (c >= 0xa0 && c <= 0xa3) {
+ if (pref & PRE_67)
+ pref |= PRE_66;
+ else
+ pref &= ~PRE_66;
+ }
+
+ opcode = c;
+ cflags = ht[ht[opcode / 4] + (opcode % 4)];
+
+ if (cflags == C_ERROR) {
+ hs->flags |= F_ERROR | F_ERROR_OPCODE;
+ cflags = 0;
+ if ((opcode & -3) == 0x24)
+ cflags++;
+ }
+
+ x = 0;
+ if (cflags & C_GROUP) {
+ uint16_t t;
+ t = *(uint16_t *)(ht + (cflags & 0x7f));
+ cflags = (uint8_t)t;
+ x = (uint8_t)(t >> 8);
+ }
+
+ if (hs->opcode2) {
+ ht = hde32_table + DELTA_PREFIXES;
+ if (ht[ht[opcode / 4] + (opcode % 4)] & pref)
+ hs->flags |= F_ERROR | F_ERROR_OPCODE;
+ }
+
+ if (cflags & C_MODRM) {
+ hs->flags |= F_MODRM;
+ hs->modrm = c = *p++;
+ hs->modrm_mod = m_mod = c >> 6;
+ hs->modrm_rm = m_rm = c & 7;
+ hs->modrm_reg = m_reg = (c & 0x3f) >> 3;
+
+ if (x && ((x << m_reg) & 0x80))
+ hs->flags |= F_ERROR | F_ERROR_OPCODE;
+
+ if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) {
+ uint8_t t = opcode - 0xd9;
+ if (m_mod == 3) {
+ ht = hde32_table + DELTA_FPU_MODRM + t*8;
+ t = ht[m_reg] << m_rm;
+ } else {
+ ht = hde32_table + DELTA_FPU_REG;
+ t = ht[t] << m_reg;
+ }
+ if (t & 0x80)
+ hs->flags |= F_ERROR | F_ERROR_OPCODE;
+ }
+
+ if (pref & PRE_LOCK) {
+ if (m_mod == 3) {
+ hs->flags |= F_ERROR | F_ERROR_LOCK;
+ } else {
+ uint8_t *table_end, op = opcode;
+ if (hs->opcode2) {
+ ht = hde32_table + DELTA_OP2_LOCK_OK;
+ table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
+ } else {
+ ht = hde32_table + DELTA_OP_LOCK_OK;
+ table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK;
+ op &= -2;
+ }
+ for (; ht != table_end; ht++)
+ if (*ht++ == op) {
+ if (!((*ht << m_reg) & 0x80))
+ goto no_lock_error;
+ else
+ break;
+ }
+ hs->flags |= F_ERROR | F_ERROR_LOCK;
+ no_lock_error:
+ ;
+ }
+ }
+
+ if (hs->opcode2) {
+ switch (opcode) {
+ case 0x20: case 0x22:
+ m_mod = 3;
+ if (m_reg > 4 || m_reg == 1)
+ goto error_operand;
+ else
+ goto no_error_operand;
+ case 0x21: case 0x23:
+ m_mod = 3;
+ if (m_reg == 4 || m_reg == 5)
+ goto error_operand;
+ else
+ goto no_error_operand;
+ }
+ } else {
+ switch (opcode) {
+ case 0x8c:
+ if (m_reg > 5)
+ goto error_operand;
+ else
+ goto no_error_operand;
+ case 0x8e:
+ if (m_reg == 1 || m_reg > 5)
+ goto error_operand;
+ else
+ goto no_error_operand;
+ }
+ }
+
+ if (m_mod == 3) {
+ uint8_t *table_end;
+ if (hs->opcode2) {
+ ht = hde32_table + DELTA_OP2_ONLY_MEM;
+ table_end = ht + sizeof(hde32_table) - DELTA_OP2_ONLY_MEM;
+ } else {
+ ht = hde32_table + DELTA_OP_ONLY_MEM;
+ table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM;
+ }
+ for (; ht != table_end; ht += 2)
+ if (*ht++ == opcode) {
+ if ((*ht++ & pref) && !((*ht << m_reg) & 0x80))
+ goto error_operand;
+ else
+ break;
+ }
+ goto no_error_operand;
+ } else if (hs->opcode2) {
+ switch (opcode) {
+ case 0x50: case 0xd7: case 0xf7:
+ if (pref & (PRE_NONE | PRE_66))
+ goto error_operand;
+ break;
+ case 0xd6:
+ if (pref & (PRE_F2 | PRE_F3))
+ goto error_operand;
+ break;
+ case 0xc5:
+ goto error_operand;
+ }
+ goto no_error_operand;
+ } else
+ goto no_error_operand;
+
+ error_operand:
+ hs->flags |= F_ERROR | F_ERROR_OPERAND;
+ no_error_operand:
+
+ c = *p++;
+ if (m_reg <= 1) {
+ if (opcode == 0xf6)
+ cflags |= C_IMM8;
+ else if (opcode == 0xf7)
+ cflags |= C_IMM_P66;
+ }
+
+ switch (m_mod) {
+ case 0:
+ if (pref & PRE_67) {
+ if (m_rm == 6)
+ disp_size = 2;
+ } else
+ if (m_rm == 5)
+ disp_size = 4;
+ break;
+ case 1:
+ disp_size = 1;
+ break;
+ case 2:
+ disp_size = 2;
+ if (!(pref & PRE_67))
+ disp_size <<= 1;
+ break;
+ }
+
+ if (m_mod != 3 && m_rm == 4 && !(pref & PRE_67)) {
+ hs->flags |= F_SIB;
+ p++;
+ hs->sib = c;
+ hs->sib_scale = c >> 6;
+ hs->sib_index = (c & 0x3f) >> 3;
+ if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1))
+ disp_size = 4;
+ }
+
+ p--;
+ switch (disp_size) {
+ case 1:
+ hs->flags |= F_DISP8;
+ hs->disp.disp8 = *p;
+ break;
+ case 2:
+ hs->flags |= F_DISP16;
+ hs->disp.disp16 = *(uint16_t *)p;
+ break;
+ case 4:
+ hs->flags |= F_DISP32;
+ hs->disp.disp32 = *(uint32_t *)p;
+ break;
+ }
+ p += disp_size;
+ } else if (pref & PRE_LOCK)
+ hs->flags |= F_ERROR | F_ERROR_LOCK;
+
+ if (cflags & C_IMM_P66) {
+ if (cflags & C_REL32) {
+ if (pref & PRE_66) {
+ hs->flags |= F_IMM16 | F_RELATIVE;
+ hs->imm.imm16 = *(uint16_t *)p;
+ p += 2;
+ goto disasm_done;
+ }
+ goto rel32_ok;
+ }
+ if (pref & PRE_66) {
+ hs->flags |= F_IMM16;
+ hs->imm.imm16 = *(uint16_t *)p;
+ p += 2;
+ } else {
+ hs->flags |= F_IMM32;
+ hs->imm.imm32 = *(uint32_t *)p;
+ p += 4;
+ }
+ }
+
+ if (cflags & C_IMM16) {
+ if (hs->flags & F_IMM32) {
+ hs->flags |= F_IMM16;
+ hs->disp.disp16 = *(uint16_t *)p;
+ } else if (hs->flags & F_IMM16) {
+ hs->flags |= F_2IMM16;
+ hs->disp.disp16 = *(uint16_t *)p;
+ } else {
+ hs->flags |= F_IMM16;
+ hs->imm.imm16 = *(uint16_t *)p;
+ }
+ p += 2;
+ }
+ if (cflags & C_IMM8) {
+ hs->flags |= F_IMM8;
+ hs->imm.imm8 = *p++;
+ }
+
+ if (cflags & C_REL32) {
+ rel32_ok:
+ hs->flags |= F_IMM32 | F_RELATIVE;
+ hs->imm.imm32 = *(uint32_t *)p;
+ p += 4;
+ } else if (cflags & C_REL8) {
+ hs->flags |= F_IMM8 | F_RELATIVE;
+ hs->imm.imm8 = *p++;
+ }
+
+ disasm_done:
+
+ if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) {
+ hs->flags |= F_ERROR | F_ERROR_LENGTH;
+ hs->len = 15;
+ }
+
+ return (unsigned int)hs->len;
+}
+
+#endif // defined(_M_IX86) || defined(__i386__)
diff --git a/deps/minhook/src/hde/hde32.h b/deps/minhook/src/hde/hde32.h
new file mode 100644
index 0000000..1112450
--- /dev/null
+++ b/deps/minhook/src/hde/hde32.h
@@ -0,0 +1,105 @@
+/*
+ * Hacker Disassembler Engine 32
+ * Copyright (c) 2006-2009, Vyacheslav Patkov.
+ * All rights reserved.
+ *
+ * hde32.h: C/C++ header file
+ *
+ */
+
+#ifndef _HDE32_H_
+#define _HDE32_H_
+
+/* stdint.h - C99 standard header
+ * http://en.wikipedia.org/wiki/stdint.h
+ *
+ * if your compiler doesn't contain "stdint.h" header (for
+ * example, Microsoft Visual C++), you can download file:
+ * http://www.azillionmonkeys.com/qed/pstdint.h
+ * and change next line to:
+ * #include "pstdint.h"
+ */
+#include "pstdint.h"
+
+#define F_MODRM 0x00000001
+#define F_SIB 0x00000002
+#define F_IMM8 0x00000004
+#define F_IMM16 0x00000008
+#define F_IMM32 0x00000010
+#define F_DISP8 0x00000020
+#define F_DISP16 0x00000040
+#define F_DISP32 0x00000080
+#define F_RELATIVE 0x00000100
+#define F_2IMM16 0x00000800
+#define F_ERROR 0x00001000
+#define F_ERROR_OPCODE 0x00002000
+#define F_ERROR_LENGTH 0x00004000
+#define F_ERROR_LOCK 0x00008000
+#define F_ERROR_OPERAND 0x00010000
+#define F_PREFIX_REPNZ 0x01000000
+#define F_PREFIX_REPX 0x02000000
+#define F_PREFIX_REP 0x03000000
+#define F_PREFIX_66 0x04000000
+#define F_PREFIX_67 0x08000000
+#define F_PREFIX_LOCK 0x10000000
+#define F_PREFIX_SEG 0x20000000
+#define F_PREFIX_ANY 0x3f000000
+
+#define PREFIX_SEGMENT_CS 0x2e
+#define PREFIX_SEGMENT_SS 0x36
+#define PREFIX_SEGMENT_DS 0x3e
+#define PREFIX_SEGMENT_ES 0x26
+#define PREFIX_SEGMENT_FS 0x64
+#define PREFIX_SEGMENT_GS 0x65
+#define PREFIX_LOCK 0xf0
+#define PREFIX_REPNZ 0xf2
+#define PREFIX_REPX 0xf3
+#define PREFIX_OPERAND_SIZE 0x66
+#define PREFIX_ADDRESS_SIZE 0x67
+
+#pragma pack(push,1)
+
+typedef struct {
+ uint8_t len;
+ uint8_t p_rep;
+ uint8_t p_lock;
+ uint8_t p_seg;
+ uint8_t p_66;
+ uint8_t p_67;
+ uint8_t opcode;
+ uint8_t opcode2;
+ uint8_t modrm;
+ uint8_t modrm_mod;
+ uint8_t modrm_reg;
+ uint8_t modrm_rm;
+ uint8_t sib;
+ uint8_t sib_scale;
+ uint8_t sib_index;
+ uint8_t sib_base;
+ union {
+ uint8_t imm8;
+ uint16_t imm16;
+ uint32_t imm32;
+ } imm;
+ union {
+ uint8_t disp8;
+ uint16_t disp16;
+ uint32_t disp32;
+ } disp;
+ uint32_t flags;
+} hde32s;
+
+#pragma pack(pop)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* __cdecl */
+unsigned int hde32_disasm(const void *code, hde32s *hs);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HDE32_H_ */
diff --git a/deps/minhook/src/hde/hde64.c b/deps/minhook/src/hde/hde64.c
new file mode 100644
index 0000000..55a702e
--- /dev/null
+++ b/deps/minhook/src/hde/hde64.c
@@ -0,0 +1,333 @@
+/*
+ * Hacker Disassembler Engine 64 C
+ * Copyright (c) 2008-2009, Vyacheslav Patkov.
+ * All rights reserved.
+ *
+ */
+
+#if defined(_M_X64) || defined(__x86_64__)
+
+#include
+#include "hde64.h"
+#include "table64.h"
+
+unsigned int hde64_disasm(const void *code, hde64s *hs)
+{
+ uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0;
+ uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0;
+ uint8_t op64 = 0;
+
+ memset(hs, 0, sizeof(hde64s));
+
+ for (x = 16; x; x--)
+ switch (c = *p++) {
+ case 0xf3:
+ hs->p_rep = c;
+ pref |= PRE_F3;
+ break;
+ case 0xf2:
+ hs->p_rep = c;
+ pref |= PRE_F2;
+ break;
+ case 0xf0:
+ hs->p_lock = c;
+ pref |= PRE_LOCK;
+ break;
+ case 0x26: case 0x2e: case 0x36:
+ case 0x3e: case 0x64: case 0x65:
+ hs->p_seg = c;
+ pref |= PRE_SEG;
+ break;
+ case 0x66:
+ hs->p_66 = c;
+ pref |= PRE_66;
+ break;
+ case 0x67:
+ hs->p_67 = c;
+ pref |= PRE_67;
+ break;
+ default:
+ goto pref_done;
+ }
+ pref_done:
+
+ hs->flags = (uint32_t)pref << 23;
+
+ if (!pref)
+ pref |= PRE_NONE;
+
+ if ((c & 0xf0) == 0x40) {
+ hs->flags |= F_PREFIX_REX;
+ if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8)
+ op64++;
+ hs->rex_r = (c & 7) >> 2;
+ hs->rex_x = (c & 3) >> 1;
+ hs->rex_b = c & 1;
+ if (((c = *p++) & 0xf0) == 0x40) {
+ opcode = c;
+ goto error_opcode;
+ }
+ }
+
+ if ((hs->opcode = c) == 0x0f) {
+ hs->opcode2 = c = *p++;
+ ht += DELTA_OPCODES;
+ } else if (c >= 0xa0 && c <= 0xa3) {
+ op64++;
+ if (pref & PRE_67)
+ pref |= PRE_66;
+ else
+ pref &= ~PRE_66;
+ }
+
+ opcode = c;
+ cflags = ht[ht[opcode / 4] + (opcode % 4)];
+
+ if (cflags == C_ERROR) {
+ error_opcode:
+ hs->flags |= F_ERROR | F_ERROR_OPCODE;
+ cflags = 0;
+ if ((opcode & -3) == 0x24)
+ cflags++;
+ }
+
+ x = 0;
+ if (cflags & C_GROUP) {
+ uint16_t t;
+ t = *(uint16_t *)(ht + (cflags & 0x7f));
+ cflags = (uint8_t)t;
+ x = (uint8_t)(t >> 8);
+ }
+
+ if (hs->opcode2) {
+ ht = hde64_table + DELTA_PREFIXES;
+ if (ht[ht[opcode / 4] + (opcode % 4)] & pref)
+ hs->flags |= F_ERROR | F_ERROR_OPCODE;
+ }
+
+ if (cflags & C_MODRM) {
+ hs->flags |= F_MODRM;
+ hs->modrm = c = *p++;
+ hs->modrm_mod = m_mod = c >> 6;
+ hs->modrm_rm = m_rm = c & 7;
+ hs->modrm_reg = m_reg = (c & 0x3f) >> 3;
+
+ if (x && ((x << m_reg) & 0x80))
+ hs->flags |= F_ERROR | F_ERROR_OPCODE;
+
+ if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) {
+ uint8_t t = opcode - 0xd9;
+ if (m_mod == 3) {
+ ht = hde64_table + DELTA_FPU_MODRM + t*8;
+ t = ht[m_reg] << m_rm;
+ } else {
+ ht = hde64_table + DELTA_FPU_REG;
+ t = ht[t] << m_reg;
+ }
+ if (t & 0x80)
+ hs->flags |= F_ERROR | F_ERROR_OPCODE;
+ }
+
+ if (pref & PRE_LOCK) {
+ if (m_mod == 3) {
+ hs->flags |= F_ERROR | F_ERROR_LOCK;
+ } else {
+ uint8_t *table_end, op = opcode;
+ if (hs->opcode2) {
+ ht = hde64_table + DELTA_OP2_LOCK_OK;
+ table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
+ } else {
+ ht = hde64_table + DELTA_OP_LOCK_OK;
+ table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK;
+ op &= -2;
+ }
+ for (; ht != table_end; ht++)
+ if (*ht++ == op) {
+ if (!((*ht << m_reg) & 0x80))
+ goto no_lock_error;
+ else
+ break;
+ }
+ hs->flags |= F_ERROR | F_ERROR_LOCK;
+ no_lock_error:
+ ;
+ }
+ }
+
+ if (hs->opcode2) {
+ switch (opcode) {
+ case 0x20: case 0x22:
+ m_mod = 3;
+ if (m_reg > 4 || m_reg == 1)
+ goto error_operand;
+ else
+ goto no_error_operand;
+ case 0x21: case 0x23:
+ m_mod = 3;
+ if (m_reg == 4 || m_reg == 5)
+ goto error_operand;
+ else
+ goto no_error_operand;
+ }
+ } else {
+ switch (opcode) {
+ case 0x8c:
+ if (m_reg > 5)
+ goto error_operand;
+ else
+ goto no_error_operand;
+ case 0x8e:
+ if (m_reg == 1 || m_reg > 5)
+ goto error_operand;
+ else
+ goto no_error_operand;
+ }
+ }
+
+ if (m_mod == 3) {
+ uint8_t *table_end;
+ if (hs->opcode2) {
+ ht = hde64_table + DELTA_OP2_ONLY_MEM;
+ table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM;
+ } else {
+ ht = hde64_table + DELTA_OP_ONLY_MEM;
+ table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM;
+ }
+ for (; ht != table_end; ht += 2)
+ if (*ht++ == opcode) {
+ if (*ht++ & pref && !((*ht << m_reg) & 0x80))
+ goto error_operand;
+ else
+ break;
+ }
+ goto no_error_operand;
+ } else if (hs->opcode2) {
+ switch (opcode) {
+ case 0x50: case 0xd7: case 0xf7:
+ if (pref & (PRE_NONE | PRE_66))
+ goto error_operand;
+ break;
+ case 0xd6:
+ if (pref & (PRE_F2 | PRE_F3))
+ goto error_operand;
+ break;
+ case 0xc5:
+ goto error_operand;
+ }
+ goto no_error_operand;
+ } else
+ goto no_error_operand;
+
+ error_operand:
+ hs->flags |= F_ERROR | F_ERROR_OPERAND;
+ no_error_operand:
+
+ c = *p++;
+ if (m_reg <= 1) {
+ if (opcode == 0xf6)
+ cflags |= C_IMM8;
+ else if (opcode == 0xf7)
+ cflags |= C_IMM_P66;
+ }
+
+ switch (m_mod) {
+ case 0:
+ if (pref & PRE_67) {
+ if (m_rm == 6)
+ disp_size = 2;
+ } else
+ if (m_rm == 5)
+ disp_size = 4;
+ break;
+ case 1:
+ disp_size = 1;
+ break;
+ case 2:
+ disp_size = 2;
+ if (!(pref & PRE_67))
+ disp_size <<= 1;
+ }
+
+ if (m_mod != 3 && m_rm == 4) {
+ hs->flags |= F_SIB;
+ p++;
+ hs->sib = c;
+ hs->sib_scale = c >> 6;
+ hs->sib_index = (c & 0x3f) >> 3;
+ if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1))
+ disp_size = 4;
+ }
+
+ p--;
+ switch (disp_size) {
+ case 1:
+ hs->flags |= F_DISP8;
+ hs->disp.disp8 = *p;
+ break;
+ case 2:
+ hs->flags |= F_DISP16;
+ hs->disp.disp16 = *(uint16_t *)p;
+ break;
+ case 4:
+ hs->flags |= F_DISP32;
+ hs->disp.disp32 = *(uint32_t *)p;
+ }
+ p += disp_size;
+ } else if (pref & PRE_LOCK)
+ hs->flags |= F_ERROR | F_ERROR_LOCK;
+
+ if (cflags & C_IMM_P66) {
+ if (cflags & C_REL32) {
+ if (pref & PRE_66) {
+ hs->flags |= F_IMM16 | F_RELATIVE;
+ hs->imm.imm16 = *(uint16_t *)p;
+ p += 2;
+ goto disasm_done;
+ }
+ goto rel32_ok;
+ }
+ if (op64) {
+ hs->flags |= F_IMM64;
+ hs->imm.imm64 = *(uint64_t *)p;
+ p += 8;
+ } else if (!(pref & PRE_66)) {
+ hs->flags |= F_IMM32;
+ hs->imm.imm32 = *(uint32_t *)p;
+ p += 4;
+ } else
+ goto imm16_ok;
+ }
+
+
+ if (cflags & C_IMM16) {
+ imm16_ok:
+ hs->flags |= F_IMM16;
+ hs->imm.imm16 = *(uint16_t *)p;
+ p += 2;
+ }
+ if (cflags & C_IMM8) {
+ hs->flags |= F_IMM8;
+ hs->imm.imm8 = *p++;
+ }
+
+ if (cflags & C_REL32) {
+ rel32_ok:
+ hs->flags |= F_IMM32 | F_RELATIVE;
+ hs->imm.imm32 = *(uint32_t *)p;
+ p += 4;
+ } else if (cflags & C_REL8) {
+ hs->flags |= F_IMM8 | F_RELATIVE;
+ hs->imm.imm8 = *p++;
+ }
+
+ disasm_done:
+
+ if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) {
+ hs->flags |= F_ERROR | F_ERROR_LENGTH;
+ hs->len = 15;
+ }
+
+ return (unsigned int)hs->len;
+}
+
+#endif // defined(_M_X64) || defined(__x86_64__)
diff --git a/deps/minhook/src/hde/hde64.h b/deps/minhook/src/hde/hde64.h
new file mode 100644
index 0000000..ecbf4df
--- /dev/null
+++ b/deps/minhook/src/hde/hde64.h
@@ -0,0 +1,112 @@
+/*
+ * Hacker Disassembler Engine 64
+ * Copyright (c) 2008-2009, Vyacheslav Patkov.
+ * All rights reserved.
+ *
+ * hde64.h: C/C++ header file
+ *
+ */
+
+#ifndef _HDE64_H_
+#define _HDE64_H_
+
+/* stdint.h - C99 standard header
+ * http://en.wikipedia.org/wiki/stdint.h
+ *
+ * if your compiler doesn't contain "stdint.h" header (for
+ * example, Microsoft Visual C++), you can download file:
+ * http://www.azillionmonkeys.com/qed/pstdint.h
+ * and change next line to:
+ * #include "pstdint.h"
+ */
+#include "pstdint.h"
+
+#define F_MODRM 0x00000001
+#define F_SIB 0x00000002
+#define F_IMM8 0x00000004
+#define F_IMM16 0x00000008
+#define F_IMM32 0x00000010
+#define F_IMM64 0x00000020
+#define F_DISP8 0x00000040
+#define F_DISP16 0x00000080
+#define F_DISP32 0x00000100
+#define F_RELATIVE 0x00000200
+#define F_ERROR 0x00001000
+#define F_ERROR_OPCODE 0x00002000
+#define F_ERROR_LENGTH 0x00004000
+#define F_ERROR_LOCK 0x00008000
+#define F_ERROR_OPERAND 0x00010000
+#define F_PREFIX_REPNZ 0x01000000
+#define F_PREFIX_REPX 0x02000000
+#define F_PREFIX_REP 0x03000000
+#define F_PREFIX_66 0x04000000
+#define F_PREFIX_67 0x08000000
+#define F_PREFIX_LOCK 0x10000000
+#define F_PREFIX_SEG 0x20000000
+#define F_PREFIX_REX 0x40000000
+#define F_PREFIX_ANY 0x7f000000
+
+#define PREFIX_SEGMENT_CS 0x2e
+#define PREFIX_SEGMENT_SS 0x36
+#define PREFIX_SEGMENT_DS 0x3e
+#define PREFIX_SEGMENT_ES 0x26
+#define PREFIX_SEGMENT_FS 0x64
+#define PREFIX_SEGMENT_GS 0x65
+#define PREFIX_LOCK 0xf0
+#define PREFIX_REPNZ 0xf2
+#define PREFIX_REPX 0xf3
+#define PREFIX_OPERAND_SIZE 0x66
+#define PREFIX_ADDRESS_SIZE 0x67
+
+#pragma pack(push,1)
+
+typedef struct {
+ uint8_t len;
+ uint8_t p_rep;
+ uint8_t p_lock;
+ uint8_t p_seg;
+ uint8_t p_66;
+ uint8_t p_67;
+ uint8_t rex;
+ uint8_t rex_w;
+ uint8_t rex_r;
+ uint8_t rex_x;
+ uint8_t rex_b;
+ uint8_t opcode;
+ uint8_t opcode2;
+ uint8_t modrm;
+ uint8_t modrm_mod;
+ uint8_t modrm_reg;
+ uint8_t modrm_rm;
+ uint8_t sib;
+ uint8_t sib_scale;
+ uint8_t sib_index;
+ uint8_t sib_base;
+ union {
+ uint8_t imm8;
+ uint16_t imm16;
+ uint32_t imm32;
+ uint64_t imm64;
+ } imm;
+ union {
+ uint8_t disp8;
+ uint16_t disp16;
+ uint32_t disp32;
+ } disp;
+ uint32_t flags;
+} hde64s;
+
+#pragma pack(pop)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* __cdecl */
+unsigned int hde64_disasm(const void *code, hde64s *hs);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HDE64_H_ */
diff --git a/deps/minhook/src/hde/pstdint.h b/deps/minhook/src/hde/pstdint.h
new file mode 100644
index 0000000..84d82a0
--- /dev/null
+++ b/deps/minhook/src/hde/pstdint.h
@@ -0,0 +1,39 @@
+/*
+ * MinHook - The Minimalistic API Hooking Library for x64/x86
+ * Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 AUTHOR 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.
+ */
+
+#pragma once
+
+#include
+
+// Integer types for HDE.
+typedef INT8 int8_t;
+typedef INT16 int16_t;
+typedef INT32 int32_t;
+typedef INT64 int64_t;
+typedef UINT8 uint8_t;
+typedef UINT16 uint16_t;
+typedef UINT32 uint32_t;
+typedef UINT64 uint64_t;
diff --git a/deps/minhook/src/hde/table32.h b/deps/minhook/src/hde/table32.h
new file mode 100644
index 0000000..7b3e12e
--- /dev/null
+++ b/deps/minhook/src/hde/table32.h
@@ -0,0 +1,73 @@
+/*
+ * Hacker Disassembler Engine 32 C
+ * Copyright (c) 2008-2009, Vyacheslav Patkov.
+ * All rights reserved.
+ *
+ */
+
+#define C_NONE 0x00
+#define C_MODRM 0x01
+#define C_IMM8 0x02
+#define C_IMM16 0x04
+#define C_IMM_P66 0x10
+#define C_REL8 0x20
+#define C_REL32 0x40
+#define C_GROUP 0x80
+#define C_ERROR 0xff
+
+#define PRE_ANY 0x00
+#define PRE_NONE 0x01
+#define PRE_F2 0x02
+#define PRE_F3 0x04
+#define PRE_66 0x08
+#define PRE_67 0x10
+#define PRE_LOCK 0x20
+#define PRE_SEG 0x40
+#define PRE_ALL 0xff
+
+#define DELTA_OPCODES 0x4a
+#define DELTA_FPU_REG 0xf1
+#define DELTA_FPU_MODRM 0xf8
+#define DELTA_PREFIXES 0x130
+#define DELTA_OP_LOCK_OK 0x1a1
+#define DELTA_OP2_LOCK_OK 0x1b9
+#define DELTA_OP_ONLY_MEM 0x1cb
+#define DELTA_OP2_ONLY_MEM 0x1da
+
+unsigned char hde32_table[] = {
+ 0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,
+ 0xa8,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xac,0xaa,0xb2,0xaa,0x9f,0x9f,
+ 0x9f,0x9f,0xb5,0xa3,0xa3,0xa4,0xaa,0xaa,0xba,0xaa,0x96,0xaa,0xa8,0xaa,0xc3,
+ 0xc3,0x96,0x96,0xb7,0xae,0xd6,0xbd,0xa3,0xc5,0xa3,0xa3,0x9f,0xc3,0x9c,0xaa,
+ 0xaa,0xac,0xaa,0xbf,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0x90,
+ 0x82,0x7d,0x97,0x59,0x59,0x59,0x59,0x59,0x7f,0x59,0x59,0x60,0x7d,0x7f,0x7f,
+ 0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x9a,0x88,0x7d,
+ 0x59,0x50,0x50,0x50,0x50,0x59,0x59,0x59,0x59,0x61,0x94,0x61,0x9e,0x59,0x59,
+ 0x85,0x59,0x92,0xa3,0x60,0x60,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,
+ 0x59,0x59,0x9f,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xcc,0x01,0xbc,0x03,0xf0,
+ 0x10,0x10,0x10,0x10,0x50,0x50,0x50,0x50,0x14,0x20,0x20,0x20,0x20,0x01,0x01,
+ 0x01,0x01,0xc4,0x02,0x10,0x00,0x00,0x00,0x00,0x01,0x01,0xc0,0xc2,0x10,0x11,
+ 0x02,0x03,0x11,0x03,0x03,0x04,0x00,0x00,0x14,0x00,0x02,0x00,0x00,0xc6,0xc8,
+ 0x02,0x02,0x02,0x02,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xca,
+ 0x01,0x01,0x01,0x00,0x06,0x00,0x04,0x00,0xc0,0xc2,0x01,0x01,0x03,0x01,0xff,
+ 0xff,0x01,0x00,0x03,0xc4,0xc4,0xc6,0x03,0x01,0x01,0x01,0xff,0x03,0x03,0x03,
+ 0xc8,0x40,0x00,0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,
+ 0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0xff,0xff,0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x7f,0x00,0x00,0xff,0x4a,0x4a,0x4a,0x4a,0x4b,0x52,0x4a,0x4a,0x4a,0x4a,0x4f,
+ 0x4c,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x55,0x45,0x40,0x4a,0x4a,0x4a,
+ 0x45,0x59,0x4d,0x46,0x4a,0x5d,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,
+ 0x4a,0x4a,0x4a,0x4a,0x4a,0x61,0x63,0x67,0x4e,0x4a,0x4a,0x6b,0x6d,0x4a,0x4a,
+ 0x45,0x6d,0x4a,0x4a,0x44,0x45,0x4a,0x4a,0x00,0x00,0x00,0x02,0x0d,0x06,0x06,
+ 0x06,0x06,0x0e,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x00,0x06,0x06,0x02,0x06,
+ 0x00,0x0a,0x0a,0x07,0x07,0x06,0x02,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04,
+ 0x04,0x04,0x00,0x00,0x00,0x0e,0x05,0x06,0x06,0x06,0x01,0x06,0x00,0x00,0x08,
+ 0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,
+ 0x86,0x00,0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,
+ 0xf8,0xbb,0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,
+ 0xc4,0xff,0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,
+ 0x13,0x09,0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,
+ 0xb2,0xff,0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,
+ 0xe7,0x08,0x00,0xf0,0x02,0x00
+};
diff --git a/deps/minhook/src/hde/table64.h b/deps/minhook/src/hde/table64.h
new file mode 100644
index 0000000..01d4541
--- /dev/null
+++ b/deps/minhook/src/hde/table64.h
@@ -0,0 +1,74 @@
+/*
+ * Hacker Disassembler Engine 64 C
+ * Copyright (c) 2008-2009, Vyacheslav Patkov.
+ * All rights reserved.
+ *
+ */
+
+#define C_NONE 0x00
+#define C_MODRM 0x01
+#define C_IMM8 0x02
+#define C_IMM16 0x04
+#define C_IMM_P66 0x10
+#define C_REL8 0x20
+#define C_REL32 0x40
+#define C_GROUP 0x80
+#define C_ERROR 0xff
+
+#define PRE_ANY 0x00
+#define PRE_NONE 0x01
+#define PRE_F2 0x02
+#define PRE_F3 0x04
+#define PRE_66 0x08
+#define PRE_67 0x10
+#define PRE_LOCK 0x20
+#define PRE_SEG 0x40
+#define PRE_ALL 0xff
+
+#define DELTA_OPCODES 0x4a
+#define DELTA_FPU_REG 0xfd
+#define DELTA_FPU_MODRM 0x104
+#define DELTA_PREFIXES 0x13c
+#define DELTA_OP_LOCK_OK 0x1ae
+#define DELTA_OP2_LOCK_OK 0x1c6
+#define DELTA_OP_ONLY_MEM 0x1d8
+#define DELTA_OP2_ONLY_MEM 0x1e7
+
+unsigned char hde64_table[] = {
+ 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5,
+ 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1,
+ 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea,
+ 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0,
+ 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab,
+ 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92,
+ 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90,
+ 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b,
+ 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,
+ 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc,
+ 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20,
+ 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff,
+ 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00,
+ 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01,
+ 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10,
+ 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00,
+ 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00,
+ 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
+ 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,
+ 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40,
+ 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43,
+ 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+ 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40,
+ 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06,
+ 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07,
+ 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04,
+ 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10,
+ 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00,
+ 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb,
+ 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff,
+ 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09,
+ 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff,
+ 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08,
+ 0x00,0xf0,0x02,0x00
+};
diff --git a/deps/minhook/src/hook.c b/deps/minhook/src/hook.c
new file mode 100644
index 0000000..ce65e57
--- /dev/null
+++ b/deps/minhook/src/hook.c
@@ -0,0 +1,889 @@
+/*
+ * MinHook - The Minimalistic API Hooking Library for x64/x86
+ * Copyright (C) 2009-2017 Tsuda Kageyu.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include
+#include
+#include
+
+#include "../include/MinHook.h"
+#include "buffer.h"
+#include "trampoline.h"
+
+#ifndef ARRAYSIZE
+ #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
+#endif
+
+// Initial capacity of the HOOK_ENTRY buffer.
+#define INITIAL_HOOK_CAPACITY 32
+
+// Initial capacity of the thread IDs buffer.
+#define INITIAL_THREAD_CAPACITY 128
+
+// Special hook position values.
+#define INVALID_HOOK_POS UINT_MAX
+#define ALL_HOOKS_POS UINT_MAX
+
+// Freeze() action argument defines.
+#define ACTION_DISABLE 0
+#define ACTION_ENABLE 1
+#define ACTION_APPLY_QUEUED 2
+
+// Thread access rights for suspending/resuming threads.
+#define THREAD_ACCESS \
+ (THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION | THREAD_SET_CONTEXT)
+
+// Hook information.
+typedef struct _HOOK_ENTRY
+{
+ LPVOID pTarget; // Address of the target function.
+ LPVOID pDetour; // Address of the detour or relay function.
+ LPVOID pTrampoline; // Address of the trampoline function.
+ UINT8 backup[8]; // Original prologue of the target function.
+
+ UINT8 patchAbove : 1; // Uses the hot patch area.
+ UINT8 isEnabled : 1; // Enabled.
+ UINT8 queueEnable : 1; // Queued for enabling/disabling when != isEnabled.
+
+ UINT nIP : 4; // Count of the instruction boundaries.
+ UINT8 oldIPs[8]; // Instruction boundaries of the target function.
+ UINT8 newIPs[8]; // Instruction boundaries of the trampoline function.
+} HOOK_ENTRY, *PHOOK_ENTRY;
+
+// Suspended threads for Freeze()/Unfreeze().
+typedef struct _FROZEN_THREADS
+{
+ LPDWORD pItems; // Data heap
+ UINT capacity; // Size of allocated data heap, items
+ UINT size; // Actual number of data items
+} FROZEN_THREADS, *PFROZEN_THREADS;
+
+//-------------------------------------------------------------------------
+// Global Variables:
+//-------------------------------------------------------------------------
+
+// Spin lock flag for EnterSpinLock()/LeaveSpinLock().
+volatile LONG g_isLocked = FALSE;
+
+// Private heap handle. If not NULL, this library is initialized.
+HANDLE g_hHeap = NULL;
+
+// Hook entries.
+struct
+{
+ PHOOK_ENTRY pItems; // Data heap
+ UINT capacity; // Size of allocated data heap, items
+ UINT size; // Actual number of data items
+} g_hooks;
+
+//-------------------------------------------------------------------------
+// Returns INVALID_HOOK_POS if not found.
+static UINT FindHookEntry(LPVOID pTarget)
+{
+ UINT i;
+ for (i = 0; i < g_hooks.size; ++i)
+ {
+ if ((ULONG_PTR)pTarget == (ULONG_PTR)g_hooks.pItems[i].pTarget)
+ return i;
+ }
+
+ return INVALID_HOOK_POS;
+}
+
+//-------------------------------------------------------------------------
+static PHOOK_ENTRY AddHookEntry()
+{
+ if (g_hooks.pItems == NULL)
+ {
+ g_hooks.capacity = INITIAL_HOOK_CAPACITY;
+ g_hooks.pItems = (PHOOK_ENTRY)HeapAlloc(
+ g_hHeap, 0, g_hooks.capacity * sizeof(HOOK_ENTRY));
+ if (g_hooks.pItems == NULL)
+ return NULL;
+ }
+ else if (g_hooks.size >= g_hooks.capacity)
+ {
+ PHOOK_ENTRY p = (PHOOK_ENTRY)HeapReAlloc(
+ g_hHeap, 0, g_hooks.pItems, (g_hooks.capacity * 2) * sizeof(HOOK_ENTRY));
+ if (p == NULL)
+ return NULL;
+
+ g_hooks.capacity *= 2;
+ g_hooks.pItems = p;
+ }
+
+ return &g_hooks.pItems[g_hooks.size++];
+}
+
+//-------------------------------------------------------------------------
+static void DeleteHookEntry(UINT pos)
+{
+ if (pos < g_hooks.size - 1)
+ g_hooks.pItems[pos] = g_hooks.pItems[g_hooks.size - 1];
+
+ g_hooks.size--;
+
+ if (g_hooks.capacity / 2 >= INITIAL_HOOK_CAPACITY && g_hooks.capacity / 2 >= g_hooks.size)
+ {
+ PHOOK_ENTRY p = (PHOOK_ENTRY)HeapReAlloc(
+ g_hHeap, 0, g_hooks.pItems, (g_hooks.capacity / 2) * sizeof(HOOK_ENTRY));
+ if (p == NULL)
+ return;
+
+ g_hooks.capacity /= 2;
+ g_hooks.pItems = p;
+ }
+}
+
+//-------------------------------------------------------------------------
+static DWORD_PTR FindOldIP(PHOOK_ENTRY pHook, DWORD_PTR ip)
+{
+ UINT i;
+
+ if (pHook->patchAbove && ip == ((DWORD_PTR)pHook->pTarget - sizeof(JMP_REL)))
+ return (DWORD_PTR)pHook->pTarget;
+
+ for (i = 0; i < pHook->nIP; ++i)
+ {
+ if (ip == ((DWORD_PTR)pHook->pTrampoline + pHook->newIPs[i]))
+ return (DWORD_PTR)pHook->pTarget + pHook->oldIPs[i];
+ }
+
+#if defined(_M_X64) || defined(__x86_64__)
+ // Check relay function.
+ if (ip == (DWORD_PTR)pHook->pDetour)
+ return (DWORD_PTR)pHook->pTarget;
+#endif
+
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+static DWORD_PTR FindNewIP(PHOOK_ENTRY pHook, DWORD_PTR ip)
+{
+ UINT i;
+ for (i = 0; i < pHook->nIP; ++i)
+ {
+ if (ip == ((DWORD_PTR)pHook->pTarget + pHook->oldIPs[i]))
+ return (DWORD_PTR)pHook->pTrampoline + pHook->newIPs[i];
+ }
+
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+static void ProcessThreadIPs(HANDLE hThread, UINT pos, UINT action)
+{
+ // If the thread suspended in the overwritten area,
+ // move IP to the proper address.
+
+ CONTEXT c;
+#if defined(_M_X64) || defined(__x86_64__)
+ DWORD64 *pIP = &c.Rip;
+#else
+ DWORD *pIP = &c.Eip;
+#endif
+ UINT count;
+
+ c.ContextFlags = CONTEXT_CONTROL;
+ if (!GetThreadContext(hThread, &c))
+ return;
+
+ if (pos == ALL_HOOKS_POS)
+ {
+ pos = 0;
+ count = g_hooks.size;
+ }
+ else
+ {
+ count = pos + 1;
+ }
+
+ for (; pos < count; ++pos)
+ {
+ PHOOK_ENTRY pHook = &g_hooks.pItems[pos];
+ BOOL enable;
+ DWORD_PTR ip;
+
+ switch (action)
+ {
+ case ACTION_DISABLE:
+ enable = FALSE;
+ break;
+
+ case ACTION_ENABLE:
+ enable = TRUE;
+ break;
+
+ default: // ACTION_APPLY_QUEUED
+ enable = pHook->queueEnable;
+ break;
+ }
+ if (pHook->isEnabled == enable)
+ continue;
+
+ if (enable)
+ ip = FindNewIP(pHook, *pIP);
+ else
+ ip = FindOldIP(pHook, *pIP);
+
+ if (ip != 0)
+ {
+ *pIP = ip;
+ SetThreadContext(hThread, &c);
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+static VOID EnumerateThreads(PFROZEN_THREADS pThreads)
+{
+ HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+ if (hSnapshot != INVALID_HANDLE_VALUE)
+ {
+ THREADENTRY32 te;
+ te.dwSize = sizeof(THREADENTRY32);
+ if (Thread32First(hSnapshot, &te))
+ {
+ do
+ {
+ if (te.dwSize >= (FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(DWORD))
+ && te.th32OwnerProcessID == GetCurrentProcessId()
+ && te.th32ThreadID != GetCurrentThreadId())
+ {
+ if (pThreads->pItems == NULL)
+ {
+ pThreads->capacity = INITIAL_THREAD_CAPACITY;
+ pThreads->pItems
+ = (LPDWORD)HeapAlloc(g_hHeap, 0, pThreads->capacity * sizeof(DWORD));
+ if (pThreads->pItems == NULL)
+ break;
+ }
+ else if (pThreads->size >= pThreads->capacity)
+ {
+ LPDWORD p = (LPDWORD)HeapReAlloc(
+ g_hHeap, 0, pThreads->pItems, (pThreads->capacity * 2) * sizeof(DWORD));
+ if (p == NULL)
+ break;
+
+ pThreads->capacity *= 2;
+ pThreads->pItems = p;
+ }
+ pThreads->pItems[pThreads->size++] = te.th32ThreadID;
+ }
+
+ te.dwSize = sizeof(THREADENTRY32);
+ } while (Thread32Next(hSnapshot, &te));
+ }
+ CloseHandle(hSnapshot);
+ }
+}
+
+//-------------------------------------------------------------------------
+static VOID Freeze(PFROZEN_THREADS pThreads, UINT pos, UINT action)
+{
+ pThreads->pItems = NULL;
+ pThreads->capacity = 0;
+ pThreads->size = 0;
+ EnumerateThreads(pThreads);
+
+ if (pThreads->pItems != NULL)
+ {
+ UINT i;
+ for (i = 0; i < pThreads->size; ++i)
+ {
+ HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]);
+ if (hThread != NULL)
+ {
+ SuspendThread(hThread);
+ ProcessThreadIPs(hThread, pos, action);
+ CloseHandle(hThread);
+ }
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+static VOID Unfreeze(PFROZEN_THREADS pThreads)
+{
+ if (pThreads->pItems != NULL)
+ {
+ UINT i;
+ for (i = 0; i < pThreads->size; ++i)
+ {
+ HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]);
+ if (hThread != NULL)
+ {
+ ResumeThread(hThread);
+ CloseHandle(hThread);
+ }
+ }
+
+ HeapFree(g_hHeap, 0, pThreads->pItems);
+ }
+}
+
+//-------------------------------------------------------------------------
+static MH_STATUS EnableHookLL(UINT pos, BOOL enable)
+{
+ PHOOK_ENTRY pHook = &g_hooks.pItems[pos];
+ DWORD oldProtect;
+ SIZE_T patchSize = sizeof(JMP_REL);
+ LPBYTE pPatchTarget = (LPBYTE)pHook->pTarget;
+
+ if (pHook->patchAbove)
+ {
+ pPatchTarget -= sizeof(JMP_REL);
+ patchSize += sizeof(JMP_REL_SHORT);
+ }
+
+ if (!VirtualProtect(pPatchTarget, patchSize, PAGE_EXECUTE_READWRITE, &oldProtect))
+ return MH_ERROR_MEMORY_PROTECT;
+
+ if (enable)
+ {
+ PJMP_REL pJmp = (PJMP_REL)pPatchTarget;
+ pJmp->opcode = 0xE9;
+ pJmp->operand = (UINT32)((LPBYTE)pHook->pDetour - (pPatchTarget + sizeof(JMP_REL)));
+
+ if (pHook->patchAbove)
+ {
+ PJMP_REL_SHORT pShortJmp = (PJMP_REL_SHORT)pHook->pTarget;
+ pShortJmp->opcode = 0xEB;
+ pShortJmp->operand = (UINT8)(0 - (sizeof(JMP_REL_SHORT) + sizeof(JMP_REL)));
+ }
+ }
+ else
+ {
+ if (pHook->patchAbove)
+ memcpy(pPatchTarget, pHook->backup, sizeof(JMP_REL) + sizeof(JMP_REL_SHORT));
+ else
+ memcpy(pPatchTarget, pHook->backup, sizeof(JMP_REL));
+ }
+
+ VirtualProtect(pPatchTarget, patchSize, oldProtect, &oldProtect);
+
+ // Just-in-case measure.
+ FlushInstructionCache(GetCurrentProcess(), pPatchTarget, patchSize);
+
+ pHook->isEnabled = enable;
+ pHook->queueEnable = enable;
+
+ return MH_OK;
+}
+
+//-------------------------------------------------------------------------
+static MH_STATUS EnableAllHooksLL(BOOL enable)
+{
+ MH_STATUS status = MH_OK;
+ UINT i, first = INVALID_HOOK_POS;
+
+ for (i = 0; i < g_hooks.size; ++i)
+ {
+ if (g_hooks.pItems[i].isEnabled != enable)
+ {
+ first = i;
+ break;
+ }
+ }
+
+ if (first != INVALID_HOOK_POS)
+ {
+ FROZEN_THREADS threads;
+ Freeze(&threads, ALL_HOOKS_POS, enable ? ACTION_ENABLE : ACTION_DISABLE);
+
+ for (i = first; i < g_hooks.size; ++i)
+ {
+ if (g_hooks.pItems[i].isEnabled != enable)
+ {
+ status = EnableHookLL(i, enable);
+ if (status != MH_OK)
+ break;
+ }
+ }
+
+ Unfreeze(&threads);
+ }
+
+ return status;
+}
+
+//-------------------------------------------------------------------------
+static VOID EnterSpinLock(VOID)
+{
+ SIZE_T spinCount = 0;
+
+ // Wait until the flag is FALSE.
+ while (InterlockedCompareExchange(&g_isLocked, TRUE, FALSE) != FALSE)
+ {
+ // No need to generate a memory barrier here, since InterlockedCompareExchange()
+ // generates a full memory barrier itself.
+
+ // Prevent the loop from being too busy.
+ if (spinCount < 32)
+ Sleep(0);
+ else
+ Sleep(1);
+
+ spinCount++;
+ }
+}
+
+//-------------------------------------------------------------------------
+static VOID LeaveSpinLock(VOID)
+{
+ // No need to generate a memory barrier here, since InterlockedExchange()
+ // generates a full memory barrier itself.
+
+ InterlockedExchange(&g_isLocked, FALSE);
+}
+
+//-------------------------------------------------------------------------
+MH_STATUS WINAPI MH_Initialize(VOID)
+{
+ MH_STATUS status = MH_OK;
+
+ EnterSpinLock();
+
+ if (g_hHeap == NULL)
+ {
+ g_hHeap = HeapCreate(0, 0, 0);
+ if (g_hHeap != NULL)
+ {
+ // Initialize the internal function buffer.
+ InitializeBuffer();
+ }
+ else
+ {
+ status = MH_ERROR_MEMORY_ALLOC;
+ }
+ }
+ else
+ {
+ status = MH_ERROR_ALREADY_INITIALIZED;
+ }
+
+ LeaveSpinLock();
+
+ return status;
+}
+
+//-------------------------------------------------------------------------
+MH_STATUS WINAPI MH_Uninitialize(VOID)
+{
+ MH_STATUS status = MH_OK;
+
+ EnterSpinLock();
+
+ if (g_hHeap != NULL)
+ {
+ status = EnableAllHooksLL(FALSE);
+ if (status == MH_OK)
+ {
+ // Free the internal function buffer.
+
+ // HeapFree is actually not required, but some tools detect a false
+ // memory leak without HeapFree.
+
+ UninitializeBuffer();
+
+ HeapFree(g_hHeap, 0, g_hooks.pItems);
+ HeapDestroy(g_hHeap);
+
+ g_hHeap = NULL;
+
+ g_hooks.pItems = NULL;
+ g_hooks.capacity = 0;
+ g_hooks.size = 0;
+ }
+ }
+ else
+ {
+ status = MH_ERROR_NOT_INITIALIZED;
+ }
+
+ LeaveSpinLock();
+
+ return status;
+}
+
+//-------------------------------------------------------------------------
+MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal)
+{
+ MH_STATUS status = MH_OK;
+
+ EnterSpinLock();
+
+ if (g_hHeap != NULL)
+ {
+ if (IsExecutableAddress(pTarget) && IsExecutableAddress(pDetour))
+ {
+ UINT pos = FindHookEntry(pTarget);
+ if (pos == INVALID_HOOK_POS)
+ {
+ LPVOID pBuffer = AllocateBuffer(pTarget);
+ if (pBuffer != NULL)
+ {
+ TRAMPOLINE ct;
+
+ ct.pTarget = pTarget;
+ ct.pDetour = pDetour;
+ ct.pTrampoline = pBuffer;
+ if (CreateTrampolineFunction(&ct))
+ {
+ PHOOK_ENTRY pHook = AddHookEntry();
+ if (pHook != NULL)
+ {
+ pHook->pTarget = ct.pTarget;
+#if defined(_M_X64) || defined(__x86_64__)
+ pHook->pDetour = ct.pRelay;
+#else
+ pHook->pDetour = ct.pDetour;
+#endif
+ pHook->pTrampoline = ct.pTrampoline;
+ pHook->patchAbove = ct.patchAbove;
+ pHook->isEnabled = FALSE;
+ pHook->queueEnable = FALSE;
+ pHook->nIP = ct.nIP;
+ memcpy(pHook->oldIPs, ct.oldIPs, ARRAYSIZE(ct.oldIPs));
+ memcpy(pHook->newIPs, ct.newIPs, ARRAYSIZE(ct.newIPs));
+
+ // Back up the target function.
+
+ if (ct.patchAbove)
+ {
+ memcpy(
+ pHook->backup,
+ (LPBYTE)pTarget - sizeof(JMP_REL),
+ sizeof(JMP_REL) + sizeof(JMP_REL_SHORT));
+ }
+ else
+ {
+ memcpy(pHook->backup, pTarget, sizeof(JMP_REL));
+ }
+
+ if (ppOriginal != NULL)
+ *ppOriginal = pHook->pTrampoline;
+ }
+ else
+ {
+ status = MH_ERROR_MEMORY_ALLOC;
+ }
+ }
+ else
+ {
+ status = MH_ERROR_UNSUPPORTED_FUNCTION;
+ }
+
+ if (status != MH_OK)
+ {
+ FreeBuffer(pBuffer);
+ }
+ }
+ else
+ {
+ status = MH_ERROR_MEMORY_ALLOC;
+ }
+ }
+ else
+ {
+ status = MH_ERROR_ALREADY_CREATED;
+ }
+ }
+ else
+ {
+ status = MH_ERROR_NOT_EXECUTABLE;
+ }
+ }
+ else
+ {
+ status = MH_ERROR_NOT_INITIALIZED;
+ }
+
+ LeaveSpinLock();
+
+ return status;
+}
+
+//-------------------------------------------------------------------------
+MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget)
+{
+ MH_STATUS status = MH_OK;
+
+ EnterSpinLock();
+
+ if (g_hHeap != NULL)
+ {
+ UINT pos = FindHookEntry(pTarget);
+ if (pos != INVALID_HOOK_POS)
+ {
+ if (g_hooks.pItems[pos].isEnabled)
+ {
+ FROZEN_THREADS threads;
+ Freeze(&threads, pos, ACTION_DISABLE);
+
+ status = EnableHookLL(pos, FALSE);
+
+ Unfreeze(&threads);
+ }
+
+ if (status == MH_OK)
+ {
+ FreeBuffer(g_hooks.pItems[pos].pTrampoline);
+ DeleteHookEntry(pos);
+ }
+ }
+ else
+ {
+ status = MH_ERROR_NOT_CREATED;
+ }
+ }
+ else
+ {
+ status = MH_ERROR_NOT_INITIALIZED;
+ }
+
+ LeaveSpinLock();
+
+ return status;
+}
+
+//-------------------------------------------------------------------------
+static MH_STATUS EnableHook(LPVOID pTarget, BOOL enable)
+{
+ MH_STATUS status = MH_OK;
+
+ EnterSpinLock();
+
+ if (g_hHeap != NULL)
+ {
+ if (pTarget == MH_ALL_HOOKS)
+ {
+ status = EnableAllHooksLL(enable);
+ }
+ else
+ {
+ FROZEN_THREADS threads;
+ UINT pos = FindHookEntry(pTarget);
+ if (pos != INVALID_HOOK_POS)
+ {
+ if (g_hooks.pItems[pos].isEnabled != enable)
+ {
+ Freeze(&threads, pos, ACTION_ENABLE);
+
+ status = EnableHookLL(pos, enable);
+
+ Unfreeze(&threads);
+ }
+ else
+ {
+ status = enable ? MH_ERROR_ENABLED : MH_ERROR_DISABLED;
+ }
+ }
+ else
+ {
+ status = MH_ERROR_NOT_CREATED;
+ }
+ }
+ }
+ else
+ {
+ status = MH_ERROR_NOT_INITIALIZED;
+ }
+
+ LeaveSpinLock();
+
+ return status;
+}
+
+//-------------------------------------------------------------------------
+MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget)
+{
+ return EnableHook(pTarget, TRUE);
+}
+
+//-------------------------------------------------------------------------
+MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget)
+{
+ return EnableHook(pTarget, FALSE);
+}
+
+//-------------------------------------------------------------------------
+static MH_STATUS QueueHook(LPVOID pTarget, BOOL queueEnable)
+{
+ MH_STATUS status = MH_OK;
+
+ EnterSpinLock();
+
+ if (g_hHeap != NULL)
+ {
+ if (pTarget == MH_ALL_HOOKS)
+ {
+ UINT i;
+ for (i = 0; i < g_hooks.size; ++i)
+ g_hooks.pItems[i].queueEnable = queueEnable;
+ }
+ else
+ {
+ UINT pos = FindHookEntry(pTarget);
+ if (pos != INVALID_HOOK_POS)
+ {
+ g_hooks.pItems[pos].queueEnable = queueEnable;
+ }
+ else
+ {
+ status = MH_ERROR_NOT_CREATED;
+ }
+ }
+ }
+ else
+ {
+ status = MH_ERROR_NOT_INITIALIZED;
+ }
+
+ LeaveSpinLock();
+
+ return status;
+}
+
+//-------------------------------------------------------------------------
+MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget)
+{
+ return QueueHook(pTarget, TRUE);
+}
+
+//-------------------------------------------------------------------------
+MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget)
+{
+ return QueueHook(pTarget, FALSE);
+}
+
+//-------------------------------------------------------------------------
+MH_STATUS WINAPI MH_ApplyQueued(VOID)
+{
+ MH_STATUS status = MH_OK;
+ UINT i, first = INVALID_HOOK_POS;
+
+ EnterSpinLock();
+
+ if (g_hHeap != NULL)
+ {
+ for (i = 0; i < g_hooks.size; ++i)
+ {
+ if (g_hooks.pItems[i].isEnabled != g_hooks.pItems[i].queueEnable)
+ {
+ first = i;
+ break;
+ }
+ }
+
+ if (first != INVALID_HOOK_POS)
+ {
+ FROZEN_THREADS threads;
+ Freeze(&threads, ALL_HOOKS_POS, ACTION_APPLY_QUEUED);
+
+ for (i = first; i < g_hooks.size; ++i)
+ {
+ PHOOK_ENTRY pHook = &g_hooks.pItems[i];
+ if (pHook->isEnabled != pHook->queueEnable)
+ {
+ status = EnableHookLL(i, pHook->queueEnable);
+ if (status != MH_OK)
+ break;
+ }
+ }
+
+ Unfreeze(&threads);
+ }
+ }
+ else
+ {
+ status = MH_ERROR_NOT_INITIALIZED;
+ }
+
+ LeaveSpinLock();
+
+ return status;
+}
+
+//-------------------------------------------------------------------------
+MH_STATUS WINAPI MH_CreateHookApiEx(
+ LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour,
+ LPVOID *ppOriginal, LPVOID *ppTarget)
+{
+ HMODULE hModule;
+ LPVOID pTarget;
+
+ hModule = GetModuleHandleW(pszModule);
+ if (hModule == NULL)
+ return MH_ERROR_MODULE_NOT_FOUND;
+
+ pTarget = (LPVOID)GetProcAddress(hModule, pszProcName);
+ if (pTarget == NULL)
+ return MH_ERROR_FUNCTION_NOT_FOUND;
+
+ if(ppTarget != NULL)
+ *ppTarget = pTarget;
+
+ return MH_CreateHook(pTarget, pDetour, ppOriginal);
+}
+
+//-------------------------------------------------------------------------
+MH_STATUS WINAPI MH_CreateHookApi(
+ LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal)
+{
+ return MH_CreateHookApiEx(pszModule, pszProcName, pDetour, ppOriginal, NULL);
+}
+
+//-------------------------------------------------------------------------
+const char * WINAPI MH_StatusToString(MH_STATUS status)
+{
+#define MH_ST2STR(x) \
+ case x: \
+ return #x;
+
+ switch (status) {
+ MH_ST2STR(MH_UNKNOWN)
+ MH_ST2STR(MH_OK)
+ MH_ST2STR(MH_ERROR_ALREADY_INITIALIZED)
+ MH_ST2STR(MH_ERROR_NOT_INITIALIZED)
+ MH_ST2STR(MH_ERROR_ALREADY_CREATED)
+ MH_ST2STR(MH_ERROR_NOT_CREATED)
+ MH_ST2STR(MH_ERROR_ENABLED)
+ MH_ST2STR(MH_ERROR_DISABLED)
+ MH_ST2STR(MH_ERROR_NOT_EXECUTABLE)
+ MH_ST2STR(MH_ERROR_UNSUPPORTED_FUNCTION)
+ MH_ST2STR(MH_ERROR_MEMORY_ALLOC)
+ MH_ST2STR(MH_ERROR_MEMORY_PROTECT)
+ MH_ST2STR(MH_ERROR_MODULE_NOT_FOUND)
+ MH_ST2STR(MH_ERROR_FUNCTION_NOT_FOUND)
+ }
+
+#undef MH_ST2STR
+
+ return "(unknown)";
+}
diff --git a/deps/minhook/src/trampoline.c b/deps/minhook/src/trampoline.c
new file mode 100644
index 0000000..c267088
--- /dev/null
+++ b/deps/minhook/src/trampoline.c
@@ -0,0 +1,320 @@
+/*
+ * MinHook - The Minimalistic API Hooking Library for x64/x86
+ * Copyright (C) 2009-2017 Tsuda Kageyu.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include
+
+#ifdef _MSC_VER
+ #include
+#endif
+
+#ifndef ARRAYSIZE
+ #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
+#endif
+
+#if defined(_M_X64) || defined(__x86_64__)
+ #include "./hde/hde64.h"
+ typedef hde64s HDE;
+ #define HDE_DISASM(code, hs) hde64_disasm(code, hs)
+#else
+ #include "./hde/hde32.h"
+ typedef hde32s HDE;
+ #define HDE_DISASM(code, hs) hde32_disasm(code, hs)
+#endif
+
+#include "trampoline.h"
+#include "buffer.h"
+
+// Maximum size of a trampoline function.
+#if defined(_M_X64) || defined(__x86_64__)
+ #define TRAMPOLINE_MAX_SIZE (MEMORY_SLOT_SIZE - sizeof(JMP_ABS))
+#else
+ #define TRAMPOLINE_MAX_SIZE MEMORY_SLOT_SIZE
+#endif
+
+//-------------------------------------------------------------------------
+static BOOL IsCodePadding(LPBYTE pInst, UINT size)
+{
+ UINT i;
+
+ if (pInst[0] != 0x00 && pInst[0] != 0x90 && pInst[0] != 0xCC)
+ return FALSE;
+
+ for (i = 1; i < size; ++i)
+ {
+ if (pInst[i] != pInst[0])
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//-------------------------------------------------------------------------
+BOOL CreateTrampolineFunction(PTRAMPOLINE ct)
+{
+#if defined(_M_X64) || defined(__x86_64__)
+ CALL_ABS call = {
+ 0xFF, 0x15, 0x00000002, // FF15 00000002: CALL [RIP+8]
+ 0xEB, 0x08, // EB 08: JMP +10
+ 0x0000000000000000ULL // Absolute destination address
+ };
+ JMP_ABS jmp = {
+ 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6]
+ 0x0000000000000000ULL // Absolute destination address
+ };
+ JCC_ABS jcc = {
+ 0x70, 0x0E, // 7* 0E: J** +16
+ 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6]
+ 0x0000000000000000ULL // Absolute destination address
+ };
+#else
+ CALL_REL call = {
+ 0xE8, // E8 xxxxxxxx: CALL +5+xxxxxxxx
+ 0x00000000 // Relative destination address
+ };
+ JMP_REL jmp = {
+ 0xE9, // E9 xxxxxxxx: JMP +5+xxxxxxxx
+ 0x00000000 // Relative destination address
+ };
+ JCC_REL jcc = {
+ 0x0F, 0x80, // 0F8* xxxxxxxx: J** +6+xxxxxxxx
+ 0x00000000 // Relative destination address
+ };
+#endif
+
+ UINT8 oldPos = 0;
+ UINT8 newPos = 0;
+ ULONG_PTR jmpDest = 0; // Destination address of an internal jump.
+ BOOL finished = FALSE; // Is the function completed?
+#if defined(_M_X64) || defined(__x86_64__)
+ UINT8 instBuf[16];
+#endif
+
+ ct->patchAbove = FALSE;
+ ct->nIP = 0;
+
+ do
+ {
+ HDE hs;
+ UINT copySize;
+ LPVOID pCopySrc;
+ ULONG_PTR pOldInst = (ULONG_PTR)ct->pTarget + oldPos;
+ ULONG_PTR pNewInst = (ULONG_PTR)ct->pTrampoline + newPos;
+
+ copySize = HDE_DISASM((LPVOID)pOldInst, &hs);
+ if (hs.flags & F_ERROR)
+ return FALSE;
+
+ pCopySrc = (LPVOID)pOldInst;
+ if (oldPos >= sizeof(JMP_REL))
+ {
+ // The trampoline function is long enough.
+ // Complete the function with the jump to the target function.
+#if defined(_M_X64) || defined(__x86_64__)
+ jmp.address = pOldInst;
+#else
+ jmp.operand = (UINT32)(pOldInst - (pNewInst + sizeof(jmp)));
+#endif
+ pCopySrc = &jmp;
+ copySize = sizeof(jmp);
+
+ finished = TRUE;
+ }
+#if defined(_M_X64) || defined(__x86_64__)
+ else if ((hs.modrm & 0xC7) == 0x05)
+ {
+ // Instructions using RIP relative addressing. (ModR/M = 00???101B)
+
+ // Modify the RIP relative address.
+ PUINT32 pRelAddr;
+
+ // Avoid using memcpy to reduce the footprint.
+#ifndef _MSC_VER
+ memcpy(instBuf, (LPBYTE)pOldInst, copySize);
+#else
+ __movsb(instBuf, (LPBYTE)pOldInst, copySize);
+#endif
+ pCopySrc = instBuf;
+
+ // Relative address is stored at (instruction length - immediate value length - 4).
+ pRelAddr = (PUINT32)(instBuf + hs.len - ((hs.flags & 0x3C) >> 2) - 4);
+ *pRelAddr
+ = (UINT32)((pOldInst + hs.len + (INT32)hs.disp.disp32) - (pNewInst + hs.len));
+
+ // Complete the function if JMP (FF /4).
+ if (hs.opcode == 0xFF && hs.modrm_reg == 4)
+ finished = TRUE;
+ }
+#endif
+ else if (hs.opcode == 0xE8)
+ {
+ // Direct relative CALL
+ ULONG_PTR dest = pOldInst + hs.len + (INT32)hs.imm.imm32;
+#if defined(_M_X64) || defined(__x86_64__)
+ call.address = dest;
+#else
+ call.operand = (UINT32)(dest - (pNewInst + sizeof(call)));
+#endif
+ pCopySrc = &call;
+ copySize = sizeof(call);
+ }
+ else if ((hs.opcode & 0xFD) == 0xE9)
+ {
+ // Direct relative JMP (EB or E9)
+ ULONG_PTR dest = pOldInst + hs.len;
+
+ if (hs.opcode == 0xEB) // isShort jmp
+ dest += (INT8)hs.imm.imm8;
+ else
+ dest += (INT32)hs.imm.imm32;
+
+ // Simply copy an internal jump.
+ if ((ULONG_PTR)ct->pTarget <= dest
+ && dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL)))
+ {
+ if (jmpDest < dest)
+ jmpDest = dest;
+ }
+ else
+ {
+#if defined(_M_X64) || defined(__x86_64__)
+ jmp.address = dest;
+#else
+ jmp.operand = (UINT32)(dest - (pNewInst + sizeof(jmp)));
+#endif
+ pCopySrc = &jmp;
+ copySize = sizeof(jmp);
+
+ // Exit the function If it is not in the branch
+ finished = (pOldInst >= jmpDest);
+ }
+ }
+ else if ((hs.opcode & 0xF0) == 0x70
+ || (hs.opcode & 0xFC) == 0xE0
+ || (hs.opcode2 & 0xF0) == 0x80)
+ {
+ // Direct relative Jcc
+ ULONG_PTR dest = pOldInst + hs.len;
+
+ if ((hs.opcode & 0xF0) == 0x70 // Jcc
+ || (hs.opcode & 0xFC) == 0xE0) // LOOPNZ/LOOPZ/LOOP/JECXZ
+ dest += (INT8)hs.imm.imm8;
+ else
+ dest += (INT32)hs.imm.imm32;
+
+ // Simply copy an internal jump.
+ if ((ULONG_PTR)ct->pTarget <= dest
+ && dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL)))
+ {
+ if (jmpDest < dest)
+ jmpDest = dest;
+ }
+ else if ((hs.opcode & 0xFC) == 0xE0)
+ {
+ // LOOPNZ/LOOPZ/LOOP/JCXZ/JECXZ to the outside are not supported.
+ return FALSE;
+ }
+ else
+ {
+ UINT8 cond = ((hs.opcode != 0x0F ? hs.opcode : hs.opcode2) & 0x0F);
+#if defined(_M_X64) || defined(__x86_64__)
+ // Invert the condition in x64 mode to simplify the conditional jump logic.
+ jcc.opcode = 0x71 ^ cond;
+ jcc.address = dest;
+#else
+ jcc.opcode1 = 0x80 | cond;
+ jcc.operand = (UINT32)(dest - (pNewInst + sizeof(jcc)));
+#endif
+ pCopySrc = &jcc;
+ copySize = sizeof(jcc);
+ }
+ }
+ else if ((hs.opcode & 0xFE) == 0xC2)
+ {
+ // RET (C2 or C3)
+
+ // Complete the function if not in a branch.
+ finished = (pOldInst >= jmpDest);
+ }
+
+ // Can't alter the instruction length in a branch.
+ if (pOldInst < jmpDest && copySize != hs.len)
+ return FALSE;
+
+ // Trampoline function is too large.
+ if ((newPos + copySize) > TRAMPOLINE_MAX_SIZE)
+ return FALSE;
+
+ // Trampoline function has too many instructions.
+ if (ct->nIP >= ARRAYSIZE(ct->oldIPs))
+ return FALSE;
+
+ ct->oldIPs[ct->nIP] = oldPos;
+ ct->newIPs[ct->nIP] = newPos;
+ ct->nIP++;
+
+ // Avoid using memcpy to reduce the footprint.
+#ifndef _MSC_VER
+ memcpy((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize);
+#else
+ __movsb((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize);
+#endif
+ newPos += copySize;
+ oldPos += hs.len;
+ }
+ while (!finished);
+
+ // Is there enough place for a long jump?
+ if (oldPos < sizeof(JMP_REL)
+ && !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL) - oldPos))
+ {
+ // Is there enough place for a short jump?
+ if (oldPos < sizeof(JMP_REL_SHORT)
+ && !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL_SHORT) - oldPos))
+ {
+ return FALSE;
+ }
+
+ // Can we place the long jump above the function?
+ if (!IsExecutableAddress((LPBYTE)ct->pTarget - sizeof(JMP_REL)))
+ return FALSE;
+
+ if (!IsCodePadding((LPBYTE)ct->pTarget - sizeof(JMP_REL), sizeof(JMP_REL)))
+ return FALSE;
+
+ ct->patchAbove = TRUE;
+ }
+
+#if defined(_M_X64) || defined(__x86_64__)
+ // Create a relay function.
+ jmp.address = (ULONG_PTR)ct->pDetour;
+
+ ct->pRelay = (LPBYTE)ct->pTrampoline + newPos;
+ memcpy(ct->pRelay, &jmp, sizeof(jmp));
+#endif
+
+ return TRUE;
+}
diff --git a/deps/minhook/src/trampoline.h b/deps/minhook/src/trampoline.h
new file mode 100644
index 0000000..bdffdac
--- /dev/null
+++ b/deps/minhook/src/trampoline.h
@@ -0,0 +1,105 @@
+/*
+ * MinHook - The Minimalistic API Hooking Library for x64/x86
+ * Copyright (C) 2009-2017 Tsuda Kageyu.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#pragma once
+
+#pragma pack(push, 1)
+
+// Structs for writing x86/x64 instructions.
+
+// 8-bit relative jump.
+typedef struct _JMP_REL_SHORT
+{
+ UINT8 opcode; // EB xx: JMP +2+xx
+ UINT8 operand;
+} JMP_REL_SHORT, *PJMP_REL_SHORT;
+
+// 32-bit direct relative jump/call.
+typedef struct _JMP_REL
+{
+ UINT8 opcode; // E9/E8 xxxxxxxx: JMP/CALL +5+xxxxxxxx
+ UINT32 operand; // Relative destination address
+} JMP_REL, *PJMP_REL, CALL_REL;
+
+// 64-bit indirect absolute jump.
+typedef struct _JMP_ABS
+{
+ UINT8 opcode0; // FF25 00000000: JMP [+6]
+ UINT8 opcode1;
+ UINT32 dummy;
+ UINT64 address; // Absolute destination address
+} JMP_ABS, *PJMP_ABS;
+
+// 64-bit indirect absolute call.
+typedef struct _CALL_ABS
+{
+ UINT8 opcode0; // FF15 00000002: CALL [+6]
+ UINT8 opcode1;
+ UINT32 dummy0;
+ UINT8 dummy1; // EB 08: JMP +10
+ UINT8 dummy2;
+ UINT64 address; // Absolute destination address
+} CALL_ABS;
+
+// 32-bit direct relative conditional jumps.
+typedef struct _JCC_REL
+{
+ UINT8 opcode0; // 0F8* xxxxxxxx: J** +6+xxxxxxxx
+ UINT8 opcode1;
+ UINT32 operand; // Relative destination address
+} JCC_REL;
+
+// 64bit indirect absolute conditional jumps that x64 lacks.
+typedef struct _JCC_ABS
+{
+ UINT8 opcode; // 7* 0E: J** +16
+ UINT8 dummy0;
+ UINT8 dummy1; // FF25 00000000: JMP [+6]
+ UINT8 dummy2;
+ UINT32 dummy3;
+ UINT64 address; // Absolute destination address
+} JCC_ABS;
+
+#pragma pack(pop)
+
+typedef struct _TRAMPOLINE
+{
+ LPVOID pTarget; // [In] Address of the target function.
+ LPVOID pDetour; // [In] Address of the detour function.
+ LPVOID pTrampoline; // [In] Buffer address for the trampoline and relay function.
+
+#if defined(_M_X64) || defined(__x86_64__)
+ LPVOID pRelay; // [Out] Address of the relay function.
+#endif
+ BOOL patchAbove; // [Out] Should use the hot patch area?
+ UINT nIP; // [Out] Number of the instruction boundaries.
+ UINT8 oldIPs[8]; // [Out] Instruction boundaries of the target function.
+ UINT8 newIPs[8]; // [Out] Instruction boundaries of the trampoline function.
+} TRAMPOLINE, *PTRAMPOLINE;
+
+BOOL CreateTrampolineFunction(PTRAMPOLINE ct);
diff --git a/deps/rapidjson.lua b/deps/rapidjson.lua
new file mode 100644
index 0000000..1c07432
--- /dev/null
+++ b/deps/rapidjson.lua
@@ -0,0 +1,18 @@
+rapidjson = {
+ source = path.join(dependencies.basePath, "rapidjson"),
+}
+
+function rapidjson.import()
+ rapidjson.includes()
+end
+
+function rapidjson.includes()
+ includedirs {
+ path.join(rapidjson.source, "include")
+ }
+end
+
+function rapidjson.project()
+end
+
+table.insert(dependencies, rapidjson)
diff --git a/deps/rapidjson/.gitattributes b/deps/rapidjson/.gitattributes
new file mode 100644
index 0000000..6f598bb
--- /dev/null
+++ b/deps/rapidjson/.gitattributes
@@ -0,0 +1,22 @@
+# Set the default behavior, in case people don't have core.autocrlf set.
+* text=auto
+
+# Explicitly declare text files you want to always be normalized and converted
+# to native line endings on checkout.
+*.cpp text
+*.h text
+*.txt text
+*.md text
+*.cmake text
+*.svg text
+*.dot text
+*.yml text
+*.in text
+*.sh text
+*.autopkg text
+Dockerfile text
+
+# Denote all files that are truly binary and should not be modified.
+*.png binary
+*.jpg binary
+*.json binary
\ No newline at end of file
diff --git a/deps/rapidjson/.gitignore b/deps/rapidjson/.gitignore
new file mode 100644
index 0000000..5932e82
--- /dev/null
+++ b/deps/rapidjson/.gitignore
@@ -0,0 +1,29 @@
+/bin/*
+!/bin/data
+!/bin/encodings
+!/bin/jsonchecker
+!/bin/types
+!/bin/unittestschema
+/build
+/doc/html
+/doc/doxygen_*.db
+*.a
+
+# Temporary files created during CMake build
+CMakeCache.txt
+CMakeFiles
+cmake_install.cmake
+CTestTestfile.cmake
+Makefile
+RapidJSON*.cmake
+RapidJSON.pc
+Testing
+/googletest
+install_manifest.txt
+Doxyfile
+Doxyfile.zh-cn
+DartConfiguration.tcl
+*.nupkg
+
+# Files created by OS
+*.DS_Store
diff --git a/deps/rapidjson/.gitmodules b/deps/rapidjson/.gitmodules
new file mode 100644
index 0000000..5e41f7c
--- /dev/null
+++ b/deps/rapidjson/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "thirdparty/gtest"]
+ path = thirdparty/gtest
+ url = https://github.com/google/googletest.git
diff --git a/deps/rapidjson/.travis.yml b/deps/rapidjson/.travis.yml
new file mode 100644
index 0000000..17d8f03
--- /dev/null
+++ b/deps/rapidjson/.travis.yml
@@ -0,0 +1,166 @@
+sudo: required
+dist: xenial
+
+language: cpp
+cache:
+ - ccache
+
+addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - cmake
+ - valgrind
+ - clang-8
+env:
+ global:
+ - USE_CCACHE=1
+ - CCACHE_SLOPPINESS=pch_defines,time_macros
+ - CCACHE_COMPRESS=1
+ - CCACHE_MAXSIZE=100M
+ - ARCH_FLAGS_x86='-m32' # #266: don't use SSE on 32-bit
+ - ARCH_FLAGS_x86_64='-msse4.2' # use SSE4.2 on 64-bit
+ - ARCH_FLAGS_aarch64='-march=armv8-a'
+ - GITHUB_REPO='Tencent/rapidjson'
+ - secure: "HrsaCb+N66EG1HR+LWH1u51SjaJyRwJEDzqJGYMB7LJ/bfqb9mWKF1fLvZGk46W5t7TVaXRDD5KHFx9DPWvKn4gRUVkwTHEy262ah5ORh8M6n/6VVVajeV/AYt2C0sswdkDBDO4Xq+xy5gdw3G8s1A4Inbm73pUh+6vx+7ltBbk="
+
+matrix:
+ include:
+ # gcc
+ - env: CONF=release ARCH=x86 CXX11=ON CXX17=OFF MEMBERSMAP=OFF
+ compiler: gcc
+ arch: amd64
+ - env: CONF=release ARCH=x86_64 CXX11=ON CXX17=OFF MEMBERSMAP=OFF
+ compiler: gcc
+ arch: amd64
+ - env: CONF=release ARCH=x86_64 CXX11=ON CXX17=OFF MEMBERSMAP=ON
+ compiler: gcc
+ arch: amd64
+ - env: CONF=debug ARCH=x86 CXX11=OFF CXX17=OFF MEMBERSMAP=OFF
+ compiler: gcc
+ arch: amd64
+ - env: CONF=debug ARCH=x86_64 CXX11=OFF CXX17=OFF MEMBERSMAP=OFF
+ compiler: gcc
+ arch: amd64
+ - env: CONF=debug ARCH=x86 CXX11=OFF CXX17=ON MEMBERSMAP=ON CXX_FLAGS='-D_GLIBCXX_DEBUG'
+ compiler: gcc
+ arch: amd64
+ - env: CONF=debug ARCH=x86_64 CXX11=OFF CXX17=ON MEMBERSMAP=ON CXX_FLAGS='-D_GLIBCXX_DEBUG'
+ compiler: gcc
+ arch: amd64
+ - env: CONF=release ARCH=aarch64 CXX11=ON CXX17=OFF MEMBERSMAP=OFF
+ compiler: gcc
+ arch: arm64
+ - env: CONF=release ARCH=aarch64 CXX11=OFF CXX17=OFF MEMBERSMAP=OFF
+ compiler: gcc
+ arch: arm64
+ - env: CONF=release ARCH=aarch64 CXX11=OFF CXX17=ON MEMBERSMAP=ON
+ compiler: gcc
+ arch: arm64
+ # clang
+ - env: CONF=release ARCH=x86 CXX11=ON CXX17=OFF MEMBERSMAP=ON CCACHE_CPP2=yes
+ compiler: clang
+ arch: amd64
+ - env: CONF=release ARCH=x86_64 CXX11=ON CXX17=OFF MEMBERSMAP=ON CCACHE_CPP2=yes
+ compiler: clang
+ arch: amd64
+ - env: CONF=release ARCH=x86_64 CXX11=ON CXX17=OFF MEMBERSMAP=OFF CCACHE_CPP2=yes
+ compiler: clang
+ arch: amd64
+ - env: CONF=debug ARCH=x86 CXX11=OFF CXX17=OFF MEMBERSMAP=ON CCACHE_CPP2=yes
+ compiler: clang
+ arch: amd64
+ - env: CONF=debug ARCH=x86_64 CXX11=OFF CXX17=OFF MEMBERSMAP=ON CCACHE_CPP2=yes
+ compiler: clang
+ arch: amd64
+ - env: CONF=debug ARCH=x86 CXX11=OFF CXX17=ON MEMBERSMAP=OFF CCACHE_CPP2=yes
+ compiler: clang
+ arch: amd64
+ - env: CONF=debug ARCH=x86_64 CXX11=OFF CXX17=ON MEMBERSMAP=OFF CCACHE_CPP2=yes
+ compiler: clang
+ arch: amd64
+ - env: CONF=debug ARCH=aarch64 CXX11=ON CXX17=OFF MEMBERSMAP=ON CCACHE_CPP2=yes
+ compiler: clang
+ arch: arm64
+ - env: CONF=debug ARCH=aarch64 CXX11=OFF CXX17=OFF MEMBERSMAP=ON CCACHE_CPP2=yes
+ compiler: clang
+ arch: arm64
+ - env: CONF=debug ARCH=aarch64 CXX11=OFF CXX17=ON MEMBERSMAP=OFF CCACHE_CPP2=yes
+ compiler: clang
+ arch: arm64
+ # coverage report
+ - env: CONF=debug ARCH=x86 GCOV_FLAGS='--coverage' CXX_FLAGS='-O0' CXX11=OFF CXX17=OFF
+ compiler: gcc
+ arch: amd64
+ cache:
+ - ccache
+ - pip
+ after_success:
+ - pip install --user cpp-coveralls
+ - coveralls -r .. --gcov-options '\-lp' -e thirdparty -e example -e test -e build/CMakeFiles -e include/rapidjson/msinttypes -e include/rapidjson/internal/meta.h -e include/rapidjson/error/en.h
+ - env: CONF=debug ARCH=x86_64 GCOV_FLAGS='--coverage' CXX_FLAGS='-O0' CXX11=ON CXX17=OFF MEMBERSMAP=ON
+ compiler: gcc
+ arch: amd64
+ cache:
+ - ccache
+ - pip
+ after_success:
+ - pip install --user cpp-coveralls
+ - coveralls -r .. --gcov-options '\-lp' -e thirdparty -e example -e test -e build/CMakeFiles -e include/rapidjson/msinttypes -e include/rapidjson/internal/meta.h -e include/rapidjson/error/en.h
+ - env: CONF=debug ARCH=aarch64 GCOV_FLAGS='--coverage' CXX_FLAGS='-O0' CXX11=OFF CXX17=ON
+ compiler: gcc
+ arch: arm64
+ cache:
+ - ccache
+ - pip
+ after_success:
+ - pip install --user cpp-coveralls
+ - coveralls -r .. --gcov-options '\-lp' -e thirdparty -e example -e test -e build/CMakeFiles -e include/rapidjson/msinttypes -e include/rapidjson/internal/meta.h -e include/rapidjson/error/en.h
+ - script: # Documentation task
+ - cd build
+ - cmake .. -DRAPIDJSON_HAS_STDSTRING=ON -DCMAKE_VERBOSE_MAKEFILE=ON
+ - make travis_doc
+ cache: false
+ addons:
+ apt:
+ packages:
+ - doxygen
+
+before_install:
+ - if [ "x86_64" = "$(arch)" ]; then sudo apt-get install -y g++-multilib libc6-dbg:i386 --allow-unauthenticated; fi
+
+before_script:
+ # travis provides clang-7 for amd64 and clang-3.8 for arm64
+ # here use clang-8 to all architectures as clang-7 is not available for arm64
+ - if [ -f /usr/bin/clang++-8 ]; then
+ sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-8 1000;
+ sudo update-alternatives --config clang++;
+ export PATH=/usr/bin:$PATH;
+ fi
+ - if [ "$CXX" = "clang++" ]; then export CCACHE_CPP2=yes; fi
+ - ccache -s
+ # hack to avoid Valgrind bug (https://bugs.kde.org/show_bug.cgi?id=326469),
+ # exposed by merging PR#163 (using -march=native)
+ # TODO: Since this bug is already fixed. Remove this when valgrind can be upgraded.
+ - sed -i "s/-march=native//" CMakeLists.txt
+ - mkdir build
+
+script:
+ - if [ "$CXX" = "clang++" ]; then export CXXFLAGS="-stdlib=libc++ ${CXXFLAGS}"; fi
+ - >
+ eval "ARCH_FLAGS=\${ARCH_FLAGS_${ARCH}}" ;
+ (cd build && cmake
+ -DRAPIDJSON_HAS_STDSTRING=ON
+ -DRAPIDJSON_USE_MEMBERSMAP=$MEMBERSMAP
+ -DRAPIDJSON_BUILD_CXX11=$CXX11
+ -DRAPIDJSON_BUILD_CXX17=$CXX17
+ -DCMAKE_VERBOSE_MAKEFILE=ON
+ -DCMAKE_BUILD_TYPE=$CONF
+ -DCMAKE_CXX_FLAGS="$ARCH_FLAGS $GCOV_FLAGS $CXX_FLAGS"
+ -DCMAKE_EXE_LINKER_FLAGS=$GCOV_FLAGS
+ ..)
+ - cd build
+ - make tests -j 2
+ - make examples -j 2
+ - ctest -j 2 -V `[ "$CONF" = "release" ] || echo "-E perftest"`
diff --git a/deps/rapidjson/CHANGELOG.md b/deps/rapidjson/CHANGELOG.md
new file mode 100644
index 0000000..1c580bd
--- /dev/null
+++ b/deps/rapidjson/CHANGELOG.md
@@ -0,0 +1,158 @@
+# Change Log
+All notable changes to this project will be documented in this file.
+This project adheres to [Semantic Versioning](http://semver.org/).
+
+## [Unreleased]
+
+## 1.1.0 - 2016-08-25
+
+### Added
+* Add GenericDocument ctor overload to specify JSON type (#369)
+* Add FAQ (#372, #373, #374, #376)
+* Add forward declaration header `fwd.h`
+* Add @PlatformIO Library Registry manifest file (#400)
+* Implement assignment operator for BigInteger (#404)
+* Add comments support (#443)
+* Adding coapp definition (#460)
+* documenttest.cpp: EXPECT_THROW when checking empty allocator (470)
+* GenericDocument: add implicit conversion to ParseResult (#480)
+* Use with C++ linkage on Windows ARM (#485)
+* Detect little endian for Microsoft ARM targets
+* Check Nan/Inf when writing a double (#510)
+* Add JSON Schema Implementation (#522)
+* Add iostream wrapper (#530)
+* Add Jsonx example for converting JSON into JSONx (a XML format) (#531)
+* Add optional unresolvedTokenIndex parameter to Pointer::Get() (#532)
+* Add encoding validation option for Writer/PrettyWriter (#534)
+* Add Writer::SetMaxDecimalPlaces() (#536)
+* Support {0, } and {0, m} in Regex (#539)
+* Add Value::Get/SetFloat(), Value::IsLossLessFloat/Double() (#540)
+* Add stream position check to reader unit tests (#541)
+* Add Templated accessors and range-based for (#542)
+* Add (Pretty)Writer::RawValue() (#543)
+* Add Document::Parse(std::string), Document::Parse(const char*, size_t length) and related APIs. (#553)
+* Add move constructor for GenericSchemaDocument (#554)
+* Add VS2010 and VS2015 to AppVeyor CI (#555)
+* Add parse-by-parts example (#556, #562)
+* Support parse number as string (#564, #589)
+* Add kFormatSingleLineArray for PrettyWriter (#577)
+* Added optional support for trailing commas (#584)
+* Added filterkey and filterkeydom examples (#615)
+* Added npm docs (#639)
+* Allow options for writing and parsing NaN/Infinity (#641)
+* Add std::string overload to PrettyWriter::Key() when RAPIDJSON_HAS_STDSTRING is defined (#698)
+
+### Fixed
+* Fix gcc/clang/vc warnings (#350, #394, #397, #444, #447, #473, #515, #582, #589, #595, #667)
+* Fix documentation (#482, #511, #550, #557, #614, #635, #660)
+* Fix emscripten alignment issue (#535)
+* Fix missing allocator to uses of AddMember in document (#365)
+* CMake will no longer complain that the minimum CMake version is not specified (#501)
+* Make it usable with old VC8 (VS2005) (#383)
+* Prohibit C++11 move from Document to Value (#391)
+* Try to fix incorrect 64-bit alignment (#419)
+* Check return of fwrite to avoid warn_unused_result build failures (#421)
+* Fix UB in GenericDocument::ParseStream (#426)
+* Keep Document value unchanged on parse error (#439)
+* Add missing return statement (#450)
+* Fix Document::Parse(const Ch*) for transcoding (#478)
+* encodings.h: fix typo in preprocessor condition (#495)
+* Custom Microsoft headers are necessary only for Visual Studio 2012 and lower (#559)
+* Fix memory leak for invalid regex (26e69ffde95ba4773ab06db6457b78f308716f4b)
+* Fix a bug in schema minimum/maximum keywords for 64-bit integer (e7149d665941068ccf8c565e77495521331cf390)
+* Fix a crash bug in regex (#605)
+* Fix schema "required" keyword cannot handle duplicated keys (#609)
+* Fix cmake CMP0054 warning (#612)
+* Added missing include guards in istreamwrapper.h and ostreamwrapper.h (#634)
+* Fix undefined behaviour (#646)
+* Fix buffer overrun using PutN (#673)
+* Fix rapidjson::value::Get() may returns wrong data (#681)
+* Add Flush() for all value types (#689)
+* Handle malloc() fail in PoolAllocator (#691)
+* Fix builds on x32 platform. #703
+
+### Changed
+* Clarify problematic JSON license (#392)
+* Move Travis to container based infrastructure (#504, #558)
+* Make whitespace array more compact (#513)
+* Optimize Writer::WriteString() with SIMD (#544)
+* x86-64 48-bit pointer optimization for GenericValue (#546)
+* Define RAPIDJSON_HAS_CXX11_RVALUE_REFS directly in clang (#617)
+* Make GenericSchemaDocument constructor explicit (#674)
+* Optimize FindMember when use std::string (#690)
+
+## [1.0.2] - 2015-05-14
+
+### Added
+* Add Value::XXXMember(...) overloads for std::string (#335)
+
+### Fixed
+* Include rapidjson.h for all internal/error headers.
+* Parsing some numbers incorrectly in full-precision mode (`kFullPrecisionParseFlag`) (#342)
+* Fix some numbers parsed incorrectly (#336)
+* Fix alignment of 64bit platforms (#328)
+* Fix MemoryPoolAllocator::Clear() to clear user-buffer (0691502573f1afd3341073dd24b12c3db20fbde4)
+
+### Changed
+* CMakeLists for include as a thirdparty in projects (#334, #337)
+* Change Document::ParseStream() to use stack allocator for Reader (ffbe38614732af8e0b3abdc8b50071f386a4a685)
+
+## [1.0.1] - 2015-04-25
+
+### Added
+* Changelog following [Keep a CHANGELOG](https://github.com/olivierlacan/keep-a-changelog) suggestions.
+
+### Fixed
+* Parsing of some numbers (e.g. "1e-00011111111111") causing assertion (#314).
+* Visual C++ 32-bit compilation error in `diyfp.h` (#317).
+
+## [1.0.0] - 2015-04-22
+
+### Added
+* 100% [Coverall](https://coveralls.io/r/Tencent/rapidjson?branch=master) coverage.
+* Version macros (#311)
+
+### Fixed
+* A bug in trimming long number sequence (4824f12efbf01af72b8cb6fc96fae7b097b73015).
+* Double quote in unicode escape (#288).
+* Negative zero roundtrip (double only) (#289).
+* Standardize behavior of `memcpy()` and `malloc()` (0c5c1538dcfc7f160e5a4aa208ddf092c787be5a, #305, 0e8bbe5e3ef375e7f052f556878be0bd79e9062d).
+
+### Removed
+* Remove an invalid `Document::ParseInsitu()` API (e7f1c6dd08b522cfcf9aed58a333bd9a0c0ccbeb).
+
+## 1.0-beta - 2015-04-8
+
+### Added
+* RFC 7159 (#101)
+* Optional Iterative Parser (#76)
+* Deep-copy values (#20)
+* Error code and message (#27)
+* ASCII Encoding (#70)
+* `kParseStopWhenDoneFlag` (#83)
+* `kParseFullPrecisionFlag` (881c91d696f06b7f302af6d04ec14dd08db66ceb)
+* Add `Key()` to handler concept (#134)
+* C++11 compatibility and support (#128)
+* Optimized number-to-string and vice versa conversions (#137, #80)
+* Short-String Optimization (#131)
+* Local stream optimization by traits (#32)
+* Travis & Appveyor Continuous Integration, with Valgrind verification (#24, #242)
+* Redo all documentation (English, Simplified Chinese)
+
+### Changed
+* Copyright ownership transferred to THL A29 Limited (a Tencent company).
+* Migrating from Premake to CMAKE (#192)
+* Resolve all warning reports
+
+### Removed
+* Remove other JSON libraries for performance comparison (#180)
+
+## 0.11 - 2012-11-16
+
+## 0.1 - 2011-11-18
+
+[Unreleased]: https://github.com/Tencent/rapidjson/compare/v1.1.0...HEAD
+[1.1.0]: https://github.com/Tencent/rapidjson/compare/v1.0.2...v1.1.0
+[1.0.2]: https://github.com/Tencent/rapidjson/compare/v1.0.1...v1.0.2
+[1.0.1]: https://github.com/Tencent/rapidjson/compare/v1.0.0...v1.0.1
+[1.0.0]: https://github.com/Tencent/rapidjson/compare/v1.0-beta...v1.0.0
diff --git a/deps/rapidjson/CMakeLists.txt b/deps/rapidjson/CMakeLists.txt
new file mode 100644
index 0000000..dc2072a
--- /dev/null
+++ b/deps/rapidjson/CMakeLists.txt
@@ -0,0 +1,248 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+if(POLICY CMP0025)
+ # detect Apple's Clang
+ cmake_policy(SET CMP0025 NEW)
+endif()
+if(POLICY CMP0054)
+ cmake_policy(SET CMP0054 NEW)
+endif()
+
+SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules)
+
+set(LIB_MAJOR_VERSION "1")
+set(LIB_MINOR_VERSION "1")
+set(LIB_PATCH_VERSION "0")
+set(LIB_VERSION_STRING "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_PATCH_VERSION}")
+
+if (CMAKE_VERSION VERSION_LESS 3.0)
+ PROJECT(RapidJSON CXX)
+else()
+ cmake_policy(SET CMP0048 NEW)
+ PROJECT(RapidJSON VERSION "${LIB_VERSION_STRING}" LANGUAGES CXX)
+endif()
+
+# compile in release with debug info mode by default
+if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
+endif()
+
+# Build all binaries in a separate directory
+SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+option(RAPIDJSON_BUILD_DOC "Build rapidjson documentation." ON)
+option(RAPIDJSON_BUILD_EXAMPLES "Build rapidjson examples." ON)
+option(RAPIDJSON_BUILD_TESTS "Build rapidjson perftests and unittests." ON)
+option(RAPIDJSON_BUILD_THIRDPARTY_GTEST
+ "Use gtest installation in `thirdparty/gtest` by default if available" OFF)
+
+option(RAPIDJSON_BUILD_CXX11 "Build rapidjson with C++11" ON)
+option(RAPIDJSON_BUILD_CXX17 "Build rapidjson with C++17" OFF)
+if(RAPIDJSON_BUILD_CXX11)
+ set(CMAKE_CXX_STANDARD 11)
+ set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
+endif()
+
+option(RAPIDJSON_BUILD_ASAN "Build rapidjson with address sanitizer (gcc/clang)" OFF)
+option(RAPIDJSON_BUILD_UBSAN "Build rapidjson with undefined behavior sanitizer (gcc/clang)" OFF)
+
+option(RAPIDJSON_ENABLE_INSTRUMENTATION_OPT "Build rapidjson with -march or -mcpu options" ON)
+
+option(RAPIDJSON_HAS_STDSTRING "" OFF)
+if(RAPIDJSON_HAS_STDSTRING)
+ add_definitions(-DRAPIDJSON_HAS_STDSTRING)
+endif()
+
+option(RAPIDJSON_USE_MEMBERSMAP "" OFF)
+if(RAPIDJSON_USE_MEMBERSMAP)
+ add_definitions(-DRAPIDJSON_USE_MEMBERSMAP=1)
+endif()
+
+find_program(CCACHE_FOUND ccache)
+if(CCACHE_FOUND)
+ set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
+ set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
+ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments -fcolor-diagnostics")
+ endif()
+endif(CCACHE_FOUND)
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ if(RAPIDJSON_ENABLE_INSTRUMENTATION_OPT AND NOT CMAKE_CROSSCOMPILING)
+ if(CMAKE_SYSTEM_PROCESSOR STREQUAL "powerpc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=native")
+ else()
+ #FIXME: x86 is -march=native, but doesn't mean every arch is this option. To keep original project's compatibility, I leave this except POWER.
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
+ endif()
+ endif()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
+ set(EXTRA_CXX_FLAGS -Weffc++ -Wswitch-default -Wfloat-equal -Wconversion -Wsign-conversion)
+ if (RAPIDJSON_BUILD_CXX11 AND CMAKE_VERSION VERSION_LESS 3.1)
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7.0")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ endif()
+ elseif (RAPIDJSON_BUILD_CXX17 AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
+ endif()
+ if (RAPIDJSON_BUILD_ASAN)
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.8.0")
+ message(FATAL_ERROR "GCC < 4.8 doesn't support the address sanitizer")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
+ endif()
+ endif()
+ if (RAPIDJSON_BUILD_UBSAN)
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9.0")
+ message(FATAL_ERROR "GCC < 4.9 doesn't support the undefined behavior sanitizer")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
+ endif()
+ endif()
+elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ if(NOT CMAKE_CROSSCOMPILING)
+ if(CMAKE_SYSTEM_PROCESSOR STREQUAL "powerpc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=native")
+ else()
+ #FIXME: x86 is -march=native, but doesn't mean every arch is this option. To keep original project's compatibility, I leave this except POWER.
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
+ endif()
+ endif()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-missing-field-initializers")
+ set(EXTRA_CXX_FLAGS -Weffc++ -Wswitch-default -Wfloat-equal -Wconversion -Wimplicit-fallthrough)
+ if (RAPIDJSON_BUILD_CXX11 AND CMAKE_VERSION VERSION_LESS 3.1)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ elseif (RAPIDJSON_BUILD_CXX17 AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.0")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
+ endif()
+ if (RAPIDJSON_BUILD_ASAN)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
+ endif()
+ if (RAPIDJSON_BUILD_UBSAN)
+ if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
+ endif()
+ endif()
+elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
+ # CMake >= 3.10 should handle the above CMAKE_CXX_STANDARD fine, otherwise use /std:c++XX with MSVC >= 19.10
+ if (RAPIDJSON_BUILD_CXX11 AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.10")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++11")
+ elseif (RAPIDJSON_BUILD_CXX17 AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.14")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
+ endif()
+ # Always compile with /WX
+ if(CMAKE_CXX_FLAGS MATCHES "/WX-")
+ string(REGEX REPLACE "/WX-" "/WX" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
+ endif()
+elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -qarch=auto")
+endif()
+
+#add extra search paths for libraries and includes
+SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The directory the headers are installed in")
+SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE STRING "Directory where lib will install")
+SET(DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/doc/${PROJECT_NAME}" CACHE PATH "Path to the documentation")
+
+IF(UNIX OR CYGWIN)
+ SET(_CMAKE_INSTALL_DIR "${LIB_INSTALL_DIR}/cmake/${PROJECT_NAME}")
+ELSEIF(WIN32)
+ SET(_CMAKE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/cmake")
+ENDIF()
+SET(CMAKE_INSTALL_DIR "${_CMAKE_INSTALL_DIR}" CACHE PATH "The directory cmake files are installed in")
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+if(RAPIDJSON_BUILD_DOC)
+ add_subdirectory(doc)
+endif()
+
+add_custom_target(travis_doc)
+add_custom_command(TARGET travis_doc
+ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/travis-doxygen.sh)
+
+if(RAPIDJSON_BUILD_EXAMPLES)
+ add_subdirectory(example)
+endif()
+
+if(RAPIDJSON_BUILD_TESTS)
+ if(MSVC11)
+ # required for VS2012 due to missing support for variadic templates
+ add_definitions(-D_VARIADIC_MAX=10)
+ endif(MSVC11)
+ add_subdirectory(test)
+ include(CTest)
+endif()
+
+# pkg-config
+IF (UNIX OR CYGWIN)
+ CONFIGURE_FILE (${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
+ @ONLY)
+ INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
+ DESTINATION "${LIB_INSTALL_DIR}/pkgconfig"
+ COMPONENT pkgconfig)
+ENDIF()
+
+install(FILES readme.md
+ DESTINATION "${DOC_INSTALL_DIR}"
+ COMPONENT doc)
+
+install(DIRECTORY include/rapidjson
+ DESTINATION "${INCLUDE_INSTALL_DIR}"
+ COMPONENT dev)
+
+install(DIRECTORY example/
+ DESTINATION "${DOC_INSTALL_DIR}/examples"
+ COMPONENT examples
+ # Following patterns are for excluding the intermediate/object files
+ # from an install of in-source CMake build.
+ PATTERN "CMakeFiles" EXCLUDE
+ PATTERN "Makefile" EXCLUDE
+ PATTERN "cmake_install.cmake" EXCLUDE)
+
+# Provide config and version files to be used by other applications
+# ===============================
+
+################################################################################
+# Export package for use from the build tree
+EXPORT( PACKAGE ${PROJECT_NAME} )
+
+# Create the RapidJSONConfig.cmake file for other cmake projects.
+# ... for the build tree
+SET( CONFIG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+SET( CONFIG_DIR ${CMAKE_CURRENT_BINARY_DIR})
+SET( ${PROJECT_NAME}_INCLUDE_DIR "\${${PROJECT_NAME}_SOURCE_DIR}/include" )
+
+CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake @ONLY )
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}ConfigVersion.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake @ONLY)
+
+# ... for the install tree
+SET( CMAKECONFIG_INSTALL_DIR ${LIB_INSTALL_DIR}/cmake/${PROJECT_NAME} )
+FILE( RELATIVE_PATH REL_INCLUDE_DIR
+ "${CMAKECONFIG_INSTALL_DIR}"
+ "${CMAKE_INSTALL_PREFIX}/include" )
+
+SET( ${PROJECT_NAME}_INCLUDE_DIR "\${${PROJECT_NAME}_CMAKE_DIR}/${REL_INCLUDE_DIR}" )
+SET( CONFIG_SOURCE_DIR )
+SET( CONFIG_DIR )
+CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PROJECT_NAME}Config.cmake @ONLY )
+
+INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PROJECT_NAME}Config.cmake"
+ DESTINATION ${CMAKECONFIG_INSTALL_DIR} )
+
+# Install files
+INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
+ DESTINATION "${CMAKE_INSTALL_DIR}"
+ COMPONENT dev)
diff --git a/deps/rapidjson/CMakeModules/FindGTestSrc.cmake b/deps/rapidjson/CMakeModules/FindGTestSrc.cmake
new file mode 100644
index 0000000..f3cb8c9
--- /dev/null
+++ b/deps/rapidjson/CMakeModules/FindGTestSrc.cmake
@@ -0,0 +1,30 @@
+
+SET(GTEST_SEARCH_PATH
+ "${GTEST_SOURCE_DIR}"
+ "${CMAKE_CURRENT_LIST_DIR}/../thirdparty/gtest/googletest")
+
+IF(UNIX)
+ IF(RAPIDJSON_BUILD_THIRDPARTY_GTEST)
+ LIST(APPEND GTEST_SEARCH_PATH "/usr/src/gtest")
+ ELSE()
+ LIST(INSERT GTEST_SEARCH_PATH 1 "/usr/src/gtest")
+ ENDIF()
+ENDIF()
+
+FIND_PATH(GTEST_SOURCE_DIR
+ NAMES CMakeLists.txt src/gtest_main.cc
+ PATHS ${GTEST_SEARCH_PATH})
+
+
+# Debian installs gtest include directory in /usr/include, thus need to look
+# for include directory separately from source directory.
+FIND_PATH(GTEST_INCLUDE_DIR
+ NAMES gtest/gtest.h
+ PATH_SUFFIXES include
+ HINTS ${GTEST_SOURCE_DIR}
+ PATHS ${GTEST_SEARCH_PATH})
+
+INCLUDE(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(GTestSrc DEFAULT_MSG
+ GTEST_SOURCE_DIR
+ GTEST_INCLUDE_DIR)
diff --git a/deps/rapidjson/RapidJSON.pc.in b/deps/rapidjson/RapidJSON.pc.in
new file mode 100644
index 0000000..6afb079
--- /dev/null
+++ b/deps/rapidjson/RapidJSON.pc.in
@@ -0,0 +1,7 @@
+includedir=@INCLUDE_INSTALL_DIR@
+
+Name: @PROJECT_NAME@
+Description: A fast JSON parser/generator for C++ with both SAX/DOM style API
+Version: @LIB_VERSION_STRING@
+URL: https://github.com/Tencent/rapidjson
+Cflags: -I${includedir}
diff --git a/deps/rapidjson/RapidJSONConfig.cmake.in b/deps/rapidjson/RapidJSONConfig.cmake.in
new file mode 100644
index 0000000..c25d312
--- /dev/null
+++ b/deps/rapidjson/RapidJSONConfig.cmake.in
@@ -0,0 +1,25 @@
+################################################################################
+# CMake minimum version required
+cmake_minimum_required(VERSION 3.0)
+
+################################################################################
+# RapidJSON source dir
+set( RapidJSON_SOURCE_DIR "@CONFIG_SOURCE_DIR@")
+
+################################################################################
+# RapidJSON build dir
+set( RapidJSON_DIR "@CONFIG_DIR@")
+
+################################################################################
+# Compute paths
+get_filename_component(RapidJSON_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+set( RapidJSON_INCLUDE_DIR "@RapidJSON_INCLUDE_DIR@" )
+set( RapidJSON_INCLUDE_DIRS "@RapidJSON_INCLUDE_DIR@" )
+message(STATUS "RapidJSON found. Headers: ${RapidJSON_INCLUDE_DIRS}")
+
+if(NOT TARGET rapidjson)
+ add_library(rapidjson INTERFACE IMPORTED)
+ set_property(TARGET rapidjson PROPERTY
+ INTERFACE_INCLUDE_DIRECTORIES ${RapidJSON_INCLUDE_DIRS})
+endif()
diff --git a/deps/rapidjson/RapidJSONConfigVersion.cmake.in b/deps/rapidjson/RapidJSONConfigVersion.cmake.in
new file mode 100644
index 0000000..25741fc
--- /dev/null
+++ b/deps/rapidjson/RapidJSONConfigVersion.cmake.in
@@ -0,0 +1,10 @@
+SET(PACKAGE_VERSION "@LIB_VERSION_STRING@")
+
+IF (PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION)
+ SET(PACKAGE_VERSION_EXACT "true")
+ENDIF (PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION)
+IF (NOT PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
+ SET(PACKAGE_VERSION_COMPATIBLE "true")
+ELSE (NOT PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
+ SET(PACKAGE_VERSION_UNSUITABLE "true")
+ENDIF (NOT PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
diff --git a/deps/rapidjson/appveyor.yml b/deps/rapidjson/appveyor.yml
new file mode 100644
index 0000000..4044ba6
--- /dev/null
+++ b/deps/rapidjson/appveyor.yml
@@ -0,0 +1,102 @@
+version: 1.1.0.{build}
+
+configuration:
+- Debug
+- Release
+
+environment:
+ matrix:
+ # - VS_VERSION: 9 2008
+ # VS_PLATFORM: win32
+ # - VS_VERSION: 9 2008
+ # VS_PLATFORM: x64
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+ VS_VERSION: 10 2010
+ VS_PLATFORM: win32
+ CXX11: OFF
+ CXX17: OFF
+ MEMBERSMAP: OFF
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+ VS_VERSION: 10 2010
+ VS_PLATFORM: x64
+ CXX11: OFF
+ CXX17: OFF
+ MEMBERSMAP: ON
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+ VS_VERSION: 11 2012
+ VS_PLATFORM: win32
+ CXX11: OFF
+ CXX17: OFF
+ MEMBERSMAP: ON
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+ VS_VERSION: 11 2012
+ VS_PLATFORM: x64
+ CXX11: OFF
+ CXX17: OFF
+ MEMBERSMAP: OFF
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+ VS_VERSION: 12 2013
+ VS_PLATFORM: win32
+ CXX11: OFF
+ CXX17: OFF
+ MEMBERSMAP: OFF
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+ VS_VERSION: 12 2013
+ VS_PLATFORM: x64
+ CXX11: OFF
+ CXX17: OFF
+ MEMBERSMAP: ON
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+ VS_VERSION: 14 2015
+ VS_PLATFORM: win32
+ CXX11: OFF
+ CXX17: OFF
+ MEMBERSMAP: ON
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+ VS_VERSION: 14 2015
+ VS_PLATFORM: x64
+ CXX11: OFF
+ CXX17: OFF
+ MEMBERSMAP: OFF
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+ VS_VERSION: 15 2017
+ VS_PLATFORM: win32
+ CXX11: OFF
+ CXX17: OFF
+ MEMBERSMAP: OFF
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+ VS_VERSION: 15 2017
+ VS_PLATFORM: x64
+ CXX11: OFF
+ CXX17: OFF
+ MEMBERSMAP: ON
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+ VS_VERSION: 15 2017
+ VS_PLATFORM: x64
+ CXX11: ON
+ CXX17: OFF
+ MEMBERSMAP: OFF
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+ VS_VERSION: 15 2017
+ VS_PLATFORM: x64
+ CXX11: OFF
+ CXX17: ON
+ MEMBERSMAP: OFF
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+ VS_VERSION: 16 2019
+ VS_PLATFORM: x64
+ CXX11: OFF
+ CXX17: ON
+ MEMBERSMAP: ON
+
+before_build:
+- git submodule update --init --recursive
+- cmake -H. -BBuild/VS -G "Visual Studio %VS_VERSION%" -DCMAKE_GENERATOR_PLATFORM=%VS_PLATFORM% -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=true -DRAPIDJSON_BUILD_CXX11=%CXX11% -DRAPIDJSON_BUILD_CXX17=%CXX17% -DRAPIDJSON_USE_MEMBERSMAP=%MEMBERSMAP% -Wno-dev
+
+build:
+ project: Build\VS\RapidJSON.sln
+ parallel: true
+ verbosity: minimal
+
+test_script:
+- cd Build\VS && if %CONFIGURATION%==Debug (ctest --verbose -E perftest --build-config %CONFIGURATION%) else (ctest --verbose --build-config %CONFIGURATION%)
diff --git a/deps/rapidjson/bin/data/abcde.txt b/deps/rapidjson/bin/data/abcde.txt
new file mode 100644
index 0000000..6a81654
--- /dev/null
+++ b/deps/rapidjson/bin/data/abcde.txt
@@ -0,0 +1 @@
+abcde
\ No newline at end of file
diff --git a/deps/rapidjson/bin/data/glossary.json b/deps/rapidjson/bin/data/glossary.json
new file mode 100644
index 0000000..d6e6ca1
--- /dev/null
+++ b/deps/rapidjson/bin/data/glossary.json
@@ -0,0 +1,22 @@
+{
+ "glossary": {
+ "title": "example glossary",
+ "GlossDiv": {
+ "title": "S",
+ "GlossList": {
+ "GlossEntry": {
+ "ID": "SGML",
+ "SortAs": "SGML",
+ "GlossTerm": "Standard Generalized Markup Language",
+ "Acronym": "SGML",
+ "Abbrev": "ISO 8879:1986",
+ "GlossDef": {
+ "para": "A meta-markup language, used to create markup languages such as DocBook.",
+ "GlossSeeAlso": ["GML", "XML"]
+ },
+ "GlossSee": "markup"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/deps/rapidjson/bin/data/menu.json b/deps/rapidjson/bin/data/menu.json
new file mode 100644
index 0000000..539c3af
--- /dev/null
+++ b/deps/rapidjson/bin/data/menu.json
@@ -0,0 +1,27 @@
+{"menu": {
+ "header": "SVG Viewer",
+ "items": [
+ {"id": "Open"},
+ {"id": "OpenNew", "label": "Open New"},
+ null,
+ {"id": "ZoomIn", "label": "Zoom In"},
+ {"id": "ZoomOut", "label": "Zoom Out"},
+ {"id": "OriginalView", "label": "Original View"},
+ null,
+ {"id": "Quality"},
+ {"id": "Pause"},
+ {"id": "Mute"},
+ null,
+ {"id": "Find", "label": "Find..."},
+ {"id": "FindAgain", "label": "Find Again"},
+ {"id": "Copy"},
+ {"id": "CopyAgain", "label": "Copy Again"},
+ {"id": "CopySVG", "label": "Copy SVG"},
+ {"id": "ViewSVG", "label": "View SVG"},
+ {"id": "ViewSource", "label": "View Source"},
+ {"id": "SaveAs", "label": "Save As"},
+ null,
+ {"id": "Help"},
+ {"id": "About", "label": "About Adobe CVG Viewer..."}
+ ]
+}}
\ No newline at end of file
diff --git a/deps/rapidjson/bin/data/readme.txt b/deps/rapidjson/bin/data/readme.txt
new file mode 100644
index 0000000..c53bfb8
--- /dev/null
+++ b/deps/rapidjson/bin/data/readme.txt
@@ -0,0 +1 @@
+sample.json is obtained from http://code.google.com/p/json-test-suite/downloads/detail?name=sample.zip
diff --git a/deps/rapidjson/bin/data/sample.json b/deps/rapidjson/bin/data/sample.json
new file mode 100644
index 0000000..30930e7
--- /dev/null
+++ b/deps/rapidjson/bin/data/sample.json
@@ -0,0 +1,3315 @@
+{
+ "a": {
+ "6U閆崬밺뀫颒myj츥휘:$薈mY햚#rz飏+玭V㭢뾿愴YꖚX亥ᮉ푊\u0006垡㐭룝\"厓ᔧḅ^Sqpv媫\"⤽걒\"˽Ἆ?ꇆ䬔未tv{DV鯀Tἆl凸g\\㈭ĭ즿UH㽤": null,
+ "b茤z\\.N": [[
+ "ZL:ᅣዎ*Y|猫劁櫕荾Oj为1糕쪥泏S룂w࡛Ᏺ⸥蚙)",
+ {
+ "\"䬰ỐwD捾V`邀⠕VD㺝sH6[칑.:醥葹*뻵倻aD\"": true,
+ "e浱up蔽CrJK軵xCʨ<뜡癙Y獩ケ齈X/螗唻?<蘡+뷄㩤쳖3偑犾&\\첊xz坍崦ݻ鍴\"嵥B3㰃詤豺嚼aqJ⑆∥韼@\u000b㢊\u0015L臯.샥": false,
+ "l?Ǩ喳e6㔡$M꼄I,(3縢,䊀疅뉲B㴔傳䂴\u0088㮰钘ꜵ!ᅛ韽>": -5514085325291784739,
+ "o㮚?\"춛㵉<\/ࠃ䃪䝣wp6ἀ䱄[s*S嬈貒pᛥ㰉'돀": [{
+ "(QP윤懊FI<ꃣ『䕷[\"珒嶮?%Ḭ壍䇟0荤!藲끹bd浶tl\u2049#쯀@僞": {"i妾8홫": {
+ ",M맃䞛K5nAㆴVN㒊햬$n꩑&ꎝ椞阫?/ṏ세뉪1x쥼㻤㪙`\"$쟒薟B煌܀쨝ଢ଼2掳7㙟鴙X婢\u0002": "Vዉ菈᧷⦌kﮞఈnz*'ahhCFX(\u0007⮊E㭍䱾Gxꥩr❣.洎",
+ "뻴5bDD큯O傆盓왻U?ꞅꐊN鐭᧢τ\"迳豲8\u001b䃥ꂻ䴺ྸH筴,": {
+ "\"L鸔SE㬡XV&~͎'놅蔞눶l匛?'.K氁\\ƢẨ疇mΊ'꽳&!鹠m'|{P痊 秄쒿u\u00111䋧gϩx7t丗D䊨䠻z0.A0": -1.50139930144708198E18,
+ "8鋂뛷?첒B☚>FM\"荭7ꍀ-VR<\/';䁙E9$䩉\f @s?퍪o3^衴cඎ䧪aK鼟q䆨c{䳠5mᒲՙ蘹ᮩ": {
+ "F㲷JGo⯍P덵x뒳p䘧☔\"+ꨲ吿JfR㔹)4n紬G练Q፞!C|": true,
+ "p^㫮솎oc.A㤠??r\u000f)⾽⌲們M2.䴘䩳:⫭胃\\@Fᭌ\\K": false,
+ "蟌Tk愙潦伩": {
+ "a<\/@ᾛ慂侇瘎": -7271305752851720826,
+ "艓藬/>၄ṯ,XW~㲆w": {"E痧郶)㜓ha朗!N赻瞉駠uC\u20ad辠x퓮⣫P1ࠫLMMX'M刼唳됤": null,
+ "P쓫晥%k覛ዩIUᇸ滨:噐혲lMR5䋈V梗>%幽u頖\\)쟟": null,
+ "eg+昉~矠䧞难\b?gQ쭷筝\\eꮠNl{ಢ哭|]Mn銌╥zꖘzⱷ⭤ᮜ^": [
+ -1.30142114406914976E17,
+ -1.7555215491128452E-19,
+ null,
+ "渾㨝ߏ牄귛r?돌?w[⚞ӻ~廩輫㼧/",
+ -4.5737191805302129E18,
+ null,
+ "xy࿑M[oc셒竓Ⓔx?뜓y䊦>-D켍(&&?XKkc꩖ﺸᏋ뵞K伕6ী)딀P朁yW揙?훻魢傎EG碸9類៌g踲C⟌aEX舲:z꒸许",
+ 3808159498143417627,
+ null,
+ {"m試\u20df1{G8&뚈h홯J<\/": {
+ "3ஸ厠zs#1K7:rᥞoꅔꯧ&띇鵼鞫6跜#赿5l'8{7㕳(b/j\"厢aq籀ꏚ\u0015厼稥": [
+ -2226135764510113982,
+ true,
+ null,
+ {
+ "h%'맞S싅Hs&dl슾W0j鿏MםD놯L~S-㇡R쭬%": null,
+ "⟓咔謡칲\u0000孺ꛭx旑檉㶆?": null,
+ "恇I転;B2Y`z\\獓w,놏濐撐埵䂄)!䶢D=ഭ㴟jyY": {
+ "$ࡘt厛毣ൢI芁<겿骫⫦6tr惺a": [
+ 6.385779736989334E-20,
+ false,
+ true,
+ true,
+ [
+ -6.891946211462334E-19,
+ null,
+ {
+ "]-\\Ꟑ1/薓❧Ὂ\\l牑\u0007A郃)阜ᇒᓌ-塯`W峬G}SDb㬨Q臉⮻빌O鞟톴첂B㺱<ƈmu챑J㴹㷳픷Oㆩs": {
+ "\"◉B\"pᶉt骔J꩸ᄇᛐi╰栛K쉷㉯鐩!㈐n칍䟅難>盥y铿e蒏M貹ヅ8嘋퀯䉶ጥ㏢殊뻳\"絧╿ꉑ䠥?∃蓊{}㣣Gk긔H1哵峱": false,
+ "6.瀫cN䇮F㧺?\\椯=ڈT䘆4␘8qv": -3.5687501019676885E-19,
+ "Q?yऴr혴{䳘p惭f1ﹸ䅷䕋贲<ྃᄊ繲hq\\b|#QSTs1c-7(䵢\u2069匏絘ꯉ:l毴汞t戀oෟᵶ뮱፣-醇Jx䙬䐁햢0࣫ᡁgrㄛ": "\u0011_xM/蘇Chv;dhA5.嗀绱V爤ﰦi뵲M",
+ "⏑[\"ugoy^儣횎~U\\섯겜論l2jwyD腅̂\u0019": true,
+ "ⵯɇ䐲࢚!㯢l샅笶戮1꣖0Xe": null,
+ "劅f넀識b宁焊E찓橵G!ʱ獓뭔雩괛": [{"p켙[q>燣䍃㞽ᩲx:쓤삘7玑퇼0<\/q璂ᑁ[Z\\3䅵䧳\u0011㤧|妱緒C['췓Yꞟ3Z鳱雼P錻BU씧U`ᢶg蓱>.1ӧ譫'L_5V䏵Ц": [
+ false,
+ false,
+ {"22䂍盥N霂얢躰e9⑩_뵜斌n@B}$괻Yᐱ@䧋V\"☒-諯cV돯ʠ": true,
+ "Ű螧ᔼ檍鍎땒딜qꄃH뜣<獧ूCY吓⸏>XQ㵡趌o끬k픀빯a(ܵ甏끆୯/6Nᪧ}搚ᆚ짌P牰泱鈷^d#L삀\"㕹襻;k㸊\\f+": true,
+ "쎣\",|⫝̸阊x庿k잣v庅$鈏괎炔k쬪O_": [
+ "잩AzZGz3v愠ꉈⵎ?㊱}S尳p\r2>췝IP䘈M)w|\u000eE",
+ -9222726055990423201,
+ null,
+ [
+ false,
+ {"´킮'뮤쯽Wx讐V,6ᩪ1紲aႈ\u205czD": [
+ -930994432421097536,
+ 3157232031581030121,
+ "l貚PY䃛5@䭄귻m㎮琸f": 1.0318894506812084E-19,
+ "࢜⩢Ш䧔1肽씮+༎ᣰ闺馺窃䕨8Mƶq腽xc(夐J5굄䕁Qj_훨/~価.䢵慯틠퇱豠㼇Qﵘ$DuSp(8Uญ<\/ಟ룴𥳐ݩ$": 8350772684161555590,
+ "ㆎQ䄾\u001bpᩭ${[諟^^骴b^ㅥI┧T㉇⾞\"绦r䰂f矩'-7䡭桥Dz兔V9谶居㺍ᔊ䩯덲.\u001eL0ὅㅷ釣": [{
+ "<쯬J卷^숞u䌗艞R9닪g㐾볎a䂈歖意:%鐔|ﵤ|y}>;2,覂啵tb*仛8乒㓶B㯉戩oX 貘5V嗆렽낁4h䧛ꍺM空\\b꿋貼": 8478577078537189402,
+ "VD*|吝z~h譺aᯒ": {
+ "YI췢K<\/濳xNne玗rJo쾘3핰鴊\"↱AR:ࢷ\"9?\"臁說)?誚ꊏe)_D翾W?&F6J@뺾ꍰNZ醊Z쾈വH嶿?炫㷱鬰M겈᭨b,⻁鈵P䕡䀠८ⱄ홎鄣": {
+ "@?k2鶖㋮\"Oರ K㨇廪儲\u0017䍾J?);\b*묀㗠섳햭1MC V": null,
+ "UIICP!BUA`ᢈ㋸~袩㗪⾒=fB﮴l1ꡛ죘R辂여ҳ7쮡<䩲`熕8頁": 4481809488267626463,
+ "Y?+8먙ᚔ鋳蜩럶1㥔y璜౩`": [
+ null,
+ 1.2850335807501874E-19,
+ "~V2",
+ 2035406654801997866,
+ {
+ "<숻1>\"": -8062468865199390827,
+ "M㿣E]}qwG莎Gn(ꔙ\\D⬲iꇲs寢t駇S뀡ꢜ": false,
+ "pꝤ㎏9W%>M;-U璏f(^j1?&RB隧 忓b똊E": "#G?C8.躬ꥯ'?냪#< 渟&헿란zpo왓Kj}鷧XﻘMツb䕖;㪻",
+ "vE풤幉xz뱕쫥Ug㦲aH} ᣟp:鬼YᰟH3镔ᴚ斦\\鏑r*2橱G⼔F/.j": true,
+ "RK좬뎂a홠f*f㱉ᮍ⦋潙㨋Gu곌SGI3I뿐\\F',)t`荁蘯囯ﮉ裲뇟쥼_ገ驪▵撏ᕤV": 1.52738225997956557E18,
+ "^k굲䪿꠹B逤%F㱢漥O披M㽯镞竇霒i꼂焅륓\u00059=皫之눃\u2047娤閍銤唫ၕb<\/w踲䔼u솆맚,䝒ᝳ'/it": "B餹饴is権ꖪ怯ꦂẉဎt\"!凢谵⧿0\\<=(uL䷍刨쑪>俆揓Cy襸Q힆䆭涷<\/ᐱ0ɧ䗾䚹\\ኜ?ꄢᇘ`䴢{囇}᠈䴥X4퓪檄]ꥷ/3謒ሴn+g騍X",
+ "GgG꽬[(嫓몍6\u0004궍宩㙻/>\u0011^辍dT腪hxǑ%ꊇk,8(W⧂結P鬜O": [{
+ "M㴾c>\\ᓲ\u0019V{>ꤩ혙넪㭪躂TS-痴闓⍵/徯O.M㏥ʷD囎⧔쁳휤T??鉬뇙=#ꢫ숣BX䭼<\/d똬졬g榿)eꨋﯪ좇첻2K)": null,
+ "Z17縬z]愀䖌 ᾋBCg5딒국憍꾓aⲷ턷u:U촳驿?雺楶\u0001\u001c{q*ᰗ苑B@k揰z.*蓗7ረIm\"Oᱍ@7?_": true,
+ "㺃Z<": -4349275766673120695,
+ "휃䠂fa塆ffixKe'덬鏗뺾w࠾鑎k땢m*႑햞鐮6攊&虜h黚,Y䱳Sﭼ둺pN6": [
+ false,
+ "IΎ䣲,\"ᬮ˪癘P~Qlnx喁Sᮔ༬˨I珌m䜛酛\u0003iꐸ㦧cQ帲晼D' \\(粋wQcN\\뵰跈",
+ [
+ "D0\\L?M1쥍Kaꏌsd+盌귤憊tz䌣댐בO坂wϢ%ὒgp,Ai⎧ᶆI餾ꦍ棩嘅怴%m]ၶis纖D凜镧o심b U",
+ {
+ "?଼\u0011Rv&^[+匚I趈T媫\u0010.䥤ᆯ1q僤HydⲰl㒽K'ᅾiౕ豲초딨@\u0013J'쪪VD౼P4Ezg#8*㋤W馓]c쿯8": false,
+ "c/擯X5~JmK䵶^쐎ച|B|u[솝(X뚤6v}W㤘⠛aR弌臌쾭諦eⒷ僡-;㩩⭖ⷴ徆龄갬{䱓ᥩ!⊚ᇨ\u001a\u0011\";~쓆BH4坋攊7",
+ "iT:L闞椕윚*滛gI≀Wਟඊ'ꢆ縺뱹鮚Nꩁ᧬蕼21줧\\䋯``⍐\\㏱鳨": 1927052677739832894,
+ "쮁缦腃g]礿Y㬙 fヺSɪ꾾N㞈": [
+ null,
+ null,
+ {
+ "!t,灝Y 1䗉罵?c饃호䉂Cᐭ쒘z(즽sZG㬣sഖE4뢜㓕䏞丮Qp簍6EZឪ겛fx'ꩱQ0罣i{k锩*㤴㯞r迎jTⲤ渔m炅肳": [
+ -3.3325685522591933E18,
+ [{"㓁5]A䢕1룥BC?Ꙍ`r룔Ⳛ䙡u伲+\u0001്o": [
+ null,
+ 4975309147809803991,
+ null,
+ null,
+ {"T팘8Dﯲ稟MM☻㧚䥧/8ﻥ⥯aXLaH\"顾S☟耲ît7fS놁뮔/ꕼ䓈쁺4\\霶䠴ᩢ<\/t4?죵>uD5➶༆쉌럮⢀秙䘥\u20972ETR3濡恆vB? ~鸆\u0005": {
+ "`閖m璝㥉b뜴?Wf;?DV콜\u2020퍉擝宏ZMj3mJ먡-傷뱙yח㸷 ໘u=M읝!5吭L4v\\?ǎ7C홫": null,
+ "|": false,
+ "~Ztᛋ䚘\\擭㗝傪W陖+㗶qᵿ蘥ᙄp%䫎)}=⠔6ᮢS湟-螾-mXH?cp": 448751162044282216,
+ "\u209fad놹j檋䇌ᶾ梕㉝bוּ": {"?苴ꩠD䋓帘5騱qﱖPF?☸珗顒yU ᡫcb䫎 S@㥚gꮒ쎘泴멖\\:I鮱TZ듒ᶨQ3+f7캙\"?\f풾\\o杞紟M.⏎靑OP": [
+ -2.6990368911551596E18,
+ [{"䒖@<᰿<\/⽬tTr腞&G%秩蜰擻f㎳?S㵧\r*k뎾-乢겹隷j軛겷0룁鮁": {")DO0腦:춍逿:1㥨่!蛍樋2": [{
+ ",ꌣf侴笾mꆽ?1?U?\u0011ꌈꂇ": {
+ "x捗甠nVq䅦w`CD⦂惺嘴0I#vỵ} \\귂S끴D얾?Ԓj溯\"v餄a": {
+ "@翙c⢃趚痋i\u0015OQ⍝lq돆Y0pࢥ3쉨䜩^<8g懥0w)]䊑n洺o5쭝QL댊랖L镈Qnt⪟㒅십q헎鳒⮤眉ᔹ梠@O縠u泌ㄘb榚癸XޔFtj;iC": false,
+ "I&뱋|蓔䔕측瓯%6ᗻHW\\N1貇#?僐ᗜgh᭪o'䗈꽹Rc욏/蔳迄༝!0邔䨷푪8疩)[쭶緄㇈୧ፐ": {
+ "B+:ꉰ`s쾭)빼C羍A䫊pMgjdx䐝Hf9W0!C樃'蘿f䫤סи\u0017Jve? 覝f둀⬣퓉Whk\"=չﳐ皆笁BIW虨쫓F廰饞": -642906201042308791,
+ "sb,XcZ<\/m㉹ ;䑷@c䵀s奤⬷7`ꘖ蕘戚?Feb#輜}p4nH⬮eKL트}": [
+ "RK鳗z=袤Pf|[,u욺",
+ "Ẏᏻ罯뉋⺖锅젯㷻{H䰞쬙-쩓D]~\u0013O㳢gb@揶蔉|kᦂ❗!\u001ebM褐sca쨜襒y⺉룓",
+ null,
+ null,
+ true,
+ -1.650777344339075E-19,
+ false,
+ "☑lꄆs꤇]'uTന⌳농].1⋔괁沰\"IWഩ\u0019氜8쟇䔻;3衲恋,窌z펏喁횗?4?C넁问?ᥙ橭{稻Ⴗ_썔",
+ "n?]讇빽嗁}1孅9#ꭨ靶v\u0014喈)vw祔}룼쮿I",
+ -2.7033457331882025E18,
+ {
+ ";⚃^㱋x:饬ኡj'꧵T☽O㔬RO婎?향ᒭ搩$渣y4i;(Q>꿘e8q": "j~錘}0g;L萺*;ᕭꄮ0l潛烢5H▄쳂ꏒוֹꙶT犘≫x閦웧v",
+ "~揯\u2018c4職렁E~ᑅቚꈂ?nq뎤.:慹`F햘+%鉎O瀜쟏敛菮⍌浢<\/㮺紿P鳆ࠉ8I-o?#jﮨ7v3Dt赻J9": null,
+ "ࣝW䌈0ꍎqC逖,횅c၃swj;jJS櫍5槗OaB>D踾Y": {"㒰䵝F%?59.㍈cᕨ흕틎ḏ㋩B=9IېⓌ{:9.yw}呰ㆮ肒᎒tI㾴62\"ዃ抡CB<\/촋jo朣",
+ [
+ -7675533242647793366,
+ {"ᙧ呃:[㒺쳀쌡쏂H稈㢤\u001dᶗGG-{GHྻຊꡃ哸䵬;$?&d\\⥬こN圴됤挨-'ꕮ$PU%?冕눖i魁q騎Q": [
+ false,
+ [[
+ 7929823049157504248,
+ [[
+ true,
+ "Z菙\u0017'eꕤ᱕l,0\\X\u001c[=雿8蠬L<\/낲긯W99g톉4ퟋb㝺\u0007劁'!麕Q궈oW:@X၎z蘻m絙璩귓죉+3柚怫tS捇蒣䝠-擶D[0=퉿8)q0ٟ",
+ "唉\nFA椭穒巯\\䥴䅺鿤S#b迅獘 ﶗ\\?q1qN犠pX꜅^䤊⛤㢌[⬛휖岺q唻ⳡ틍\"㙙Eh@oA賑㗠y必Nꊑᗘ",
+ -2154220236962890773,
+ -3.2442003245397908E18,
+ "Wᄿ筠:瘫퀩?o貸q⊻(KWf宛尨h^残3[U(='橄",
+ -7857990034281549164,
+ 1.44283696979059942E18,
+ null,
+ {"ꫯAw跭喀 ?_9\"Aty背F=9缉ྦྷ@;?^鞀w:uN㘢Rỏ": [
+ 7.393662029337442E15,
+ 3564680942654233068,
+ [
+ false,
+ -5253931502642112194,
+ "煉\\辎ೆ罍5⒭1䪁䃑s䎢:[e5}峳ﴱn騎3?腳Hyꏃ膼N潭錖,Yᝋ˜YAၓ㬠bG렣䰣:",
+ true,
+ null,
+ {
+ "⒛'P&%죮|:⫶춞": -3818336746965687085,
+ "钖m<\/0ݎMtF2Pk=瓰୮洽겎.": [[
+ -8757574841556350607,
+ -3045234949333270161,
+ null,
+ {
+ "Ꮬr輳>⫇9hU##w@귪A\\C 鋺㘓ꖐ梒뒬묹㹻+郸嬏윤'+g<\/碴,}ꙫ>손;情d齆J䬁ຩ撛챝탹/R澡7剌tꤼ?ặ!`⏲睤\u00002똥⟏": null,
+ "\u20f2ܹe\\tAꥍư\\x当뿖렉禛;G檳ﯪS૰3~㘠#[J<}{奲 5箉⨔{놁<\/釿抋,嚠/曳m&WaOvT赋皺璑텁": [[
+ false,
+ null,
+ true,
+ -5.7131445659795661E18,
+ "萭m䓪D5|3婁ఞ>蠇晼6nﴺPp禽羱DS<睓닫屚삏姿",
+ true,
+ [
+ -8759747687917306831,
+ {
+ ">ⓛ\t,odKr{䘠?b퓸C嶈=DyEᙬ@ᴔ쨺芛髿UT퓻春<\/yꏸ>豚W釺N뜨^?꽴﨟5殺ᗃ翐%>퍂ဿ䄸沂Ea;A_\u0005閹殀W+窊?Ꭼd\u0013P汴G5썓揘": 4.342729067882445E-18,
+ "Q^즾眆@AN\u0011Kb榰냎Y#䝀ꀒᳺ'q暇睵s\"!3#I⊆畼寤@HxJ9": false,
+ "D[)袨i]웪䀤ᛰMvR<蟏㣨": {"v퇓L㪱ꖣ豛톤\\곱#kDTN": [{
+ "(쾴䡣,寴ph(C\"㳶w\"憳2s馆E!n!&柄<\/0Pꈗſ?㿳Qd鵔": {"娇堰孹L錮h嵅⛤躏顒?CglN束+쨣ﺜ\\MrH": {"獞䎇둃ቲ弭팭^ꄞ踦涟XK錆쳞ឌ`;੶S炥騞ଋ褂B៎{ڒ䭷ᶼ靜pI荗虶K$": [{"◖S~躘蒉輜譝Q㽙闐@ᢗ¥E榁iء5┄^B[絮跉ᰥ遙PWi3wㄾⵀDJ9!w㞣ᄎ{듒ꓓb6\\篴??c⼰鶹⟧\\鮇ꮇ": [[
+ 654120831325413520,
+ -1.9562073916357608E-19,
+ {
+ "DC(昐衵ἡ긙갵姭|֛[t": 7.6979110359897907E18,
+ "J␅))嫼❳9Xfd飉j7猬ᩉ+⤻眗벎E鰉Zᄊ63zၝ69}ZᶐL崭ᦥ⡦靚⋛ꎨ~i㨃咊ꧭo䰠阀3C(": -3.5844809362512589E17,
+ "p꣑팱쒬ꎑ뛡Ꙩ挴恍胔&7ᔈ묒4Hd硶훐㎖zꢼ豍㿢aሃ=<\/湉鵲EӅ%$F!퍶棌孼{O駍geu+": ")\u001b잓kŀX쩫A밁®ڣ癦狢)扔弒p}k縕ꩋ,䃉tࣼi",
+ "ァF肿輸<솄G-䢹䛸ꊏl`Tqꕗ蒞a氷⸅ᴉ蠰]S/{J왲m5{9.uέ~㕚㣹u>x8U讁B덺襪盎QhVS맅킃i识{벂磄Iහ䙅xZy/抍૭Z鲁-霳V据挦ℒ": null,
+ "㯛|Nꐸb7ⵐb?拠O\u0014ކ?-(EꞨ4ꕷᄤYᯕOW瞺~螸\"욿ќe㺰\"'㌢ƐW\u0004瞕>0?V鷵엳": true,
+ "뤥G\\迋䠿[庩'꼡\u001aiᩮV쯁ᳪ䦪Ô;倱ନ뛁誈": null,
+ "쥹䄆䚟Q榁䎐<\/2㕣p}HW蟔|䃏꿈ꚉ锳2Pb7㙑Tⅹᵅ": {
+ "Y?֭$>#cVBꩨ:>eL蒁務": {
+ "86柡0po 䏚&-捑Ћ祌<\/휃-G*㶢הּ쩍s㶟餇c걺yu꽎還5*턧簕Og婥SꝐ": null,
+ "a+葞h٥ࠆ裈嗫ﵢ5輙퀟ᛜ,QDﹼ⟶Y騠锪E_|x죗j侵;m蜫轘趥?븅w5+mi콛L": {
+ ";⯭ﱢ!买F⽍柤鶂n䵣V㫚墱2렾ELEl⣆": [
+ true,
+ -3.6479311868339015E-18,
+ -7270785619461995400,
+ 3.334081886177621E18,
+ 2.581457786298155E18,
+ -6.605252412954115E-20,
+ -3.9232347037744167E-20,
+ {
+ "B6㊕.k1": null,
+ "ZAꄮJ鮷ᳱo갘硥鈠䠒츼": {
+ "ᕅ}럡}.@y陪鶁r業'援퀉x䉴ﵴl퍘):씭脴ᥞhiꃰblﲂ䡲엕8߇M㶭0燋標挝-?PCwe⾕J碻Ᾱ䬈䈥뷰憵賣뵓痬+": {"a췩v礗X⋈耓ፊf罅靮!㔽YYᣓw澍33⎔芲F|\"䜏T↮輦挑6ᓘL侘?ᅥ]덆1R௯✎餘6ꏽ<\/௨\\?q喷ꁫj~@ulq": {"嗫欆뾔Xꆹ4H㌋F嵧]ࠎ]㠖1ꞤT<$m뫏O i댳0䲝i": {"?෩?\u20cd슮|ꯆjs{?d7?eNs⢚嫥氂䡮쎱:鑵롟2hJꎒﯭ鱢3춲亄:뼣v䊭諱Yj択cVmR䩃㘬T\"N홝*ै%x^F\\_s9보zz4淗?q": [
+ null,
+ "?",
+ 2941869570821073737,
+ "{5{殇0䝾g6밖퍋臩綹R$䖭j紋釰7sXI繳漪행y",
+ false,
+ "aH磂?뛡#惇d婅?Fe,쐘+늵䍘\"3r瘆唊勐j⳧࠴ꇓ<\/唕윈x⬌讣䋵%拗ᛆⰿ妴M2㳗必꧂淲?ゥ젯檢<8끒MidX䏒3Q▮佐UT|⤪봦靏⊏",
+ [[{
+ "颉(&뜸귙{y^\"P춝Ჟ䮭D顡9=?}Y誱<$b뱣RvO8cH煉@tk~4ǂ⤧⩝屋SS;J{vV#剤餓ᯅc?#a6D,s": [
+ -7.8781018564821536E16,
+ true,
+ [
+ -2.28770899315832371E18,
+ false,
+ -1.0863912140143876E-20,
+ -6282721572097446995,
+ 6767121921199223078,
+ -2545487755405567831,
+ false,
+ null,
+ -9065970397975641765,
+ [
+ -5.928721243413937E-20,
+ {"6촊\u001a홯kB0w撨燠룉{绎6⳹!턍贑y▾鱧ժ[;7ᨷ∀*땒䪮1x霆Hᩭ☔\"r䝐7毟ᝰr惃3ꉭE+>僒澐": [
+ "Ta쎩aƝt쵯ⰪVb",
+ [
+ -5222472249213580702,
+ null,
+ -2851641861541559595,
+ null,
+ 4808804630502809099,
+ 5657671602244269874,
+ "5犲﨣4mᥣ?yf젫꾯|䋬잁$`Iⳉﴷ扳兝,'c",
+ false,
+ [
+ null,
+ {
+ "DyUIN쎾M仼惀⮥裎岶泭lh扠\u001e礼.tEC癯튻@_Qd4c5S熯A<\/\6U윲蹴Q=%푫汹\\\u20614b[C⒥Xe⊇囙b,服3ss땊뢍i~逇PA쇸1": -2.63273619193485312E17,
+ "Mq꺋貘k휕=nK硍뫞輩>㾆~ࡹ긐榵l⋙Hw뮢帋M엳뢯v⅃^": 1877913476688465125,
+ "ᶴ뻗`~筗免⚽টW˃⽝b犳䓺Iz篤p;乨A\u20ef쩏?疊m㝀컩뫡b탔鄃ᾈV(遢珳=뎲ିeF仢䆡谨8t0醄7㭧瘵⻰컆r厡궥d)a阄፷Ed&c伮1p": null,
+ "⯁w4曢\"(欷輡": "\"M᭫]䣒頳B\\燧ࠃN㡇j姈g⊸⺌忉ꡥF矉স%^",
+ "㣡Oᄦ昵⫮Y祎S쐐級㭻撥>{I$": -378474210562741663,
+ "䛒掷留Q%쓗1*1J*끓헩ᦢ哉쩧EↅIcꅡ\\?ⴊl귛顮4": false,
+ "寔愆샠5]䗄IH贈=d/偶?ॊn%晥D視N'᫂⚦|X쵩넽z질tskxDQ莮Aoﱻ뛓": true,
+ "钣xp?&\u001e侉/y䴼~?U篔蘚缣/I畚?Q绊": -3034854258736382234,
+ "꺲眀)⿷J暘pИfAV삕쳭Nꯗ4々'唄ⶑ伻㷯騑倭D*Ok꧁3b_<\/챣Xm톰ၕ䆄`*fl㭀暮滠毡?": [
+ "D男p`V뙸擨忝븪9c麺`淂⢦Yw⡢+kzܖ\fY1䬡H歁)벾Z♤溊-혰셢?1<-\u0005;搢Tᐁle\\ᛵߓﭩ榩訝-xJ;巡8깊蠝ﻓU$K": {
+ "Vꕡ諅搓W=斸s︪vﲜ츧$)iꡟ싉e寳?ጭムVથ嵬i楝Fg<\/Z|ꩆ-5'@ꃱ80!燱R쇤t糳]罛逇dṌ֣XHiͦ{": true,
+ "Ya矲C멗Q9膲墅携휻c\\딶G甔<\/.齵휴": -1.1456247877031811E-19,
+ "z#.OOJ": -8263224695871959017,
+ "崍_3夼ᮟ1F븍뽯ᦓ鴭V豈Ь": [{
+ "N蒬74": null,
+ "yuB?厅vK笗!ᔸcXQ旦컶P-녫mᄉ麟_": "1R@ 톘xa_|遘s槞d!d껀筤⬫薐焵먑D{\\6k共倌☀G~AS_D\"딟쬚뮥馲렓쓠攥WTMܭ8nX㩴䕅檹E\u0007ﭨN 2 ℆涐ꥏ꠵3▙玽|됨_\u2048",
+ "恐A C䧩G": {":M큣5e들\\ꍀ恼ᔄ靸|I﨏$)n": {
+ "|U䬫㟯SKV6ꛤ㗮\bn봻䲄fXT:㾯쳤'笓0b/ೢC쳖?2浓uO.䰴": "ཐ꼋e?``,ᚇ慐^8ꜙNM䂱\u0001IᖙꝧM'vKdꌊH牮r\\O@䊷ᓵ쀆(fy聻i툺\"?<\/峧ࣞ⓺ᤤ쵒߯ꎺ騬?)刦\u2072l慪y꺜ﲖTj+u",
+ "뽫hh䈵w>1ⲏ쐭V[ⅎ\\헑벑F_㖝⠗㫇h恽;῝汰ᱼ瀖J옆9RR셏vsZ柺鶶툤r뢱橾/ꉇ囦FGm\"謗ꉦ⨶쒿⥡%]鵩#ᖣ_蹎 u5|祥?O",
+ null,
+ 2.0150326776036215E-19,
+ null,
+ true,
+ false,
+ true,
+ {"\fa᭶P捤WWcf뚉ᬏ퓗ⳀW睹5:HXH=q7x찙X$)모r뚥ᆟ!Jﳸf": [
+ -2995806398034583407,
+ [
+ 6441377066589744683,
+ "Mﶒ醹i)Gἦ廃s6몞 KJ౹礎VZ螺费힀\u0000冺업{谥'뱻:.ꘘ굄奉攼Di᷑K鶲y繈욊阓v㻘}枭캗e矮1c?휐\"4\u0005厑莔뀾墓낝⽴洗ṹ䇃糞@b1\u0016즽Y轹",
+ {
+ "1⽕⌰鉟픏M㤭n⧴ỼD#%鐘⊯쿼稁븣몐紧ᅇ㓕ᛖcw嬀~ഌ㖓(0r⧦Q䑕髍ര铂㓻R儮\"@ꇱm❈頌8}㿹犴?xn잆R": 2.07321075750427366E18,
+ "˳b18㗈䃟柵Z曆VTAu7+㛂cb0Wp執<\/臋뭡뚋刼틮荋벲TLP预庰܈G\\O@VD'鱃#乖끺*鑪ꬳ?Mޞdﭹ{␇圯쇜㼞顄︖Y홡g": [{
+ "0a,FZ": true,
+ "2z̬蝣ꧦ驸\u0006L↛Ḣ4๚뿀'?lcwᄧ㐮!蓚䃦-|7.飑挴.樵*+1ﮊ\u0010ꛌ%貨啺/JdM:똍!FBe?鰴㨗0O财I藻ʔWAG쳛u`<\/I": [{
+ "$τ5V鴐a뾆両環iZp頻යn븃v": -4869131188151215571,
+ "*즢[⦃b礞R◚nΰꕢH=귰燙[yc誘g䆌?ଜ臛": {
+ "洤湌鲒)⟻\\䥳va}PeAMnN[": "㐳ɪ/(軆lZR,Cp殍ȮN啷\"3B婴?i=r$펽ᤐ쀸",
+ "阄R4㒿㯔ڀ69ZᲦ2癁핌噗P崜#\\-쭍袛&鐑/$4童V꩑_ZHA澢fZ3": {"x;P{긳:G閉:9?活H": [
+ "繺漮6?z犞焃슳\">ỏ[Ⳛ䌜녏䂹>聵⼶煜Y桥[泥뚩MvK$4jtロ",
+ "E#갶霠좭㦻ୗ먵F+䪀o蝒ba쮎4X㣵 h",
+ -335836610224228782,
+ null,
+ null,
+ [
+ "r10>danjY짿bs{",
+ [
+ -9.594464059325631E-23,
+ 1.0456894622831624E-20,
+ null,
+ 5.803973284253454E-20,
+ -8141787905188892123,
+ true,
+ -4735305442504973382,
+ 9.513150514479281E-20,
+ "7넳$螔忷㶪}䪪l짴\u0007鹁P鰚HF銏ZJﳴ/⍎1ᷓ忉睇ᜋ쓈x뵠m䷐窥Ꮤ^\u0019ᶌ偭#ヂt☆၃pᎍ臶䟱5$䰵&分숝]䝈뉍♂坎\u0011<>",
+ "C蒑貑藁lﰰ}X喇몛;t밿O7/f\u0015kI嘦<ዴ㟮ᗎZ`GWퟩ瑹ᅴB꿊칈??R校s脚",
+ {
+ "9珵戬+AU^洘拻ቒy柭床'粙XG鞕繀伪%]hC,$輙?Ut乖Qm떚W8઼}~q⠪rU䤶CQ痗ig@#≲t샌f㈥酧l;y闥ZH斦e⸬]j⸗?ঢ拻퀆滌": null,
+ "畯}㧢J罚帐VX㨑>1ꢶkT⿄蘥㝑o|<嗸層沈挄GEOM@-䞚䧰$만峬輏䠱V✩5宸-揂D'㗪yP掶7b⠟J㕻SfP?d}v㼂Ꮕ'猘": {
+ "陓y잀v>╪": null,
+ "鬿L+7:됑Y=焠U;킻䯌잫!韎ஔ\f": {
+ "駫WmGጶ": {
+ "\\~m6狩K": -2586304199791962143,
+ "ႜࠀ%͑l⿅D.瑢Dk%0紪dḨTI픸%뗜☓s榗\"?V籄7w髄♲쟗翛歂E䤓皹t ?)ᄟ鬲鐜6C": {
+ "_췤a圷1\u000eB-XOy缿請∎$`쳌eZ~杁튻/蜞`塣\"⪰\"沒l}蕌\\롃荫氌.望wZ|o!)Hn獝qg}": null,
+ "kOSܧ䖨钨:಼鉝ꭝO醧S`십`ꓭ쭁ﯢN&Et㺪馻㍢ⅳ㢺崡ຊ蜚锫\\%ahx켨|ż劻ꎄ㢄쐟A躊p譞綨Ir쿯\u0016ﵚOd럂*僨郀N*b㕷63z": {
+ ":L5r+T㡲": [{
+ "VK泓돲ᮙRy㓤➙Ⱗ38oi}LJቨ7Ó㹡*q)1豢⛃e뙪壥镇枝7G藯g㨛oI䄽 孂L缊ꋕ'EN`": -2148138481412096818,
+ "`⛝ᘑ$(खꊲ⤖ᄁꤒ䦦3=)]Y㢌跨NĴ驳줟秠++d孳>8ᎊ떩EꡣSv룃 쯫أ?#E|᭙㎐?zv:5祉^⋑V": [
+ -1.4691944435285607E-19,
+ 3.4128661569395795E17,
+ "㐃촗^G9佭龶n募8R厞eEw⺡_ㆱ%⼨D뉄퉠2ꩵᛅⳍ搿L팹Lවn=\"慉념ᛮy>!`g!풲晴[/;?[v겁軇}⤳⤁핏∌T㽲R홓遉㓥",
+ "愰_⮹T䓒妒閤둥?0aB@㈧g焻-#~跬x<\/舁P݄ꐡ=\\׳P\u0015jᳪᢁq;㯏l%᭗;砢觨▝,謁ꍰGy?躤O黩퍋Y㒝a擯\n7覌똟_䔡]fJ晋IAS",
+ 4367930106786121250,
+ -4.9421193149720582E17,
+ null,
+ {
+ ";ᄌ똾柉곟ⰺKpፇ䱻ฺ䖝{o~h!eꁿ욄ښ\u0002y?xUd\u207c悜ꌭ": [
+ 1.6010824122815255E-19,
+ [
+ "宨︩9앉檥pr쇷?WxLb",
+ "氇9】J玚\u000f옛呲~ 輠1D嬛,*mW3?n휂糊γ虻*ᴫ꾠?q凐趗Ko↦GT铮",
+ "㶢ថmO㍔k'诔栀Z蛟}GZ钹D",
+ false,
+ -6.366995517736813E-20,
+ -4894479530745302899,
+ null,
+ "V%II璅䅛䓎풹ﱢ/pU9se되뛞x梔~C)䨧䩻蜺(g㘚R?/Ự[忓C뾠ࢤc왈邠买?嫥挤풜隊枕",
+ ",v碍喔㌲쟚蔚톬៓ꭶ",
+ 3.9625444752577524E-19,
+ null,
+ [
+ "kO8란뿒䱕馔b臻⍟隨\"㜮鲣Yq5m퐔K#ꢘug㼈ᝦ=P^6탲@䧔%$CqSw铜랊0&m⟭<\/a逎ym\u0013vᯗ": true,
+ "洫`|XN뤮\u0018詞=紩鴘_sX)㯅鿻Ố싹": 7.168252736947373E-20,
+ "ꛊ饤ﴏ袁(逊+~⽫얢鈮艬O힉7D筗S곯w操I斞᠈븘蓷x": [[[[
+ -7.3136069426336952E18,
+ -2.13572396712722688E18,
+ {
+ "硢3R:o칢行E<=\u0018ၬYuH!\u00044U%卝炼2>\u001eSi$⓷ꒈ'렢gᙫ番ꯒ㛹럥嶀澈v;葷鄕x蓎\\惩+稘UEᖸﳊ㊈壋N嫿⏾挎,袯苷ኢ\\x|3c": 7540762493381776411,
+ "?!*^ᢏ窯?\u0001ڔꙃw虜돳FgJ?&⨫*uo籤:?}ꃹ=ٴ惨瓜Z媊@ત戹㔏똩Ԛ耦Wt轁\\枒^\\ꩵ}}}ꀣD\\]6M_⌫)H豣:36섘㑜": {
+ ";홗ᰰU㙛`D왔ཿЃS회爁\u001b-㢈`봆?盂㛣듿ᦾ蒽_AD~EEຆ㊋(eNwk=Rɠ峭q\"5Ἠ婾^>'ls\n8QAK)- Q䲌mo펹L_칍樖庫9꩝쪹ᘹ䑖瀍aK ?*趤f뭓廝p=磕",
+ "哑z懅ᤏ-ꍹux쀭",
+ [
+ true,
+ 3998739591332339511,
+ "ጻ㙙?᳸aK<\/囩U`B3袗ﱱ?\"/k鏔䍧2l@쿎VZ쨎/6ꃭ脥|B?31+on颼-ꮧ,O嫚m `KH葦:粘i]aSU쓙$쐂f+詛頖b",
+ [{"^<9<箝&絡;%i2攑紴\\켉h쓙-柂䚝ven\u20f7浯-Ꮏ\r^훁䓚헬\u000e?\\ㅡֺJ떷VOt": [{
+ "-卶k㘆혐y⎱㢬sS+^瞥h;ᾷj;抭\u0003밫f<\/5Ⱗ裏_朻%*[-撵䷮彈-芈": {
+ "㩩p3篊G|宮hz䑊o곥j^Co0": [
+ 653239109285256503,
+ {"궲?|\":N1ۿ氃NZ#깩:쇡o8킗ࡊ[\"됸Po핇1(6鰏$膓}⽐*)渽J'DN<썙긘毦끲Ys칖": {
+ "2Pr?Xjㆠ?搮/?㓦柖馃5뚣Nᦼ|铢r衴㩖\"甝湗ܝ憍": "\"뾯i띇筝牻$珲/4ka $匝휴译zbAᩁꇸ瑅&뵲衯ꎀᆿ7@ꈋ'ᶨH@ᠴl+",
+ "7뢽뚐v?4^ꊥ_⪛.>pởr渲<\/⢕疻c\"g䇘vU剺dஔ鮥꒚(dv祴X⼹\\a8y5坆": true,
+ "o뼄B욞羁hr폘뒚U5pꪴfg!6\\\"爑쏍䢱W<ﶕ\\텣珇oI/BK뺡'谑♟[Ut븷亮g(\"t⡎有?ꬊ躺翁艩nl F⤿蠜": 1695826030502619742,
+ "ۊ깖>ࡹ햹^ⵕ쌾BnN〳2C䌕tʬ]찠?ݾ2饺蹳ぶꌭ訍\"◹ᬁD鯎4e滨T輀ﵣ3\u20f3킙D瘮g\\擦+泙ၧ 鬹ﯨַ肋7놷郟lP冝{ߒhড়r5,": null,
+ "ΉN$y{}2\\NⱙK'8ɜͣwt,.钟廣䎘ꆚk媄_": null,
+ "䎥eᾆᝦ읉,Jުn岪㥐s搖謽䚔5t㯏㰳㱊ZhD䃭f絕s鋡篟a`Q鬃┦鸳n_靂(E4迠_觅뷝_宪D(NL疶hL追V熑%]v肫=惂!5⬒\u001f喺4랪옑": {
+ "2a輍85먙R㮧㚪Sm}E2yꆣꫨrRym㐱膶ᔨ\\t綾A☰.焄뙗9<쫷챻䒵셴᭛䮜.<\/慌꽒9叻Ok䰊Z㥪幸k": [
+ null,
+ true,
+ {"쌞쐍": {
+ "▟GL K2i뛱iQ\"̠.옛1X$}涺]靎懠ڦ늷?tf灟ݞゟ{": 1.227740268699265E-19,
+ "꒶]퓚%ฬK❅": [{
+ "(ෛ@Ǯっ䧼䵤[aテൖvEnAdU렖뗈@볓yꈪ,mԴ|캁(而첸죕CX4Y믅": "2⯩㳿ꢚ훀~迯?᪑\\啚;4X\u20c2襏B箹)俣eỻw䇄",
+ "75༂f詳䅫ꐧ鏿 }3\u20b5'∓䝱虀f菼Iq鈆﨤g퍩)BFa왢d0뮪痮M鋡nw∵謊;ꝧf美箈ḋ*\u001c`퇚퐋䳫$!V#N㹲抗ⱉ珎(V嵟鬒_b㳅\u0019": null,
+ "e_m@(i㜀3ꦗ䕯䭰Oc+-련0뭦⢹苿蟰ꂏSV䰭勢덥.ྈ爑Vd,ᕥ=퀍)vz뱊ꈊB_6듯\"?{㒲&㵞뵫疝돡믈%Qw限,?\r枮\"? N~癃ruࡗdn&": null,
+ "㉹&'Pfs䑜공j<\/?|8oc᧨L7\\pXᭁ 9᪘": -2.423073789014103E18,
+ "䝄瑄䢸穊f盈,B뾧푗횵B1쟢f\u001f凄": "魖⚝2儉j꼂긾껢嗎0ࢇ纬xI4](`蕞;픬\fC\"斒\")2櫷I﹥迧",
+ "ퟯ詔x悝령+T?Bg⥄섅kOeQ큼㻴*{E靼6氿L缋\u001c둌-㥂2==-츫I즃㠐Lg踞ꙂEG貨鞠\"\u0014d'.缗gI-lIb䋱ᎂDy缦?": null,
+ "紝M㦁犿w浴詟棓쵫G:䜁?V2ힽ7N*n&㖊Nd-'ຊ?-樹DIv⊜)g䑜9뉂ㄹ푍阉~ꅐ쵃#R^\u000bB䌎䦾]p.䀳": [{"ϒ爛\"ꄱ︗竒G䃓-ま帳あ.j)qgu扐徣ਁZ鼗A9A鸦甈!k蔁喙:3T%&㠘+,䷞|챽v䚞문H<\/醯r셓㶾\\a볜卺zE䝷_죤ဵ뿰CB": [
+ 6233512720017661219,
+ null,
+ -1638543730522713294,
+ false,
+ -8901187771615024724,
+ [
+ 3891351109509829590,
+ true,
+ false,
+ -1.03836679125188032E18,
+ {
+ "j랎:g曞ѕᘼ}链N",
+ -1.1103819473845426E-19,
+ true,
+ [
+ true,
+ null,
+ -7.9091791735309888E17,
+ true,
+ {"}蔰鋈+ꐨ啵0?g*사%`J?*": [{
+ "\"2wG?yn,癷BK\\龞䑞x?蠢": -3.7220345009853505E-19,
+ ";饹়❀)皋`噿焒j(3⿏w>偍5X薙婏聿3aFÆÝ": "2,ꓴg?_섦_>Y쪥션钺;=趘F~?D㨫\bX?㹤+>/믟kᠪ멅쬂Uzỵ]$珧`m雁瑊ඖ鯬cꙉ梢f묛bB",
+ "♽n$YjKiXX*GO贩鏃豮祴遞K醞眡}ꗨv嵎꼷0+M菋eH徸J:⼐悥B켽迚㯃b諂\u000bjꠜ碱逮m8": [
+ "푷ﻯd8ﱖ嬇ភH鹎⡱᱅0g:果6$GQ췎{vᷧYy-脕x偹砡館⮸C蓼ꏚ=軄H犠G谖ES詤Z蠂3l봟hᅭ7䦹1GPQG癸숟~[#駥8zQ뛣J소obg,",
+ null,
+ 1513751096373485652,
+ null,
+ -6.851466660824754E-19,
+ {"䩂-2ٰK솖풄꾚ႻP앳1H鷛wmR䗂皎칄?醜<\/&ࠧ㬍X濬䵈K`vJ륒Q/IC묛!;$vϑ": {
+ "@-ꚗxྐྵ@m瘬\u0010U絨ﮌ驐\\켑寛넆T=tQ㭤L연@脸삯e-:⩼u㎳VQ㋱襗ຓ<Ⅶ䌸cML3+\u001e_C)r\\9+Jn\\Pﺔ8蠱檾萅Pq鐳话T䄐I": -1.80683891195530061E18,
+ "ᷭዻU~ཷsgSJ`᪅'%㖔n5픆桪砳峣3獮枾䌷⊰呀": {
+ "Ş䓰邟自~X耤pl7间懑徛s첦5ਕXexh⬖鎥᐀nNr(J컗|ૃF\"Q겮葲놔엞^겄+㈆话〾희紐G'E?飕1f❼텬悚泬먐U睬훶Qs": false,
+ "(\u20dag8큽튣>^Y{뤋.袊䂓;_g]S\u202a꽬L;^'#땏bႌ?C緡<䝲䲝断ꏏ6\u001asD7IK5Wxo8\u0006p弊⼂ꯍ扵\u0003`뵂픋%ꄰ⫙됶l囏尛+䗅E쟇\\": [
+ true,
+ {
+ "\n鱿aK㝡␒㼙2촹f;`쾏qIࡔG}㝷䐍瓰w늮*粅9뒪ㄊCj倡翑閳R渚MiUO~仨䜶RꙀA僈㉋⦋n{㖥0딿벑逦⥻0h薓쯴Ꝼ": [
+ 5188716534221998369,
+ 2579413015347802508,
+ 9.010794400256652E-21,
+ -6.5327297761238093E17,
+ 1.11635352494065523E18,
+ -6656281618760253655,
+ {
+ "": ")?",
+ "TWKLꑙ裑꺔UE俸塑炌Ũ᜕-o\"徚#": {"M/癟6!oI51ni퐚=댡>xꍨ\u0004 ?": {
+ "皭": {"⢫䋖>u%w잼<䕏꘍P䋵$魋拝U䮎緧皇Y훂&|羋ꋕ잿cJ䨈跓齳5\u001a삱籷I꿾뤔S8㌷繖_Yឯ䲱B턼O歵F\\l醴o_欬6籏=D": [
+ false,
+ true,
+ {"Mt|ꏞD|F궣MQ뵕T,띺k+?㍵i": [
+ 7828094884540988137,
+ false,
+ {
+ "!༦鯠,&aﳑ>[euJꏽ綷搐B.h": -7648546591767075632,
+ "-n켧嘰{7挐毄Y,>❏螵煫乌pv醑Q嶚!|⌝責0왾덢ꏅ蛨S\\)竰'舓Q}A釡5#v": 3344849660672723988,
+ "8閪麁V=鈢1녈幬6棉⪮둌\u207d᚛驉ꛃ'r䆉惏ै|bἧﺢᒙ<=穊强s혧eꮿ慩⌡ \\槳W븧J檀C,ᘉ의0俯퀉M;筷ࣴ瓿{늊埂鄧_4揸Nn阼Jੵ˥(社": true,
+ "o뼀vw)4A뢵(a䵢)p姃뛸\u000fK#KiQp\u0005ꅍ芅쏅": null,
+ "砥$ꥸ┇耽u斮Gc{z빔깎밇\\숰\u001e괷各㶇쵿_ᴄ+h穢p촀Ნ䃬z䝁酳ӂ31xꔄ1_砚W렘G#2葊P ": [
+ -3709692921720865059,
+ null,
+ [
+ 6669892810652602379,
+ -135535375466621127,
+ "뎴iO}Z? 馢녱稹ᄾ䐩rSt帤넆&7i騏멗畖9誧鄜'w{Ͻ^2窭외b㑎粖i矪ꦨ탪跣)KEㆹ\u0015V8[W?⽉>'kc$䨘ᮛ뉻٬M5",
+ 1.10439588726055846E18,
+ false,
+ -4349729830749729097,
+ null,
+ [
+ false,
+ "_蠢㠝^䟪/D녒㡋ỎC䒈판\u0006એq@O펢%;鹐쏌o戥~A[ꡉ濽ỳ&虃荣唙藍茨Ig楡꒻M窓冉?",
+ true,
+ 2.17220752996421728E17,
+ -5079714907315156164,
+ -9.960375974658589E-20,
+ "ᾎ戞༒",
+ true,
+ false,
+ [[
+ "ⶉᖌX⧕홇)g엃x뚐癟\u0002",
+ -5185853871623955469,
+ {
+ "L㜤9ợㇶK鐰⋓V뽋˖!斫as|9"፬䆪?7胜&n薑~": -2.11545634977136992E17,
+ "O8뀩D}캖q萂6༣㏗䈓煮吽ਆᎼDᣘ폛;": false,
+ "YTᡅ^L㗎cbY$pᣞ縿#fh!ꘂb삵玊颟샞ဢ$䁗鼒몁~rkH^:닮먖츸륈⪺쒉砉?㙓扫㆕꣒`R䢱B酂?C뇞<5Iޚ讳騕S瞦z": null,
+ "\\RB?`mG댵鉡幐物䵎有5*e骄T㌓ᛪ琾駒Ku\u001a[柆jUq8⋈5鿋츿myﻗ?雍ux?": 5828963951918205428,
+ "n0晅:黯 xu씪^퓞cB㎊ᬍ⺘٤փ~B岚3㥕擄vᲂ~F?C䶖@$m~忔S왖㲚?챴⊟W#벌{'㰝I䝠縁s樘\\X뢻9핡I6菍ㄛ8쯶]wॽ0L\"q": null,
+ "x增줖j⦦t䏢᎙㛿Yf鼘~恄4惊\u209c": "oOhbᤃz&Bi犑\\3B㩬劇䄑oŁ쨅孥멁ຖacA㖫借㞝vg싰샂㐜#譞⢤@k]鋰嘘䜾L熶塥_<\/⍾屈ﮊ_mY菹t뙺}Ox=w鮮4S1ꐩמּ'巑",
+ "㗓蟵ꂾe蠅匳(JP䗏\u0089耀왲": [{
+ "ᤃ㵥韎뤽\r?挥O쯡⇔㞚3伖\u0005P⋪\"D궣QLn(⚘罩䩢Ŏv䤘尗뼤됛O淽鋋闚r崩a{4箙{煷m6〈": {
+ "l곺1L": {
+ "T'ਤ?砅|੬Km]䄩\"(<\/6U爢䫈倔郴l2㴱^줣k'L浖L鰄Rp今鎗⒗C얨M훁㡧ΘX粜뫈N꤇輊㌻켑#㮮샶-䍗룲蠝癜㱐V>=\\I尬癤t=": 7648082845323511446,
+ "鋞EP:<\/_`ၧe混ㇹBd⯢㮂驋\\q碽饩跓྿ᴜ+j箿렏㗑yK毢宸p謹h䦹乕U媣\\炤": [[
+ "3",
+ [
+ true,
+ 3.4058271399411134E-20,
+ true,
+ "揀+憱f逮@먻BpW曉\u001a㣐⎊$n劈D枤㡞좾\u001aᛁ苔౩闝1B䷒Ṋ➐ꀞꐃ磍$t_:蘺⮼(#N",
+ 697483894874368636,
+ [
+ "vᘯ锴)0訶}䳅⩚0O壱韈ߜ\u0018*U鍾䏖=䧉뽑单휻ID쿇嘗?ꌸῬ07",
+ -5.4858784319382006E18,
+ 7.5467775182251151E18,
+ -8911128589670029195,
+ -7531052386005780140,
+ null,
+ [
+ null,
+ true,
+ [[{
+ "1欯twG<\/Q:0怯押殃탷聫사<ỗꕧ蚨䡁nDꌕ\u001c녬~蓩鲃g儊>ꏡl㻿/⑷*챳6㻜W毤緛ﹺᨪ4\u0013뺚J髬e3쳸䘦伧?恪&{L掾p+M䏊d娘6": {
+ "2p첼양棜h䜢﮶aQ*c扦v︥뮓kC寵횂S銩&ǝ{O*य़iH`U큅ࡓr䩕5ꄸ?`\\᧫?ᮼ?t〟崾훈k薐ì/iy꤃뵰z1<\/AQ#뿩8jJ1z@u䕥": 1.82135747285215155E18,
+ "ZdN &=d년ᅆ'쑏ⅉ:烋5&៏ᄂ汎来L㯄固{钧u\\㊏튚e摑&t嗄ꖄUb❌?m䴘熚9EW": [{
+ "ଛ{i*a(": -8.0314147546006822E17,
+ "⫾ꃆY\u000e+W`௸ \"M뒶+\\뷐lKE}(NT킶Yj選篒쁶'jNQ硾(똡\\\"逌ⴍy? IRꜘ鄬﨧:M\\f⠋Cꚜ쫊ᚴNV^D䕗ㅖἔIao꿬C⍏8": [
+ 287156137829026547,
+ {
+ "H丞N逕⯲": {"": {
+ "7-;枮阕梒9ᑄZ": [[[[
+ null,
+ {
+ "": [[[[
+ -7.365909561486078E-19,
+ 2948694324944243408,
+ null,
+ [
+ true,
+ "荒\"并孷䂡쵼9o䀘F\u0002龬7⮹Wz%厖/*? a*R枈㌦됾g뒠䤈q딄㺿$쮸tᶎ릑弣^鏎<\/Y鷇驜L鿽<\/춋9Mᲆឨ^<\/庲3'l낢",
+ "c鮦\u001b두\\~?眾ಢu݆綑෪蘛轋◜gȃ<\/ⴃcpkDt誩܅\"Y",
+ [[
+ null,
+ null,
+ [
+ 3113744396744005402,
+ true,
+ "v(y",
+ {
+ "AQ幆h쾜O+꺷铀ꛉ練A蚗⼺螔j㌍3꽂楎䥯뎸먩?": null,
+ "蠗渗iz鱖w]擪E": 1.2927828494783804E-17,
+ "튷|䀭n*曎b✿~杤U]Gz鄭kW|㴚#㟗ഠ8u擨": [[
+ true,
+ null,
+ null,
+ {"⾪壯톽g7?㥜ώQꑐ㦀恃㧽伓\\*᧰閖樧뢇赸N휶䎈pI氇镊maᬠ탷#X?A+kНM ༑؝?5鰜ṚY즫궔 =ঈ;ﳈ?*s|켦蜌wM笙莔": [
+ null,
+ -3808207793125626469,
+ [
+ -469910450345251234,
+ 7852761921290328872,
+ -2.7979740127017492E18,
+ 1.4458504352519893E-20,
+ true,
+ "㽙깹?먏䆢:䴎ۻg殠JBTU⇞}ꄹꗣi#I뵣鉍r혯~脀쏃#釯:场:䔁>䰮o'㼽HZ擓௧nd",
+ [
+ 974441101787238751,
+ null,
+ -2.1647718292441327E-19,
+ 1.03602824249831488E18,
+ [
+ null,
+ 1.0311977941822604E-17,
+ false,
+ true,
+ {
+ "": -3.7019778830816707E18,
+ "E峾恆茍6xLIm縂0n2视֯J-ᤜz+ᨣ跐mYD豍繹䊓몓ﴀE(@詮(!Y膽#᎙2䟓섣A䈀㟎,囪QbK插wcG湎ꤧtG엝x⥏俎j'A一ᯥ뛙6ㅑ鬀": 8999803005418087004,
+ "よ殳\\zD⧅%Y泥簳Uꈩ*wRL{3#3FYHା[d岀䉯T稉駅䞘礄P:闈W怏ElB㤍喬赔bG䠼UNw鰯闀楈ePsDꥷ⊊": [
+ 6.77723657904486E-20,
+ null,
+ [
+ "ཚ_뷎꾑蹝q'㾱ꂓ钚蘞慵렜떆`ⴹ⎼櫯]J?[t9Ⓢ !컶躔I᮸uz>3a㠕i,錃L$氰텰@7녫W㸮?羧W뇧ꃞ,N鋮숪2ɼ콏┍䁲6",
+ "&y?뢶=킕올Za惻HZk>c\u20b58i?ꦶcfBv잉ET9j䡡",
+ "im珊Ճb칧校\\뼾쯀",
+ 9.555715121193197E-20,
+ true,
+ {
+ "<㫚v6腓㨭e1㕔&&V∌ᗈT奄5Lጥ>탤?튣瑦㳆ꉰ!(ᙪ㿬擇_n쌯IMΉ㕨櫈ᱷ5풔蟹&L.첽e鰷쯃劼b#ﭶ퓀7뷄Wr㢈Tʴશ㶑澕鍍%": -1810142373373748101,
+ "fg晌o?߲ꗄ;>C>?=鑰監侯Kt굅": true,
+ "䫡蓺ꑷ]C蒹㦘\"1ః@呫\u0014NL䏾eg呮፳,r$裢k>/\\?ㄤᇰﻛ쉕1'Ċ\" \\_?쨔\"ʾr: 9S䘏禺ᪧꄂ㲄",
+ [[{
+ "*硙^+E쌺I1䀖ju?:⦈Ꞓl竣迃xKC/饉:\fl\"XTFᄄ蟭,芢<\/骡軺띜hꏘ\u001f銿<棔햳▨(궆*=乥b8\\媦䷀뫝}닶ꇭ(Kej䤑M": [{
+ "1Ꮼ?>옿I╅C<ގ?ꊌ冉SV5A㢊㶆z-๎玶绢2F뵨@㉌뀌o嶔f9-庒茪珓뷳4": null,
+ ";lᰳ": "CbB+肻a䄷苝*/볳+/4fq=㰁h6瘉샴4铢Y骐.⌖@哼猎㦞+'gꋸ㒕ߤ㞑(䶒跲ti⑴a硂#No볔",
+ "t?/jE幸YHT셵⩎K!Eq糦ꗣv刴w\"l$ο:=6:移": {
+ "z]鑪醊嫗J-Xm銌翁絨c里됏炙Ep㣋鏣똼嚌䀓GP﹖cmf4鹭T䅿꣭姧wy6ꦶ;S&(}ᎧKxᾂQ|t뻳k\"d6\"|Ml췆hwLt꼼4$&8Պ褵婶鯀9": {"嵃닢ᒯ'd᧫䳳#NXe3-붋鸿ଢ떓%dK\u0013䲎ꖍYV.裸R⍉rR3蟛\\:젯:南ĺLʆ넕>|텩鴷矔ꋅⒹ{t孶㓑4_": [
+ true,
+ null,
+ [
+ false,
+ "l怨콈lᏒ",
+ {
+ "0w䲏嬧-:`䉅쉇漧\\܂yㄨb%㽄j7ᦶ涶<": 3.7899452730383747E-19,
+ "ꯛTẀq纤q嶏V?\"g}ი艹(쥯B T騠I=仵및X": {"KX6颠+&ᅃ^f畒y[": {
+ "H?뱜^?꤂-⦲1a㋞&ꍃ精Ii챪咽쬘唂쫷<땡劈훫놡o㥂\\ KⴙD秼F氮[{'좴:례晰Iq+I쭥_T綺砸GO煝䟪ᚪ`↹l羉q쐼D꽁ᜅ훦: vUV": true,
+ "u^yﳍ0㱓#[y뜌앸ꊬL㷩?蕶蘾⻍KӼ": -7931695755102841701,
+ "䤬轉車>\u001c鴵惋\"$쯃྆⇻n뽀G氠S坪]ಲꨍ捇Qxኻ椕駔\\9ࣼ읜磡煮뺪ᶚ볝l㕆t+sζ": [[[
+ true,
+ false,
+ [
+ null,
+ 3363739578828074923,
+ true,
+ {
+ "\"鸣詩 볰㑵gL㯦춝旫}ED辗ﮈI쀤-ꧤ|㠦Z\"娑ᕸ4爏騍㣐\"]쳝Af]茛⬻싦o蚁k䢯䩐菽3廇喑ޅ": 4.5017999150704666E17,
+ "TYႇ7ʠ值4챳唤~Zo&ݛ": false,
+ "`塄J袛㭆끺㳀N㺣`꽐嶥KﯝSVᶔ∲퀠獾N딂X\"ᤏhNﬨvI": {"\u20bb㭘I䖵䰼?sw䂷쇪](泒f\"~;꼪Fԝsᝦ": {"p,'ꉂ軿=A蚶?bƉ㏵䅰諬'LYKL6B깯⋩겦뎙(ᜭ\u0006噣d꾆㗼Z;䄝䚔cd<情@䞂3苼㸲U{)<6&ꩻ钛\u001au〷N숨囖愙j=BXW욕^x芜堏Ῑ爂뛷꒻t✘Q\b": [[
+ "籛&ଃ䩹.ꃩ㦔\\C颫#暪&!勹ꇶ놽攺J堬镙~軌C'꾖䣹㮅岃ᙴ鵣",
+ 4.317829988264744E15,
+ 6.013585322002147E-20,
+ false,
+ true,
+ null,
+ null,
+ -3.084633632357326E-20,
+ false,
+ null,
+ {
+ "\"짫愔昻 X\"藣j\"\"먁ཅѻ㘤㬯0晲DU㸃d벀윒l䦾c*3": null,
+ "谈Wm陧阦咟ฯ歖擓N喴㋐銭rCCnVࢥ^♼Ⅾ젲씗刊S༝+_t赔\\b䚍뉨ꬫ6펛cL䊘<\/澤pF懽&H": [
+ null,
+ {
+ "W\"HDUuΌ퀟M'P4H똆ⰱﮯ<\/凐蘲\"C鴫ﭒж}ꭩ쥾t5yd诪ﮡ퍉ⴰ@?氐醳rj4I6Qt": 6.9090159359219891E17,
+ "絛ﳛ⺂": {"諰P㗮聦`ZQ?ꫦh*റcb⧱}埌茥h{棩렛툽o3钛5鮁l7Q榛6_g)ὄ\u0013kj뤬^爖eO4Ⱈ槞鉨ͺ订%qX0T썗嫷$?\\\"봅늆'%": [
+ -2.348150870600346E-19,
+ [[
+ true,
+ -6619392047819511778,
+ false,
+ [[
+ -1.2929189982356161E-20,
+ 1.7417192219309838E-19,
+ {"?嵲2࿐2\u0001啑㷳c縯": [
+ null,
+ [
+ false,
+ true,
+ 2578060295690793218,
+ {
+ "?\"殃呎#㑑F": true,
+ "}F炊_殛oU헢兔Ꝉ,赭9703.B数gTz3⏬": {
+ "5&t3,햓Mݸᵣ㴵;꣫䩍↳#@뫷䠅+W-ࣇzᓃ鿕ಔ梭?T䮑ꥬ旴]u뫵막bB讍:왳둛lEh=숾鱠p咐$짏#?gᗊv㷵.斈u頻\u0018-G.": "뽙m-ouࣤ牷\"`Ksꕞ筼3HlȨvC堈\"I]㖡玎r먞#'W賜鴇k'c룼髋䆿飉㗆xg巤9;芔cጐ/ax䊨♢큓r吓㸫䢗da\"]屣`",
+ ":M딪<䢥喠\u0013㖅x9蕐㑂XO]f*Q呰瞊吭VP@9,㨣 D\\穎vˤƩs㜂-曱唅L걬/롬j㈹EB8g<\/섩o渀\"u0y&룣": ">氍緩L/䕑돯Ꟙ蕞^aB뒣+0jK⪄瑨痜LXK^1qK{淚t츔X:Vm{2r獁B뾄H첚7氥?쉟䨗ꠂv팳圎踁齀\\",
+ "D彤5㢷Gꪻ[lㄆ@⓰絳[ଃ獽쮹☒[*0ꑚ㜳": 9022717159376231865,
+ "ҖaV銣tW+$魿\u20c3亜~뫡ᙰ禿쨽㏡fṼzE/h": "5臐㋇Ჯ쮺? 昨탰Wム밎#'\"崲钅U?幫뺀⍾@4kh>騧\\0ҾEV=爐͌U捀%ꉼ 㮋<{j]{R>:gԩL\u001c瀈锌ﯲﳡꚒ'⫿E4暍㌗뵉X\"H",
+ "ᱚגּ;s醒}犍SἿ㦣&{T$jkB\\\tḮ앾䤹o<避(tW": "vb⯽䴪䮢@|)",
+ "⥒퐁껉%惀뗌+녣迺顀q條g⚯i⤭룐M琹j̈́⽜A": -8385214638503106917,
+ "逨ꊶZ<\/W⫟솪㎮ᘇb?ꠔi\"H㧺x韒Xꫨฟ|]窽\u001a熑}Agn?Mᶖa9韲4$3Ỵ^=쏍煤ፐ돷2䣃%鷠/eQ9頸쥎",
+ 2398360204813891033,
+ false,
+ 3.2658897259932633E-19,
+ null,
+ "?ꚃ8Nn㞷幵d䲳䱲뀙ꪛQ瑓鎴]䩋-鰾捡䳡??掊",
+ false,
+ -1309779089385483661,
+ "ᦲxu_/yecR.6芏.ᜇ過 ~",
+ -5658779764160586501,
+ "쒌:曠=l썜䢜wk#s蕚\"互㮉m䉤~0듐䋙#G;h숄옥顇勹(C7㢅雚㐯L⠅VV簅<",
+ null,
+ -4.664877097240962E18,
+ -4.1931322262828017E18,
+ {
+ ",": {
+ "v㮟麑䄠뤵g{M띮.\u001bzt뢜뵡0Ǥ龍떟Ᾰ怷ϓRT@Lꀌ樂U㏠⾕e扉|bJg(뵒㠶唺~ꂿ(땉x⻫싉쁊;%0鎻V(o\f,N鏊%nk郼螺": -1.73631993428376141E18,
+ "쟧摑繮Q@Rᕾ㭚㾣4隅待㓎3蒟": [
+ 4971487283312058201,
+ 8973067552274458613,
+ {
+ "`a揙ᣗ\u0015iBo¸": 4.3236479112537999E18,
+ "HW&퉡ぁ圍Y?瑡Qy훍q!帰敏s舠㫸zꚗaS歲v`G株巷Jp6킼 (귶鍔⾏⡈>M汐㞍ቴ꙲dv@i㳓ᇆ?黍": [
+ null,
+ 4997607199327183467,
+ "E㻎蠫ᐾ高䙟蘬洼旾텛㇛?'M$㣒蔸=A_亀绉앭rN帮",
+ null,
+ [{
+ "Eᑞ)8餧A5u&㗾q?": [
+ -1.969987519306507E-19,
+ null,
+ [
+ 3.42437673373841E-20,
+ true,
+ "e걷M墁\"割P␛퍧厀R䱜3ﻴO퓫r﹉⹊",
+ [
+ -8164221302779285367,
+ [
+ true,
+ null,
+ "爘y^-?蘞Ⲽꪓa␅ꍨ}I",
+ 1.4645984996724427E-19,
+ [{
+ "tY좗⧑mrzﺝ㿥ⴖj諅\u0000q賋譁Ꞅ⮱S\nࡣB/큃굪3Zɑ复o<\/;롋": null,
+ "彟h浠_|V4䦭Dᙣ♞u쿻=삮㍦\u001e哀鬌": [{"6횣楠,qʎꗇ鎆빙]㱭R굋鈌%栲j分僅ペ䇰w폦p蛃N溈ꡐꏀ?@(GI뉬$ﮄ9誁ꓚ2e甸ڋ[䁺,\u0011\u001cࢃ=\\+衪䷨ᯕ鬸K": [[
+ "ㅩ拏鈩勥\u000etgWVXs陂規p狵w퓼{뮵_i\u0002ퟑႢ⬐d6鋫F~챿搟\u0096䚼1ۼ칥0꣯儏=鋷牋ⅈꍞ龐",
+ -7283717290969427831,
+ true,
+ [
+ 4911644391234541055,
+ {
+ "I鈒첽P릜朸W徨觘-Hᎄ퐟⓺>8kr1{겵䍃〛ᬡ̨O귑o䝕'쿡鉕p5": "fv粖RN瞖蛐a?q꤄\u001d⸥}'ꣴ犿ꦼ?뤋?鵆쥴덋䡫s矷̄?ඣ/;괱絢oWfV<\/\u202cC,㖦0䑾%n賹g&T;|lj_欂N4w",
+ "짨䠗;䌕u i+r๏0": [{"9䥁\\8\"馇z䇔<\/ႡY3e狚쐡\"ุ6ﰆZ遖c\"Ll:ꮾ疣<\/᭙O◌납୕湞9⡳Und㫜\u0018^4pj1;䧐儂䗷ୗ>@e톬": {
+ "a⑂F鋻Q螰'<퇽Q贝瀧{ᘪ,cP&~䮃Z?gI彃": [
+ -1.69158726118025933E18,
+ [
+ "궂z簽㔛㮨瘥⤜䛖Gℤ逆Y⪾j08Sn昞ꘔ캻禀鴚P謦b{ꓮmN靐Mᥙ5\"睏2냑I\u0011.L&=?6ᄠ뻷X鸌t刑\"#z)on쳟줋",
+ null,
+ 7517598198523963704,
+ "ኑQp襟`uᩄr方]*F48ꔵn俺ሙ9뇒",
+ null,
+ null,
+ 6645782462773449868,
+ 1219168146640438184,
+ null,
+ {
+ ")ယ넌竀Sd䰾zq⫣⏌ʥ\u0010ΐ' |磪&p牢蔑mV蘸૰짬꺵;K": [
+ -7.539062290108008E-20,
+ [
+ true,
+ false,
+ null,
+ true,
+ 6574577753576444630,
+ [[
+ 1.2760162530699766E-19,
+ [
+ null,
+ [
+ "顊\\憎zXB,",
+ [{
+ "㇆{CVC9-MN㜋ઘR눽#{h@ퟨ!鼚XOvXS\u0017ᝣ=cS+梽៲綆16s덽휐y屬?ᇳG2ᴭ\u00054쫖y룇nKcW̭炦s/鰘ᬽ?J|퓀髣n勌\u0010홠P>j": false,
+ "箴": [
+ false,
+ "鍞j\"ꮾ*엇칬瘫xṬ⭽쩁䃳\"-⋵?ᦽ댎Ĝ": true,
+ "Pg帯佃籛n㔠⭹࠳뷏≻3㞱!-쒾!}쭪䃕!籿n涻J5ਲ਼yvy;Rኂ%ᔡጀ裃;M⣼)쵂쑈": 1.80447711803435366E18,
+ "ꈑC⡂ᑆ㤉壂뎃Xub<\/쀆༈憓ق쨐ק\\": [
+ 7706977185172797197,
+ {"": {"K╥踮砆NWࡆFy韣7ä밥{|紒︧䃀榫rᩛꦡTSy잺iH8}ퟴ,M?Ʂ勺ᴹ@T@~꾂=I㙕뾰_涀쑜嫴曣8IY?ҿo줫fऒ}\\S\"ᦨ뵼#nDX": {
+ "♘k6?癫d68?㽚乳䬳-V顷\u0005蝕?\u0018䞊V{邾zじl]雏k臤~ൖH뒐iꢥ]g?.G碄懺䔛pR$䅒X觨l봜A刊8R梒',}u邩퉕?;91Ea䈈믁G⊶芔h袪&廣㺄j;㡏綽\u001bN頸쳘橆": -2272208444812560733,
+ "拑Wﵚj鵼駳Oࣿ)#㾅顂N傓纝y僱栜'Bꐍ-!KF*ꭇK¦?䈴^:啤wG逭w᧯": "xᣱmYe1ۏ@霄F$ě꧘푫O䤕퀐Pq52憬ꀜ兴㑗ᡚ?L鷝ퟐ뭐zJꑙ}╆ᅨJB]\"袌㺲u8䯆f",
+ "꿽၅㔂긱Ǧ?SI": -1669030251960539193,
+ "쇝ɨ`!葎>瞺瘡驷錶❤ﻮ酜=": -6961311505642101651,
+ "?f7♄Jᡔ훮e읇퍾፣䭴KhखT;Qty}O\\|뫁IῒNe(5惁ꥶㆷY9ﮡ\\ oy⭖-䆩婁m#x봉>Y鈕E疣s驇↙ᙰm<": {"퉻:dꂁ&efᅫ쫢[\"돈늖꺙|Ô剐1͖-K:ʚ᭕/;쏖㷛]I痐职4gZ4⍜kเꛘZ⥺\\Bʫᇩ鄨魢弞&幟ᓮ2̊盜",
+ -9006004849098116748,
+ -3118404930403695681,
+ {
+ "_彃Y艘-\"Xx㤩㳷瑃?%2䐡鵛o귵옔夘v*탋职&㳈챗|O钧": [
+ false,
+ "daꧺdᗹ羞쯧H㍤鄳頳<型孒ン냆㹀f4㹰\u000f|C*ሟ鰠(O<ꨭ峹ipຠ*y೧4VQ蔔hV淬{?ᵌEfrI_",
+ "j;ꗣ밷邍副]ᗓ",
+ -4299029053086432759,
+ -5610837526958786727,
+ [
+ null,
+ [
+ -1.3958390678662759E-19,
+ {
+ "lh좈T_믝Y\"伨\u001cꔌG爔겕ꫳ晚踍⿻읐T䯎]~e#燇\"5hٔ嶰`泯r;ᗜ쮪Q):/t筑,榄&5懶뎫狝(": [{
+ "2ፁⓛ]r3C攟וּ9賵s⛔6'ஂ|\"ⵈ鶆䐹禝3\"痰ࢤ霏䵩옆䌀?栕r7O簂Isd?K`^讶}z8?z얰T:X倫⨎ꑹ": -6731128077618251511,
+ "|︦僰~m漿햭\\Y1'Vvخ굇ቍ챢c趖": [null]
+ }],
+ "虌魿閆5⛔煊뎰㞤ᗴꥰF䮥蘦䂪樳-K-(^\u20dd_": 2.11318679791770592E17
+ }
+ ]
+ ]
+ ]},
+ "묗E䀳㧯᳀逞GMc\b墹㓄끖Ơ&U??펌鑍 媋k))ᄊ": null,
+ "묥7콽벼諌J_DɯﮪM殴䣏,煚ྼ`Y:씧<\/⩫%yf䦀!1Ჶk춎Q米W∠WC跉鬽*ᛱi,l<崣炂骵*?8푐៣ⰵ憉⎑.,Nw罣q+ο컆弎": false
+ },
+ "e[|+lꑸ㝈TT?뿿|ꫛ9`㱯䊸楋-곳賨?쳁k棽擋wQ餈⟐Nq[q霩䵀뷮锅ꚢ": 5753148631596678144,
+ "sᓝ鴻߸d렶ὕ蜗ဟ툑!诉౿": false,
+ "|4䕳鵻?䈔(]틍/Ui#湻{듲ーMዀt7潔泄Ch⸨}쏣`螧銚㋼壯kⰥQ戵峉갑x辙'첛": "jd䘯$䕌茷!auw眶ㅥ䁣ꆢ民i",
+ "剖駰ꞫsM2]ᾴ2ࡷ祅拌Av狔'ꓗ킧ꣁ0酜✘O'": false,
+ "澩뢣ꀁeU~D\\ꮡ킠": "v^YC嚈ί\u0007죋h>㴕Lꀏ쓪\"_g鿄'#t⽙?,Wg㥖|D鑆e⥏쪸僬h鯔咼ඡ;4TK聎졠嫞"
+ }
+ ]
+ ]
+ }
+ ]
+ ]
+ ]}}
+ }
+ ]}
+ },
+ "뿋뀾淣截䔲踀&XJ펖꙯^Xb訅ꫥgᬐ>棟S\"혧騾밫겁7-": "擹8C憎W\"쵮yR뢩浗絆䠣簿9䏈引Wcy䤶孖ꯥ;퐌]輩䍐3@{叝 뽸0ᡈ쵡Ⲇ\u001dL匁꧐2F~ݕ㪂@W^靽L襒ᦘ~沦zZ棸!꒲栬R"
+ }
+ ]
+ ],
+ "Z:덃൛5Iz찇䅄駠㭧蓡K1": "e8᧤좱U%?ⵇ䯿鿝\u0013縮R∱骒EO\u000fg?幤@֗퉙vU`",
+ "䐃쪈埽້=Ij,쭗쓇చ": false
+ }]}}
+ ]
+ }
+ ]}
+ }
+ ]
+ ]
+ ],
+ "咰긖VM]6䓑쇎琺etDҌ?㞏ꩄ퇫밉gj8蠃\"⩐5䛹1ࣚ㵪": "ക蹊?⎲⧘⾚̀I#\"䈈⦞돷`wo窭戕휾䃼)앷嵃꾞稧,Ⴆ윧9S?EMk3Მ3+e{⹔Te驨7䵒?타Ulg悳o43"
+ }
+ ],
+ "zQᤚ纂땺6#ٽv#ࠫ휊冟蹧텈ꃊʆ?&a䥯De潝|쿓pt瓞㭻啹^盚2Ꝋf醪,얏T窧\\Di䕎谄nn父ꋊE": -2914269627845628872,
+ "䉩跐|㨻ᷢ㝉B{蓧瞸`I!℄욃힕#ೲᙾ竛ᔺCjk췒늕貭词\u0017署?W딚%(pꍁ⤼띳^=on뺲l䆼bzrﳨ[&j狸䠠=ᜑꦦ\u2061յnj=牲攑)M\\龏": false,
+ "뎕y絬⥮Ϙᯑ㌔/NF*˓.,QEzvK!Iwz?|쥾\"ꩻL꼗Bꔧ賴緜s뉣隤茛>ロ?(?^`>冺飒=噸泥⺭婓鎔븜z^坷裮êⓅ໗jM7ﶕ找\\O": 1.376745434746303E-19
+ },
+ "䐛r滖w㏤,|Nዜ": false
+ }
+ ]],
+ "@꿙?薕尬 gd晆(띄5躕ﻫS蔺4)떒錸瓍?~": 1665108992286702624,
+ "w믍nᏠ=`ᅥC>'從됐槷䤝眷螄㎻揰扰XᅧC贽uჍ낟jKD03T!lDV쀉Ӊy뢖,袛!终캨G?鉮Q)1쾅庅O4ꁉH7?d\u0010蠈줘월ސ粯Q!낇껉6텝|{": null,
+ "~˷jg쿤촖쉯y": -5.5527605669177098E18,
+ "펅Wᶺzꐆと푭e?4j仪열[D<鈑皶婆䵽ehS?袪;HꍨM뗎ば[(嗏M3q퍟g4y╸鰧茀[Bi盤~唎鋆彺⦊q?B4쉓癚O洙킋툈䶯_?ퟲ": null
+ }
+ ]
+ ]]
+ ]],
+ "Ԕ㍤7曁聯ಃ錐V䷰?v㪃૦~K\"$%请|ꇹn\"k䫛㏨鲨\u2023䄢\u0004[︊VJ?䶟ាꮈ䗱=깘U빩": -4863152493797013264
+ }
+ ]}]}
+ ]
+ }}}
+ ],
+ "쏷쐲۹퉃~aE唙a챑,9㮹gLHd'䔏|킗㍞䎥&KZYT맵7䥺Nⱳ同莞鿧w\\༌疣n/+ꎥU\"封랾○ퟙAJᭌ?9䛝$?驔9讐짘魡T֯c藳`虉C읇쐦T"
+ }
+ ],
+ "谶개gTR>ၵ͚dt晑䉇陏滺}9㉸P漄": -3350307268584339381
+ }]
+ ]
+ ]
+ ]]
+ ]
+ ],
+ "0y馋X뱔瑇:䌚廿jg-懲鸭䷭垤㒬茭u賚찶ಽ+\\mT땱\u20821殑㐄J쩩䭛ꬿNS潔*d\\X,壠뒦e殟%LxG9:摸": 3737064585881894882,
+ "풵O^-⧧ⅶvѪ8廸鉵㈉ר↝Q㿴뺟EႳvNM:磇>w/唎뷭!냹D䯙i뵱貁C#⼉NH6`柴ʗ#\\!2䂗Ⱨf?諳.P덈-返I6?8ꐘ": -8934657287877777844,
+ "溎-蘍寃i诖ര\"汵\"\ftl,?d⼡쾪⺋h匱[,෩I8MҧF{k瓿PA'橸ꩯ綷퉲翓": null
+ }
+ ]
+ ],
+ "ោ係<元": 1.7926963090826924E-18
+ }}]
+ }
+ ]
+ ]]}]
+ }]
+ ]
+ ]
+ ]
+ ],
+ "ጩV<\"ڸsOᤘ": 2.0527167903723048E-19
+ }]
+ ]}
+ ]
+ ]],
+ "∳㙰3젴p᧗䱙?`yZA8Ez0,^ᙛ4_0븢\u001ft:~䎼s.bb룦明yNP8弆C偯;⪾짍'蕴뮛": -6976654157771105701,
+ "큵ꦀ\\㇑:nv+뒤燻䀪ﴣ9ᚈK㚊誦撪䚛,ꮪxሲ쳊\u0005HSf?asg昱dqꬌVꙇ㼺'k*'㈈": -5.937042203633044E-20
+ }
+ ]
+ }],
+ "?}\u20e0],s嶳菋@#2u쒴sQS䩗=ꥮ;烌,|ꘔ䘆": "ᅩ영N璠kZ먕眻?2ቲ芋眑D륟渂⸑ﴃIRE]啗`K'"
+ }},
+ "쨀jmV賂ﰊ姐䂦玞㬙ᏪMՎ씜~`uOn*ॠ8\u000ef6??\\@/?9見d筜ﳋB|S䝬葫㽁o": true
+ },
+ "즛ꄤ酳艚␂㺘봿㎨iGࡿ?1\"䘓您\u001fSኝ⺿溏zៀ뻤B\u0019?윐a䳵᭱䉺膷d:<\/": 3935553551038864272
+ }
+ ]
+ ]}
+ ]]
+ ]]
+ ]}
+ }
+ ]
+ }
+ ]]}},
+ "3h↛!ꋰy\"攜(ெl䪕oUkc1A㘞ᡲ촾ᣫ<\/䒌E㛝潨i{v?W౾H\\RჅpz蝬R脾;v:碽✘↯삞鷱o㸧瑠jcmK7㶧뾥찲n": true,
+ "ⶸ?x䊺⬝-䰅≁!e쩆2ꎿ准G踌XXᩯ1߁}0?.헀Z馟;稄\baDꟹ{-寪⚈ꉷ鮸_L7ƽᾚ<\u001bጨA䧆송뇵⨔\\礍뗔d设룱㶉cq{HyぱR㥽吢ſtp": -7985372423148569301,
+ "緫#콮IB6<\/=5Eh礹\t8럭@饹韠r㰛斣$甝LV췐a갵'请o0g:^": "䔨(.",
+ "띳℡圤pンĝ倧訜B쁟G䙔\"Sb⓮;$$▏S1J뢙SF|赡g*\"Vu䲌y": "䪈&틐),\\kT鬜1풥;뷴'Zေ䩹@J鞽NぼM?坥eWb6榀ƩZڮ淽⺞삳煳xჿ絯8eⶍ羷V}ჿ쎱䄫R뱃9Z>'\u20f1ⓕ䏜齮"
+ }
+ ]
+ ]]]
+ }}
+ }
+ ]
+ ]},
+ "펮b.h粔폯2npX詫g錰鷇㇒<쐙S値bBi@?镬矉`剔}c2壧ଭfhY깨R()痩⺃a\\⍔?M&ﯟ<劜꺄멊ᄟA\"_=": null
+ },
+ "~潹Rqn榢㆓aR鬨侅?䜑亡V_翅㭔(䓷w劸ၳDp䀅<\/ﰎ鶊m䵱팱긽ꆘ