From ebece08923c9400d104a9b2e1f4a42e0193c657f Mon Sep 17 00:00:00 2001 From: Young-zhiqiang Date: Tue, 5 Dec 2023 09:40:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=89=E6=96=B9=E5=BA=93jszip=E9=80=82?= =?UTF-8?q?=E9=85=8Dohpm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Young-zhiqiang --- OAT.xml | 6 + ohos-jszip/.gitignore | 7 + ohos-jszip/AppScope/app.json5 | 10 + .../resources/base/element/string.json | 8 + .../resources/base/media/app_icon.png | Bin 0 -> 6790 bytes ohos-jszip/CHANGELOG.md | 4 + ohos-jszip/LICENSE | 651 + ohos-jszip/NOTICE | 666 + ohos-jszip/OAT.xml | 57 + ohos-jszip/README.OpenSource | 12 + ohos-jszip/README.md | 105 + ohos-jszip/build-profile.json5 | 32 + ohos-jszip/entry/.gitignore | 6 + ohos-jszip/entry/build-profile.json5 | 13 + ohos-jszip/entry/hvigorfile.ts | 16 + ohos-jszip/entry/oh-package.json5 | 12 + .../main/ets/components/CreateDirOrFile.ets | 104 + .../src/main/ets/entryability/EntryAbility.ts | 55 + ohos-jszip/entry/src/main/ets/pages/Index.ets | 306 + ohos-jszip/entry/src/main/ets/types/type.ets | 39 + .../entry/src/main/ets/utils/FileSaver.ets | 38 + ohos-jszip/entry/src/main/ets/utils/log.ts | 21 + ohos-jszip/entry/src/main/module.json5 | 37 + .../main/resources/base/element/color.json | 8 + .../main/resources/base/element/string.json | 16 + .../src/main/resources/base/media/icon.png | Bin 0 -> 6790 bytes .../resources/base/profile/main_pages.json | 5 + .../main/resources/en_US/element/string.json | 16 + .../src/main/resources/rawfile/source.zip | Bin 0 -> 163944 bytes .../main/resources/zh_CN/element/string.json | 16 + .../src/ohosTest/ets/test/Ability.test.ets | 31 + .../entry/src/ohosTest/ets/test/List.test.ets | 27 + .../ohosTest/ets/test/constructor.test.ets | 34 + .../entry/src/ohosTest/ets/test/file.test.ets | 299 + .../src/ohosTest/ets/test/filter.test.ets | 69 + .../src/ohosTest/ets/test/forEach.test.ets | 59 + .../ohosTest/ets/testability/TestAbility.ets | 62 + .../ohosTest/ets/testability/pages/Index.ets | 48 + .../ets/testrunner/OpenHarmonyTestRunner.ts | 63 + ohos-jszip/entry/src/ohosTest/module.json5 | 37 + .../resources/base/element/color.json | 8 + .../resources/base/element/string.json | 16 + .../ohosTest/resources/base/media/icon.png | Bin 0 -> 6790 bytes .../resources/base/profile/test_pages.json | 5 + ohos-jszip/hvigor/hvigor-config.json5 | 6 + ohos-jszip/hvigor/hvigor-wrapper.js | 2 + ohos-jszip/hvigorfile.ts | 16 + ohos-jszip/hvigorw | 48 + ohos-jszip/hvigorw.bat | 64 + ohos-jszip/library/.gitignore | 8 + ohos-jszip/library/Index.js | 15 + ohos-jszip/library/build-profile.json5 | 28 + ohos-jszip/library/consumer-rules.txt | 0 ohos-jszip/library/hvigorfile.ts | 20 + ohos-jszip/library/obfuscation-rules.txt | 18 + ohos-jszip/library/oh-package.json5 | 27 + ohos-jszip/library/package.json | 23 + ohos-jszip/library/rollup.config.js | 53 + .../src/main/core/jszip-master/lib/aes.js | 141 + .../src/main/core/jszip-master/lib/base64.js | 106 + .../core/jszip-master/lib/compressedObject.js | 99 + .../core/jszip-master/lib/compressions.js | 14 + .../src/main/core/jszip-master/lib/crc32.js | 77 + .../main/core/jszip-master/lib/defaults.js | 11 + .../main/core/jszip-master/lib/external.js | 18 + .../src/main/core/jszip-master/lib/flate.js | 85 + .../lib/generate/ZipFileWorker.js | 559 + .../core/jszip-master/lib/generate/index.js | 70 + .../src/main/core/jszip-master/lib/index.js | 55 + .../core/jszip-master/lib/license_header.js | 11 + .../src/main/core/jszip-master/lib/load.js | 93 + .../lib/nodejs/NodejsStreamInputAdapter.js | 74 + .../lib/nodejs/NodejsStreamOutputAdapter.js | 42 + .../main/core/jszip-master/lib/nodejsUtils.js | 57 + .../src/main/core/jszip-master/lib/object.js | 386 + .../lib/readable-stream-browser.js | 10 + .../jszip-master/lib/reader/ArrayReader.js | 57 + .../jszip-master/lib/reader/DataReader.js | 116 + .../lib/reader/NodeBufferReader.js | 19 + .../jszip-master/lib/reader/StringReader.js | 38 + .../lib/reader/Uint8ArrayReader.js | 22 + .../core/jszip-master/lib/reader/readerFor.js | 28 + .../main/core/jszip-master/lib/signature.js | 7 + .../src/main/core/jszip-master/lib/sjcl.js | 1056 ++ .../jszip-master/lib/stream/ConvertWorker.js | 26 + .../jszip-master/lib/stream/Crc32Probe.js | 24 + .../lib/stream/DataLengthProbe.js | 29 + .../jszip-master/lib/stream/DataWorker.js | 116 + .../jszip-master/lib/stream/GenericWorker.js | 263 + .../jszip-master/lib/stream/StreamHelper.js | 214 + .../src/main/core/jszip-master/lib/support.js | 38 + .../src/main/core/jszip-master/lib/utf8.js | 275 + .../src/main/core/jszip-master/lib/utils.js | 501 + .../main/core/jszip-master/lib/zipEntries.js | 263 + .../main/core/jszip-master/lib/zipEntry.js | 329 + .../main/core/jszip-master/lib/zipObject.js | 153 + ohos-jszip/library/src/main/dist/dist.js | 15349 ++++++++++++++++ ohos-jszip/library/src/main/module.json5 | 10 + .../main/resources/base/element/string.json | 8 + .../main/resources/en_US/element/string.json | 8 + .../main/resources/zh_CN/element/string.json | 8 + ohos-jszip/library/src/main/type/index.d.ts | 332 + ohos-jszip/library/src/test/List.test.ets | 19 + .../library/src/test/LocalUnit.test.ets | 47 + ohos-jszip/oh-package.json5 | 13 + 105 files changed, 24628 insertions(+) create mode 100644 ohos-jszip/.gitignore create mode 100644 ohos-jszip/AppScope/app.json5 create mode 100644 ohos-jszip/AppScope/resources/base/element/string.json create mode 100644 ohos-jszip/AppScope/resources/base/media/app_icon.png create mode 100644 ohos-jszip/CHANGELOG.md create mode 100644 ohos-jszip/LICENSE create mode 100644 ohos-jszip/NOTICE create mode 100644 ohos-jszip/OAT.xml create mode 100644 ohos-jszip/README.OpenSource create mode 100644 ohos-jszip/README.md create mode 100644 ohos-jszip/build-profile.json5 create mode 100644 ohos-jszip/entry/.gitignore create mode 100644 ohos-jszip/entry/build-profile.json5 create mode 100644 ohos-jszip/entry/hvigorfile.ts create mode 100644 ohos-jszip/entry/oh-package.json5 create mode 100644 ohos-jszip/entry/src/main/ets/components/CreateDirOrFile.ets create mode 100644 ohos-jszip/entry/src/main/ets/entryability/EntryAbility.ts create mode 100644 ohos-jszip/entry/src/main/ets/pages/Index.ets create mode 100644 ohos-jszip/entry/src/main/ets/types/type.ets create mode 100644 ohos-jszip/entry/src/main/ets/utils/FileSaver.ets create mode 100644 ohos-jszip/entry/src/main/ets/utils/log.ts create mode 100644 ohos-jszip/entry/src/main/module.json5 create mode 100644 ohos-jszip/entry/src/main/resources/base/element/color.json create mode 100644 ohos-jszip/entry/src/main/resources/base/element/string.json create mode 100644 ohos-jszip/entry/src/main/resources/base/media/icon.png create mode 100644 ohos-jszip/entry/src/main/resources/base/profile/main_pages.json create mode 100644 ohos-jszip/entry/src/main/resources/en_US/element/string.json create mode 100644 ohos-jszip/entry/src/main/resources/rawfile/source.zip create mode 100644 ohos-jszip/entry/src/main/resources/zh_CN/element/string.json create mode 100644 ohos-jszip/entry/src/ohosTest/ets/test/Ability.test.ets create mode 100644 ohos-jszip/entry/src/ohosTest/ets/test/List.test.ets create mode 100644 ohos-jszip/entry/src/ohosTest/ets/test/constructor.test.ets create mode 100644 ohos-jszip/entry/src/ohosTest/ets/test/file.test.ets create mode 100644 ohos-jszip/entry/src/ohosTest/ets/test/filter.test.ets create mode 100644 ohos-jszip/entry/src/ohosTest/ets/test/forEach.test.ets create mode 100644 ohos-jszip/entry/src/ohosTest/ets/testability/TestAbility.ets create mode 100644 ohos-jszip/entry/src/ohosTest/ets/testability/pages/Index.ets create mode 100644 ohos-jszip/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts create mode 100644 ohos-jszip/entry/src/ohosTest/module.json5 create mode 100644 ohos-jszip/entry/src/ohosTest/resources/base/element/color.json create mode 100644 ohos-jszip/entry/src/ohosTest/resources/base/element/string.json create mode 100644 ohos-jszip/entry/src/ohosTest/resources/base/media/icon.png create mode 100644 ohos-jszip/entry/src/ohosTest/resources/base/profile/test_pages.json create mode 100644 ohos-jszip/hvigor/hvigor-config.json5 create mode 100644 ohos-jszip/hvigor/hvigor-wrapper.js create mode 100644 ohos-jszip/hvigorfile.ts create mode 100644 ohos-jszip/hvigorw create mode 100644 ohos-jszip/hvigorw.bat create mode 100644 ohos-jszip/library/.gitignore create mode 100644 ohos-jszip/library/Index.js create mode 100644 ohos-jszip/library/build-profile.json5 create mode 100644 ohos-jszip/library/consumer-rules.txt create mode 100644 ohos-jszip/library/hvigorfile.ts create mode 100644 ohos-jszip/library/obfuscation-rules.txt create mode 100644 ohos-jszip/library/oh-package.json5 create mode 100644 ohos-jszip/library/package.json create mode 100644 ohos-jszip/library/rollup.config.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/aes.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/base64.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/compressedObject.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/compressions.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/crc32.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/defaults.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/external.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/flate.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/generate/ZipFileWorker.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/generate/index.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/index.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/license_header.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/load.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/nodejs/NodejsStreamInputAdapter.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/nodejs/NodejsStreamOutputAdapter.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/nodejsUtils.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/object.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/readable-stream-browser.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/reader/ArrayReader.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/reader/DataReader.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/reader/NodeBufferReader.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/reader/StringReader.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/reader/Uint8ArrayReader.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/reader/readerFor.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/signature.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/sjcl.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/stream/ConvertWorker.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/stream/Crc32Probe.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/stream/DataLengthProbe.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/stream/DataWorker.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/stream/GenericWorker.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/stream/StreamHelper.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/support.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/utf8.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/utils.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/zipEntries.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/zipEntry.js create mode 100644 ohos-jszip/library/src/main/core/jszip-master/lib/zipObject.js create mode 100644 ohos-jszip/library/src/main/dist/dist.js create mode 100644 ohos-jszip/library/src/main/module.json5 create mode 100644 ohos-jszip/library/src/main/resources/base/element/string.json create mode 100644 ohos-jszip/library/src/main/resources/en_US/element/string.json create mode 100644 ohos-jszip/library/src/main/resources/zh_CN/element/string.json create mode 100644 ohos-jszip/library/src/main/type/index.d.ts create mode 100644 ohos-jszip/library/src/test/List.test.ets create mode 100644 ohos-jszip/library/src/test/LocalUnit.test.ets create mode 100644 ohos-jszip/oh-package.json5 diff --git a/OAT.xml b/OAT.xml index 9b53b532..0a8a9091 100644 --- a/OAT.xml +++ b/OAT.xml @@ -22,6 +22,8 @@ + + @@ -48,12 +50,15 @@ + + + @@ -101,6 +106,7 @@ + diff --git a/ohos-jszip/.gitignore b/ohos-jszip/.gitignore new file mode 100644 index 00000000..1882c54c --- /dev/null +++ b/ohos-jszip/.gitignore @@ -0,0 +1,7 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +/oh-package-lock.json5 diff --git a/ohos-jszip/AppScope/app.json5 b/ohos-jszip/AppScope/app.json5 new file mode 100644 index 00000000..f62c4415 --- /dev/null +++ b/ohos-jszip/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.jszip", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos-jszip/AppScope/resources/base/element/string.json b/ohos-jszip/AppScope/resources/base/element/string.json new file mode 100644 index 00000000..1080233f --- /dev/null +++ b/ohos-jszip/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "MyApplication" + } + ] +} diff --git a/ohos-jszip/AppScope/resources/base/media/app_icon.png b/ohos-jszip/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c GIT binary patch literal 6790 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 + 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 diff --git a/ohos-jszip/NOTICE b/ohos-jszip/NOTICE new file mode 100644 index 00000000..b75d63a3 --- /dev/null +++ b/ohos-jszip/NOTICE @@ -0,0 +1,666 @@ +OPEN SOURCE SOFTWARE NOTICE + +Please note we provide an open source software notice for the third party open source software along with this software and/or this software component (in the following just “this SOFTWARE”). The open source software licenses are granted by the respective right holders. + +Warranty Disclaimer +THE OPEN SOURCE SOFTWARE IN THIS PRODUCT 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 APPLICABLE LICENSES FOR MORE DETAILS. + +Copyright Notice and License Texts + +---------------------------------------------------------------------- +Software: jszip 3.5.0 + +Copyright notice: +JSZip is dual licensed. At your choice you may use it under the MIT license *or* the GPLv3 +license. + +License: The MIT License (MIT) + +The MIT License +=============== + +Copyright (c) 2009-2016 Stuart Knightley, David Duponchel, Franz Buchinger, António Afonso + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +GPL version 3 +============= + + 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 diff --git a/ohos-jszip/OAT.xml b/ohos-jszip/OAT.xml new file mode 100644 index 00000000..e87e0034 --- /dev/null +++ b/ohos-jszip/OAT.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ohos-jszip/README.OpenSource b/ohos-jszip/README.OpenSource new file mode 100644 index 00000000..e2d37099 --- /dev/null +++ b/ohos-jszip/README.OpenSource @@ -0,0 +1,12 @@ +[ + + { + "Name": "jszip", + "License": "MIT OR GPL-3.0", + "License File": "LICENSE", + "Version Number": "3.5.0", + "Owner" : "xiafeng@huawei.com" + "Upstream URL": "https://github.com/xqdoo00o/jszip", + "Description": "A library for creating, reading and editing .zip files with JavaScript, with a lovely and simple API." + }; +] \ No newline at end of file diff --git a/ohos-jszip/README.md b/ohos-jszip/README.md new file mode 100644 index 00000000..4b5fecbd --- /dev/null +++ b/ohos-jszip/README.md @@ -0,0 +1,105 @@ +# jszip + +## 简介 + +[jszip](https://github.com/xqdoo00o/jszip) ,是一个支持创建、编辑以及生成压缩文件的工具库。本库基于[jszip](https://github.com/xqdoo00o/jszip) 原库 v3.5.0 版本进行适配,使其可以运行在 OpenHarmony,并沿用其现有用法和特性。 + +## 下载安装 + +```javascript +ohpm install @ohos/jszip +``` + +OpenHarmony ohpm 环境配置等更多内容,请参考[如何安装 OpenHarmony ohpm 包](https://gitee.com/openharmony-tpc/docs/blob/master/OpenHarmony_har_usage.md) + +## 接口和属性列表 + +接口列表 + +| **接口** | 参数 | 功能 | +| ------------------------------------------------ | ------------------------------------------------------------------------ | ---------------- | +| file | (path,data[, options]) | 创建文件 | +| folder | (name) | 创建文件夹 | +| forEach | (callback:(relativePath,file) => void) | 遍历目录及文件 | +| filter | (predicate:(relativePath,file) => boolean) | 支持过滤目录/文件 | +| remove | (path) | 移除目录或者文件 | +| generateAsync | (options,onUpdate) | 异步生成压缩文件,支持设置密码 | +| loadAsync | (data,options) | 异步加载压缩文件 | + + + +## 使用示例 +创建zip实例 +```javascript +import JSZip from "@ohos/jszip"; + +const jszip = new JSZip(); +``` + +创建文件 + +```javascript +jszip.file("xxx.txt","这是一段文本"); +``` + +创建文件夹 + +```javascript +jszip.folder("xxx"); +``` + +指定目录下创建文件或文件夹 +```javascript +const folder = jszip.folder("xxx"); + +folder.folder("xxx"); +folder.file("xxx.txt","这是一段文本"); +``` + + +异步生成压缩文件 +```javascript +jszip.generateAsync({ type: "arraybuffer"}) +``` +异步生成加密压缩文件 +```javascript +jszip.generateAsync({ type: "arraybuffer", password: "1234", encryptStrength: 3 }) +``` + +异步加载压缩文件 +```javascript +jszip.loadAsync(data) +``` + + +## 约束与限制 + +在下述版本验证通过: +DevEco Studio: 4.1.3.313, SDK: API11(4.1.2.1) + +## 目录结构 + +```javascript +|---- jszip +| |---- AppScrope # 示例代码文件夹 +| |---- entry # 示例代码文件夹 +| |---- jszip # jszip库文件夹 +| |---- src # 模块代码 +| |---- core # jszip核心代码 +| |---- dist # 打包脚本生成代码 +| |---- type # 类型声明文件 +| |---- index.ets # 入口文件 +| |---- *.json5 # 配置文件 +| |---- rollup.config.js # rollup配置文件 +| |---- README.md # 安装使用方法 +| |---- README.OpenSource # 开源说明 +| |---- CHANGELOG.md # 更新日志 +``` + +## 开源协议 + +本项目基于 [Apache License 2.0](https://gitee.com/openharmony-tpc/openharmony_tpc_samples/blob/master/jszipDemo/LICENSE ) ,请自由地享受和参与开源。 + +## 贡献代码 + +使用过程中发现任何问题都可以提 [Issue](https://gitee.com/openharmony-tpc/openharmony_tpc_samples/issues ) 给我们,当然,我们也非常欢迎你给我们发 [PR](https://gitee.com/openharmony-tpc/openharmony_tpc_samples/pulls ) 。 diff --git a/ohos-jszip/build-profile.json5 b/ohos-jszip/build-profile.json5 new file mode 100644 index 00000000..cbc7f4f6 --- /dev/null +++ b/ohos-jszip/build-profile.json5 @@ -0,0 +1,32 @@ +{ + "app": { + "signingConfigs": [ + ], + "products": [ + { + "compileSdkVersion": 10, + "compatibleSdkVersion": 10, + "name": "default", + "signingConfig": "default", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + }, + { + "name": "library", + "srcPath": "./library" + } + ] +} \ No newline at end of file diff --git a/ohos-jszip/entry/.gitignore b/ohos-jszip/entry/.gitignore new file mode 100644 index 00000000..e2713a27 --- /dev/null +++ b/ohos-jszip/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos-jszip/entry/build-profile.json5 b/ohos-jszip/entry/build-profile.json5 new file mode 100644 index 00000000..7dc37bb9 --- /dev/null +++ b/ohos-jszip/entry/build-profile.json5 @@ -0,0 +1,13 @@ +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos-jszip/entry/hvigorfile.ts b/ohos-jszip/entry/hvigorfile.ts new file mode 100644 index 00000000..d803af2f --- /dev/null +++ b/ohos-jszip/entry/hvigorfile.ts @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos-jszip/entry/oh-package.json5 b/ohos-jszip/entry/oh-package.json5 new file mode 100644 index 00000000..b3edc13e --- /dev/null +++ b/ohos-jszip/entry/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/jszip": "file:../library" + } +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/main/ets/components/CreateDirOrFile.ets b/ohos-jszip/entry/src/main/ets/components/CreateDirOrFile.ets new file mode 100644 index 00000000..8121e7e1 --- /dev/null +++ b/ohos-jszip/entry/src/main/ets/components/CreateDirOrFile.ets @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Confirm, Cancel, ReturnValue } from "../types/type" + +@CustomDialog +export struct CreateDirOrFile { + create_type: "DIR" | "FILE" | "ZIP" = "DIR"; + controller?: CustomDialogController; + folderName: string = ""; + fileName: string = ""; + contentText: string = ""; + zipName:string = ""; + textController: TextInputController = new TextInputController() + confirm: Confirm = () => { + } + cancel: Cancel = () => { + } + + + isShowDir(){ + return this.create_type === "DIR" + } + + isShowFile(){ + return this.create_type === "FILE" + } + + isShowZip(){ + return this.create_type === "ZIP" + } + + + build() { + Column() { + Text(this.create_type === "DIR" ? "创建文件夹" : this.create_type === "FILE"?"创建文件":"加载ZIP文件").fontSize(20).margin({ top: 10, bottom: 10 }) + TextInput({ placeholder: '请输入文件夹名称...', text: this.folderName,controller:this.textController }) + .height(80) + .width('90%') + .onChange((value: string) => { + this.folderName = value + }) + .margin({ bottom: 12 }) + .visibility(this.isShowDir()?Visibility.Visible:Visibility.None) + + + TextInput({ placeholder: '请输入文件名称...', text: this.fileName }) + .height(80) + .width('90%') + .onChange((value: string) => { + this.fileName = value + }) + .margin({ bottom: 12 }) + .visibility(this.isShowFile()?Visibility.Visible:Visibility.None) + + + + TextInput({ placeholder: '请输入文件内容...', text: this.contentText }) + .height(80) + .width('90%') + .onChange((value: string) => { + this.contentText = value + }) + .margin({ bottom: 12 }) + .visibility(this.isShowFile()?Visibility.Visible:Visibility.None) + + TextInput({ placeholder: '请输入ZIP文件名称...', text: this.zipName }) + .height(80) + .width('90%') + .onChange((value: string) => { + this.zipName = value + }) + .margin({ bottom: 12 }) + .visibility(this.isShowZip()?Visibility.Visible:Visibility.None) + + + Column() { + Button("确定").onClick(() => { + const result = new ReturnValue(); + result.create_type = this.create_type; + result.folderName = this.folderName; + result.fileName = this.fileName; + result.contentText = this.contentText; + result.zipName = this.zipName; + this.confirm(result); + }).width("100%").margin({bottom:8}).height(50) + Button("取消").onClick(this.cancel).width("100%").height(50) + }.margin(20) + } + + + } +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/main/ets/entryability/EntryAbility.ts b/ohos-jszip/entry/src/main/ets/entryability/EntryAbility.ts new file mode 100644 index 00000000..90d23b58 --- /dev/null +++ b/ohos-jszip/entry/src/main/ets/entryability/EntryAbility.ts @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import UIAbility from '@ohos.app.ability.UIAbility'; +import hilog from '@ohos.hilog'; +import window from '@ohos.window'; + +export default class EntryAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground() { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground() { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/ohos-jszip/entry/src/main/ets/pages/Index.ets b/ohos-jszip/entry/src/main/ets/pages/Index.ets new file mode 100644 index 00000000..bb3a37a6 --- /dev/null +++ b/ohos-jszip/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import JSZip, { JSZipObject } from "@ohos/jszip"; +import { BuildButtonOptions, Files, ReturnValue } from '../types/type'; +import promptAction from '@ohos.promptAction'; +import { writeCacheDirFile, loadAsyncFromRawFile } from "../utils/FileSaver"; +import { log } from "../utils/log"; +import { CreateDirOrFile } from "../components/CreateDirOrFile"; + +@Entry +@Component +struct Index { + @State instance: JSZip = new JSZip(); + @State directory: Array = []; + @State currentInstance: JSZip | null = null; + @State index: number = 0; + @State create_type: "DIR" | "FILE" | "ZIP" = "DIR"; + @State currentFolder: string = ""; + @State password: string | null = null; + @State isLoading:boolean = false; + dialogController: CustomDialogController = new CustomDialogController({ + builder: CreateDirOrFile({ + create_type: this.create_type, + confirm: (data): void => this.onConfirm(data), + cancel: ():void => this.onCancel() + }), + autoCancel: true, + }) + + @Builder + BuildButton(text: string, callback?: () => void, options: BuildButtonOptions = { + bgColor: Color.Blue, + color: Color.White, + borderOptions: {} + }) { + Button(text) + .fontSize(14) + .fontColor(options.color) + .backgroundColor(options.bgColor) + .border(options.borderOptions) + .onClick(callback) + .margin({ bottom: 8 }) + } + + @Builder + BuildDirOrFile(item: JSZipObject) { + if (this.isDir(item)) { + + Flex({ justifyContent: FlexAlign.SpaceAround }) { + Text(item.name) + .fontSize(22) + .padding(8) + .width("100%") + .border({ width: { bottom: 1 }, color: "#ff6700" }) + .onClick(() => { + this.currentFolder = item.name; + }) + Button("删除").onClick(() => { + this.removeDirOrFile(item.name); + }) + } + } else { + Flex({ justifyContent: FlexAlign.SpaceAround }) { + Text(item.name).fontSize(20).padding(4).width("100%").fontColor(Color.Grey) + Button("删除").onClick(() => { + this.removeDirOrFile(item.name); + }) + } + } + } + + createDir() { + this.create_type = "DIR"; + this.openDialog(); + } + + createFile() { + this.create_type = "FILE"; + this.openDialog(); + } + + removeDirOrFile(path: string) { + this.instance.remove(path); + this.refresh(); + promptAction.showToast({ message: `删除成功` }); + + } + + openDialog() { + this.dialogController.open() + } + + closeDialog() { + this.dialogController?.close(); + } + + openLoading(){ + this.isLoading = true; + } + closeLoading(){ + this.isLoading = false; + } + + + onConfirm(data: ReturnValue) { + const type = data.create_type; + if (type === 'DIR') { + if (!data.folderName) { + promptAction.showToast({ message: `创建失败,请输入正确的文件夹名称!` }); + return + } + const folderName = this.currentFolder + data.folderName; + folderName && this.instance.folder(folderName); + promptAction.showToast({ message: `文件夹创建成功!` }); + this.refresh(); + this.dialogController?.close(); + } else if (type === "FILE") { + if (!data.fileName || !data.contentText) { + promptAction.showToast({ message: `创建失败,请输入正确的文件名称以及内容!` }); + return + } + const fileName = this.currentFolder + data.fileName; + const content = data.contentText; + fileName && content && this.instance.file(fileName, content); + promptAction.showToast({ message: `文件创建成功!` }); + this.refresh(); + this.dialogController?.close(); + } else if (type === "ZIP") { + const zipName = data.zipName; + if(!zipName) { + promptAction.showToast({ message: `文件名称不能为空` }); + return; + } + loadAsyncFromRawFile(zipName).then(res => { + if(!res) { + promptAction.showToast({ message: `没有找到此压缩文件!` }); + + // this.closeLoading(); + return; + } + this.closeDialog(); + + this.openLoading(); + + this.instance.loadAsync(res).then(() => { + this.refresh(); + promptAction.showToast({ message: "解压缩文件成功!" }); + this.closeLoading(); + + + }).catch((err: Error) => { + promptAction.showToast({ message: "解压缩文件失败! 错误原因:" + err.message }) + log(err.message) + this.closeLoading(); + this.closeDialog(); + + + }); + }); + } + + + } + + onCancel() { + this.dialogController?.close(); + } + + forEachZIP() { + this.instance.forEach((_, file) => { + log(file) + }) + } + + filterZIP() { + const zips = this.instance.filter((_, file) => (file.dir === false)); + log(zips); + } + + generateZIP() { + this.openLoading(); + this.instance.generateAsync({ type: "arraybuffer", password: this.password, encryptStrength: 3 }).then(res => { + writeCacheDirFile(`prod-${Date.now()}.zip`, res); + this.closeLoading(); + }) + .catch((err: object) => { + this.closeLoading(); + promptAction.showToast({ message: `生成压缩文件失败!` }); + + log(`生成压缩文件失败 ${err}`) + }) + } + + loadAsyncFile() { + this.create_type = "ZIP"; + this.openDialog(); + } + + refresh() { + this.directory = this.format(this.instance.files); + } + + isDir(item: JSZipObject): boolean { + return item.dir; + } + + format(files: Files): Array { + return Object.keys(files).map(v => (files[v])) + } + + /** + * 调试日志 + */ + debugger = () => { + log(this.instance.files); + log(this.directory) + } + + build() { + Scroll() { + Column() { + + Flex({ justifyContent: FlexAlign.SpaceBetween, wrap: FlexWrap.Wrap }) { + Row({ space: 8 }) { + this.BuildButton("+新建文件夹", (): void => this.createDir()) + this.BuildButton("+新建文件", (): void => this.createFile(), { + bgColor: Color.White, + color: Color.Black, + borderOptions: { width: 2, color: Color.Black } + }) + }.margin({ bottom: 8 }) + + this.BuildButton("加载压缩文件", (): void => this.loadAsyncFile(), { bgColor: Color.Green }) + this.BuildButton("生成压缩文件", (): void => this.generateZIP(), { bgColor: Color.Orange }) + // this.BuildButton("查看文件信息",this.debugger,{bgColor:Color.Gray}); + this.BuildButton("遍历(目录及文件)", (): void => this.forEachZIP()) + this.BuildButton("过滤(过滤文件)", (): void => this.filterZIP()) + } + + Row() { + Text("设置密码:") + TextInput({ placeholder: '请输入密码...', text: this.password || "" }) + .height(40) + .width('50%') + .onChange((value: string) => { + this.password = value + }) + .margin({ bottom: 12 }) + } + + Row() { + Text(`当前选中文件夹:${this.currentFolder || '根目录'}`) + .fontSize(20) + .fontColor(Color.Red) + .textAlign(TextAlign.Start) + .margin({ right: 10 }); + this.BuildButton("选择根目录", () => this.currentFolder = ""); + }.justifyContent(FlexAlign.Start).padding({ left: 8, right: 8, top: 24, bottom: 24 }).width("100%") + + List() { + ForEach(this.directory, (item: JSZipObject) => { + ListItem() { + this.BuildDirOrFile(item); + } + }) + + }.width("100%").layoutWeight(1) + Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){ + LoadingProgress() + .color(Color.White) + .width(100) + .height(100) + } + .position({x:0,y:0}) + .opacity(0.3) + .backgroundColor(Color.Black) + .width("100%") + .height("100%") + .visibility(this.isLoading?Visibility.Visible:Visibility.None) + + + + + } + .width('100%') + .height("100%") + .justifyContent(FlexAlign.Start) + .padding({ left: 4, right: 4, top: 4 }) + } + .width("100%") + .height("100%") + + } +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/main/ets/types/type.ets b/ohos-jszip/entry/src/main/ets/types/type.ets new file mode 100644 index 00000000..9824d571 --- /dev/null +++ b/ohos-jszip/entry/src/main/ets/types/type.ets @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { JSZipObject } from "@ohos/jszip" +export interface BuildButtonOptions {bgColor?:ResourceColor,color?:ResourceColor,borderOptions?:BorderOptions} + +export type Files = Record; + + + +export class ReturnValue { + create_type:"DIR"| "FILE" | "ZIP" + folderName?:string; + fileName?:string; + contentText?:string; + zipName?:string; + + constructor() { + this.create_type = "DIR"; + this.folderName = ""; + this.fileName = ""; + this.contentText = ""; + this.zipName = "" + } +} + +export type Confirm = (data:ReturnValue) => void; +export type Cancel = () => void; \ No newline at end of file diff --git a/ohos-jszip/entry/src/main/ets/utils/FileSaver.ets b/ohos-jszip/entry/src/main/ets/utils/FileSaver.ets new file mode 100644 index 00000000..76118a01 --- /dev/null +++ b/ohos-jszip/entry/src/main/ets/utils/FileSaver.ets @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import fs from '@ohos.file.fs'; +import promptAction from '@ohos.promptAction'; + +let context = getContext(); + +export function writeCacheDirFile(fileName:string,fileData:string|ArrayBuffer):void{ + const path = `${context.cacheDir}/${fileName}`; + const openInfo = fs.openSync(path,fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + fs.writeSync(openInfo.fd,fileData); + promptAction.showToast({message:"保存文件成功,请在设备管理器中查看!"}); + console.log("保存文件成功,请在设备管理器中查看!") +} + +export async function loadAsyncFromRawFile(fileName:string):Promise{ + const resourceManager = context.resourceManager; + try { + const data = await resourceManager.getRawFileContent(fileName); + promptAction.showToast({message:"加载rawfile目录下面的文件成功!"}); + + return data; + }catch (err){ + promptAction.showToast({message:"加载rawfile目录下面的文件失败!"}); + } +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/main/ets/utils/log.ts b/ohos-jszip/entry/src/main/ets/utils/log.ts new file mode 100644 index 00000000..08cda98a --- /dev/null +++ b/ohos-jszip/entry/src/main/ets/utils/log.ts @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +let tag = "jszip=======>" +export function log(text:any){ + if(typeof text === "object"){ + text = JSON.stringify(text,null,"\t"); + } + console.log(`${tag} ${text}`); +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/main/module.json5 b/ohos-jszip/entry/src/main/module.json5 new file mode 100644 index 00000000..9b07af70 --- /dev/null +++ b/ohos-jszip/entry/src/main/module.json5 @@ -0,0 +1,37 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ts", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/main/resources/base/element/color.json b/ohos-jszip/entry/src/main/resources/base/element/color.json new file mode 100644 index 00000000..3c712962 --- /dev/null +++ b/ohos-jszip/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/main/resources/base/element/string.json b/ohos-jszip/entry/src/main/resources/base/element/string.json new file mode 100644 index 00000000..f9459551 --- /dev/null +++ b/ohos-jszip/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/main/resources/base/media/icon.png b/ohos-jszip/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c GIT binary patch literal 6790 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⪌NEN0UcA&pF@fq~Fh&)0f<(44r&Yuxd5sh~ic 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
  • 1l|zvHiM*J`0K+l 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 z zpxNTTvxmb=T~gM=SJdr|yjpnOHcouW!Ql`4zJ|W`dv#)VoM(V5;yp&k;$4r6tndCF zXgB&TtlK`@3$#WyWl|KCb_{ms1c8V zGT}v^RvjkRaCe;Gax>Pj_3r`rGhVY6n$DiLF=u}ypO|+Q;d&><4~n|}p)QZ5cw`H^ zb=^BZD<7ufa0jn7a_3anukYm3JYD1cJ4TktQb{b~4J5@SVgUJYpz+-BIqA(uGAr31 z9RAba4)p&33}0!tUK~|xEV9T0jmXFD<$XE~*UQ3KF0pYa%c2~A2wZf}T>cgM1LJ$2 z+1lDiZF^O|*O|`A2b`#kdz>au>t1mek3VPs01vAl40tBm{zl+^pgqfD{@Ric(-`)t zbrG+#x#apTji-34NtaL4VHX;l5j$HFta>KkJs7db$F4D7RQ}En8BvK51vU5;`*+v#fi|F+W#@8rQDc_abJq|5;?2( zr6?RHi@aU%!^B#V*Q|7x)~^K2u|+z(fG?<6%H$tL&vV|f^}h=K(O(nnt~@W`_JhG* zAGuTvZLQYb*+}FaxNQ9meaoSE1H#$@D(RYJP~(t7jMt#rK#PNn9CW1WUt#i}3iuE9 z9q_)Le-69x2UEQ9PN0Ytp5|5~0Cd3MkFIO#3lD?70MemIwC@kvLZ~pfiF#MAs(?7D z_khU~46_5zZYwLXo=Y!*H2YKLSf|(}!3iWkBQLlk)8C5nEn~#r9zGXF@;$S7=RsY^ z?KZF})NL29?`^?fIepOPzPtMh$k~^Z>DrOB$X&7q(mSca{OYc086PM3C*wWmiZsdm zL$CNZRnnrjkPkI1<|0r>RE4uHI}?Hd>TBHmC*xlUc*zn?J6DDi_e?XXis4%s+azZU zr|K)HywNSLl))*GsqQ3YBk=@Rnd`p{d=)&BUS8VUwb_h;HOse{6my-*!GT_(ha<71 z#@Xu+YF*i_Zex)Fz##BVd{6sd>Ruz&JTs)|dM=r9G%0?f{z$-OjZQW*0nW_zJ*(LC z`<+6>8yzYMuQafEo;kv%K*=A!WoGr@lkHw1@sGz^Rp)>_LH&uWLpe6GEQ#g=F3sUx z2G-n8csLwXl@s#o<9+vq$BL%YGzsUwx{xe0#T=e{OFjU?wm#@R0O?-y`!DEU7yK*X z%e@~-x4yA!%dI^=;g5_KchFz>yIbF6z>{qu z-skbh74Mf;>nvtD{{VX)LBZ*f(AC>m8P|Jb>r%^a@?w#R$7((p@V2ytHH{X={5M}d z+Bq}$mCxf|S@E;MUJpM9JY_6;J+v=lq3SY1VvI$xRySXEXl*tHx`} z{x!!h{3+ib0tQn-)ickftd!Q}Me2Y5*7{>p_|M^eIlP;z)so^xb^;P5cMI2KQSM>~ zOp%QH*8ySiSH#!9Yt^(L3hFw=y|iXWg(Hm_@;54t=L^TL%nwmtk4y0r!TL^@K8^6o z`@|YHpL4NfM41%l?#N`9{d1N)tYLzT^U}S~!ymM7gMJ?AE2j8!MY-1JMrmZZzPa*T zG`QTc#}V6=#sO@exvn$IaqNBaJ|<7Bc%lWl(k9UI(JXODRLyYDg3Am`^GUbAPC4mc zMA}Ujg$(yPl1MKuM(FMHxTmo_IPYJRo(27@z8?5{#afSy+rhJ2U)+ofqjJ}BK<++m zh~(@Kj!N_RS1~W`Bk?1}8nyhM8M~ZCa;)%2y_BS-xDL!2h*6J~FdLknvVlE5Go}v0rF$>K7Azq)J$aP&fm(9+mk^@V~)77kqQ7TVMQG zx}H56)t-FFR@y0@@wj6yWNqxclV4=`@8kD}eirGPcY*vpVR5Nze`VWmr&&Z? zK!kveaO_tbi5*U8DW2gzv!>~@&v9|(+N&SlPap}9qm9f4P6w?|2Df3TSuOsZI$Ybh zBuf)-LI(uy9C2R+_={an4e8dNGWg+t9=EENON$)@lLfRgugpBi*-4d`9bFg$%8vEs z`seK{@jK(!hIKCo_-{v#!uBchUtHT>EKMD@K4rrMBOq|AmTyHASXO7~@@x8i@*9hL zm68BT??w!#AKfE6zY6R$#@S=`k0H=G&gpUsdL5?#&p#qr7E?Fc`Z(pkwR zv~Z{Qm;<_AxLw~`2I9}!JNv;t@X`ie120^!bs+FT?hSr4{A=)k{2*Ttbz5Hx6t~cI zRx%`M^TeTvXMkg-#$o_H1}kds#2zoO(;9sb;v`yyo#eUu6n|(JQODD1ow(dbIj+w0 z;ncc^?A;P-1nry=9j|jhRc}II1GIm#=I;jzf$ zwL6a%o}H?>it{}K_E-1|C&E7r-Rqt&@|(qa-?_*y633B8@!xBLvh1gNBwg1K5g#IXjlEV0+0v(K{RtfQ|qa zHO0&kKGwmakO`1$u&t3Oe2qIhA9ASeR%byg4sq`F>((i)z7oR0^$+Z zsXb{HH;H!V0-q>{Breit90AnyAAqlu{{U*=it+dd!@3uPG|~2rYsGg*3KYMUYiovS zHuYv{3Zf|Q*NXa|Qq?VVy*lFd>D6uRk*1nPJ5?h=mSRsppk&wM$HfhIU-AC{#Enbi zEXy+JiwLyRc9Nwm#|<(mr-fUmRSp?AdcH-nI1mrL*FNz#Qp5^ znwsTOci1@snVYer7Q3s-FiEB!R|K&iHa)(T&}xY!s4e4i+rTA?3g2j=)gSCl zfV_fFYS>G1Ey9t`F;ELvTrf}%e0QLvd9~(?ZKn9A!&lliCYQtV+}mCEZzA)` z!LEy0j9l3H_i(Vcm=8YMPy=H;50vmh=ZfTfLYMDs*BT=;Tt-!u6bwj(fpN6)oOGmV z7JPr>4~0G-x$$dV_bJ34X&S7$cZeZV9gWP) z-#o}kF*`5-K7Q{x#~mxW@ZXDMzK$I~#8+!$tHRz}nAsO=uK?pcNc9wx17_35)5)cw z@x6lhe{|vzJ3jaXhwiL{8<02fw?kc*hwi*VVSglArLDZy6RNatXw4>92NDo?8R>v? zR)>VFd|6?2W39^9wihep&Jd{HI_+XJw1db!M{4q$eGgIiUE-DS{q6na+70_Du$oC! z#}tSDSjrn5pWtD^=x}L?p2c{I{{ZPxxHj{IY~Y=zILEd+8m+3{JTRE9-g(w>$(7s#bd;_cS82gc=iIXz9<}U ze82a{-p_t0CL(E;`f?|e36W5~@f3u%K{?LsH+$S(bshd^i4bMaS0CK$PVD!WS6Eh*ct}g zJgZWHd}rfHUs;{oPqAIAYi=`^1C?o80B0PKIqhEArRj?~j^w#m_61mYF~kVR%10#Q zu4~Ht7X|c2?slCgMv(3yMoaW#ob&vv(l7NrS5J}{bi|HGkp|?-nMpkk(o_W=r03eD z2IpgE8`%ZHmXxdOo>hA}*ON5by4pa>ARAhA^ z^sMV|3TZc2%c$P!hFxajH3@mg+oB(NOhE9ey;X6Hb~;vXvV!AOK^ zNPMXnx!MfSkQIO0Va9t?BIk|jUJqY}-YEY7g{yGVYT6FEH{V~_#9!>rPst-g86}W` ziH0%{%sS$_?*jP$0O7xhH7R^MZ>b6OIOOwDi}{Oj7il7M_m>{OFarmg=yjim`j>$` zQG4+}z`Cs3U4`nrnvR?gnP(%n26c$=f7?~$j#s^Wbgx%bmD~{77xz%8r>i99?Zz)g5ly>ve!T7g^a6paEza)jt=*NxZL?CfkUm6; zHiEvVJY&6L-Rco(S_)5nBv$r`8U}cGJV;Li1wlCX>0B+=yR4?2qUdR6bUjWRh~m7r zFXje94jEmV|{}5SMacmtByCO+%W^&8LxpgUkCh4_<7jr1Y+yT@OtD z$ZZ1Z1(h&knHhJ2-^O;FfxG_z)l`9_Y9F|X)lf-iSD&W#iqHXt|GYE_oBFs zutWF98SR?)9Vf)M@yKm%q>cb^V{P9ogVg7t_O3s~e+I7fXznEVd8$P&m3X90qiS2G zv~o^=b3ZQ!PBYN-HOT0GJ@Djq-|&NcYp}S`FQX+bZkRWg@#p1HFvws#G3J<(?0o^} z&m6yKmM|FfWgH*NiqL~z)FNH6J_q*+=kPrb^RJ!tp9=Wj!*NG(@cUewSFn+TB!Wbl zKs^R~{V8<+0E#wN_XAAv$NWie$=Vs?kt2}$uHlc?k)^aggr8EH7{>i$S9PcBK?-@B|ygDa(@~HDD^$^OZz=YqB=)(j5>x!EA?FG@valZ8YKE>nW*WI zJs@yppILNn*KT9@+bL78=`VgZble#KAElE1IL<~Uzl;1qqsiq6-Wud|&Y1wC|_u znri7+NSFsuhnF4l2qPbjEtIwl>py}#Wd@UVDxAX=(!H}QasHx0c9EV4!4zB>_tu$z z9)%frWg-B0+;~8LgmwG}T9?J27ycf2cSB3R5?w@Y3ogis!-C$e!A$$~?_Lw|lKWfM zyf=BQUTYCt>afo}q)iwN3dacm%B%h93Bhi|rF_-n`wc@}@pD^UK?GLw4U#H=%QFtF zSD?ZC>nT;`1xn{_#k&#>l@h+(Kvh3j4p|_riY6ULfRTYKF$Lmqa-;{-?nz$gbNJ-Dyc z4L{;_mb2jNUkhn+Ko-|~N+AO!T!H~7oB|K&UQeocdiuuYwZ95S3*EEj;JIRBeB!&d_8CIr{WdmsG2<$qekdtDvZB@Ij)As;K#%Ue@DuXXri`yhC)#k!@You}KPT05)VUPu8kDjs%|*VqdE2l!?CJ4<^Ude4lB zh8G!IRQv2RkXZ5tYwWEfMbq?KIP7$bb+xyMVO0k~?t9cq2@@&Y{M7L$>{Ia;H1hm4 z9H=GXRF{iwV>V45C*<98Oy?sqwTz({^>cO2(EEA{$li!WT_ zvzpzHP)$vXR=3wF*1YP`1CY#wS|$aX(0uf7rdW4>Ur>TXpy3bC?}u0{@PIxm6086b8xnv9VK zZTnCVyStnodG0zI{Z@NTq-_|;r28V{?(DPd^Y*eafOmOV{sNBb=6caq62zpB0Il0z%*kgn%F z2?Ma`2WtD?*GP{|xN-^aS535R4-_k~euu@HU+lNxTVI;#RGfDCzcXF-o$x=w znrg;kwdOxiIs7Z=(`32eQZAmY!5O8P$Q1Q z-Zk_{QGfIm72Zdusvo#Ht7~W<<|Bc{T9u1D#k>)r+~>@WW20DzzAQt5vW z?DYGYF6}RM2AHlRS?=CgkoLk6)7rf}SpnOhrCS!Ea8`$AD;#~c>$`=9H1ZHg;mZS` z-F@Xyf4!W7dvY^f0$Roxl~Y@P+1Aq_GcHN*+t_K>edW9C%g(b#Z#0 zCDc&m8tsvhSaf8zOrjrimiMSdqcf)_2UnWchugMbAaAhQ2C(*&h*nQ*U{srOMh^%EUyG zuHA}ymB&xQzFL0}-)lB&rfN45O#?AyjGkIX>fHDDprh0EUyff8uXTNE#TFW^+%|gF zB4tT7u46nAi~vWjI#-+cH&S)i#-V*Amu#e#c;sbx!?x$c41y1EMPuq3d{H2RX<9pI zQ~?Ser26}sUk6WXVR>pCxud_$uokZYQZdY#3l^7koj&?7{>9EM_YK*_~^c6>d$u+svh zajc^BY#WZP->ubiF4MUM=jA3^ZKH7;fs5U~)b3CQ}x5#`l?gT3kSYx>9-lVqp&8O;?%yjwP=T$5%@wRryP!yAs{z2u%i<^nz@#Hq5D03yX-I};~{{X&ZbB%-4;|7;7 zSo_mK@m-z7JLbNPq+kh1-CffoqX2j!xPOd#<$`=A@!%~avQMFEXbTaHy{v;KzazEF zkN8&?S699U@g(!Hm7ZJ0-k4|QRH-B~`;Kdt(XKu-d`{3jN8)XB#k0fVO%@ppj}d8w z~{)QH(J82^-k_ zz_7<0*PTn@&j8FCZ8q;w)9r$iBfChZaz=5P0gRE@e7^kClj0Qmjp&zJ)uXhMQe$PG z=52$HdDz+i0QJ_CT6c;3S*S%}@bgW76kSQrn;dG8#-!sePs#_TO>vwNXP;R3F4p1R zBuG(t<01Z3^E!ucY~Z4TT=1=hmktl%lf9S_Uc)N=)mZDYpMYTC={nystJapw6c=d*c|O8o+} zD*%A~=3+71n&KK}stJ9FVbhdvj7 z9Q;JmX4L#&t0T3oqbA#Xcx7Bd&$wsIDl!*54tv)>)}7euZUNYwwY}m zmX!c;CFA`2-yAA8W1fvcQnN)HUx!~6)53Af;g%Ou>QV%?)8~jS^Ldgod(i4uHl(+DU^)JrFt?k{vnWSi}+vRZ42SXi(xISQh#p9 zRy(6`;_~w8yQ6Y&zKx6u^{<57$(muQ3jSwe%kJaa+M zWAdN&g79s(!mo}RcDvz%Eq>KEo%UdGE!;OCjGhVP53PQMcr9%FQQ`jp?HDFuZ6NaQ z?A?T(M5hFWVaP@tsPx7Set!HSx6{0T<8Kmp-%_)iSWPY#duZl9X<6iKD@g6ZDmnDc zd-sO^ET0M6$q$A!AGBR+*lA-dNd_^F6m%W&+JTL2ixrlDhJE%flAxd31i0CpdA z=hLNd+Nw&Y>73?DBaa#j1J!i5Cbl{Apmpf#!>XRYTK#YM5%J@} zpB%hAmwHnrp0{j(-dHjD)Svll7Jl?cwmDP5p`kQ;jGB}?c0`OZ{o_e(eRC(>jQ)I7 zzhCjH1HFMM%GixwulH%bIf?)v0fA(ZpYA^9k&`xc-$3n@fDLLR|hL zpB2Omxgg`~iV%x%&ngBXUP4ZOZZImw=V(cnfKLOxXTADFxs3gDUKR11<0Yqn^oX?R z1HQAWzn2aU5(x2=E8~!Vx;xd4qo4TU<0E-&{{Ro{v*pgw$$rbv?o{MM?YQ#U?ZtfE zuC<-jvD4W%!z>LG1L*u5dSkHdSo)_oC&V#aP4=)4m`fM)gZhJ17V%n0&DlRbLa^zP z(SE0}pq9;DD$nfpkZJI<6oo>9Nhbr;n%es`R*{rpnOl&3KMIFN6GnX5@E52U!ROYr z1hKTmT(0CDx(+M0 zx4Mng4WnxDfkAw_7omW8WUAx6LmEgW`NlC?)^kBH#BGu~{e3BAhZ5(xpsNm52_8uN z>M+VrYKr06-D6G_eLK{lRx!QK1v`%87>;&|_u^o>dlr|%Q*Y#~vM$mji zsmjY0u9ug$GGYAKLI!4Yo<3qgu7ARsw3_#Y>@`m=Nam6yEV7I+&peLV?dmzKs5R+4 zd*E$i!b^2qyR~SMhY_?SoiCQkd7mKaDS7CD_={AgR3=Kn4@E#vI0u~9p2t0f&6M_b zb3;AsO|{{flsn0S0AbLv9-i5%1af-0j>2EFc!J-~)AbUKaW3OqEPl4}? zU0FQ3e4rVcSHl%vRPacU4^9d7udQ!9Ip9Bwej01rcb8TUF>@KYJEE0&`E$xLo>YE$ zuZjF$;cp*!SY2xV8`LAb(5+w05Zc}Srdw1T?s(WM7|(nH0IeSd-}t{$g6GD64_?#l zmQk$N`elO@nsh_{yUYGBMp4cv1L|K4c!yH(GY*i^?r0uj_#gm9-&)uFe z*RuhUUda>b+J=MX*~bRQQe4OKrtZhke~o%x>B2|uB1>vk$%t+Fa}T?84KSX zE7WbgH(@+$Jmxu|bx9UT$T7bhNUS}&*N}ME!uNV!uD&SK8J(e#PUL)>cLU{R$MCq| zj)sC+=yrYyy3+K7w9@VoCXE$W&H2On?r&0i*OhA;E!LT>F1-!3_g63iCbda+w5WRQ z2ZF=4YuNk~+%YyL|1Qqyl=3^UXtd zr0P08tQJd&1)^{L!NHDD*c+JR?+VwllEO(;TmJ4;9SG^{tY{?XrO|CHFJDxCXPu4@ zlswcUs98FnLzBm9n$fPtpl7_7%#Kpv##7}8+-*7GvO1dB)GTz%nM|@YrdAj#9EHYz zyIC=BaBQZYJ@5=iB#acW&j5qeiU7T#=o%h{;&c|8b>^8B>u$G}OOtVBxfC-;9BxmP zSaO-_Mg@9KrQyO+(?XD1TF-E^$|69o1fAL}ar5)LJvxD2Q+cZ)jjbe<`H+8om;EkK#O0 zc!$HD8~)Al0#5On;&n*wB8wqi+aSj09B1zu`TM}%7<@tC9}}Gm;+3P{+d;Y+TBk`ExB zmCsM%`y@-bEhd)U;_=HosONt@ah!o$nU3b-;v`ukSV#fS3dHtbrDa~(-@zMsQdQO$5?0>d*#Fst5O5HRB#6@IQ?_F*GJ^UfSZ`@JeD?V7i(ek>h^Q zo_Iy%WU&?cBYAgo6mDUU%#aV4ByA-6=dkK)m4X$Q#3xjpgfc^G_FxfsWi7vQlg87> z9dalwNwf2k!&mX%iXF5~ZqHJ-jOC%WC*wzK%ZeIODyLaXd=UOh-)lkzm&Yto$DEhl!;ZI+XVp<iRhurD^ z0BtZF{&bk$r_VMXGt;e@y}qj*-MgM6iM+WXJ=e-_nU~Ot@3hYr#eI0TR&OC@8;Em) zsymQ<>w8-G2V-*|+3fEuWVgl?-CCct#0N!5qam<6XElpI?Cql3M$=nd-A{EaVGP3L zp^MbVyQuawgl}A4Nb(`MK`d%d4anqFI*-OQ(JZYr7K`nSBnue;$|Bv636J=K=QW!@ zgmkY3+AMmWuw${1Z4+I{N!{pMrcH9U8e7AzY4&;o+r6am7Hf-Z6VMLH_zLW7H49x+PKs+JnrI|q(VKuH-nrq`NXS## zxNR!HShU)Ck{ibPS<$h%dE+6!O7wdjKJw**T}&g|IMHR|{k=D0=Yd-|qc#HO4@w^u59!m=$et>n&s|Vxo&3w_| z-;Mek*h6`y-N!AXw$zYt82e|vdtK+nC_F{sO=rVb&AQ)JvADHxMm||%W%T!|glrLa zXW{<M) z&cob&Ju8;}(!5m>`KM^FNY!IaZ%y)Tm=PDuJCpS_9V2{ZI3_GQvM zE#l2GC^XyEhg?EM&)Os`b~juqj`+fp(ATo+mKQpHr7oRw5k`Y(W+Z@4Gr&E4b6=D? zKC`K4dW1TbnLFEDLUOK*RO7ff#zF2Y?9T)IdDgsNeWqv^4`i2Hwx74oZQ*qsfU zsJLZ`G3CVA^*PG}--`6_gdP|0j+x;b8~*?g>FZ~AJW6ginB<*g+BX9vWQI)iAmEPO ztJhKvGeoK!+@?R+rHlZCIPbe4{$iZaO|Wg0Mtzq!{Oey~#YRwiRvg{RY0Cb@;S%|jh zoYcz)Ls}*uUJWk74h1(bu|;4V_^FZ{{Hs>B6VsZnaj0q53%>s9D_}dw;Xj$Afg(`` z-lD85AY&tn;P1XB_)ZA~8hr1nOVFjHZz<2FRdJujxx4R(elDGrY;?O#9@w5|)h+_K z9-H`1DRDW1pzDBMQ^xouCz{vOjVKEVWys%j^trIPv5{{Xh#pCp37SHC)*a@uXN4kxHV^pt={39(Mrdklri~-wOWCsX&ohwy(OLbp6nU-FeLX=>b23&;=4Iy!nu9jOo`9u zTn)Xo#l~3>zC9|uxmMV~sn0?=r(`}(i1hm(9BLYU#A#~g=@@{qDd%@=3iq!B{AHg^ znY8}^6Ox6w5vx0fF@5}cs})E-7F4Yj>KSj1junvyYT zvP|&JkGhQ$e4$6LUwZIeH^ujUA=0DL_0@uTlPE4DiE>K%vJBA{k$q!0n^L&Cu(OyI zON%F2_UG0tfmlS$A#Id2uBI;4JF(8kg^;18I$q2#H+9V%O^ zElh>bD#DB&%Xk*wBHZkLFTIKb1F7A zDER`B^y^$4#}6s%ejxG3#cf%Mw7rq;uGN8!lM5EkwF}&8O}dC`g_8EvnHwHtr9EC?M~}T zi#w86j5wP;aSWYDxxlJMa&~9t^LS$ZDZ@v;*nyO2pUq9a$Jg4r`)>^RvNb^!<1$XX zd50NM*y6uVwEqCv58-8_u<;Z(6B*acGOfbfIehXG7_-6k>Ds!>KY^bJ^o>&9J5LL( z#j`F=#qI2mAYs7RoCEL8E>ZhK@>>4O#5!7(mr46m9s)*Ou|0^}&t7Y+@JHtC-rSHu4R40vf;9XCpb6quJYKJCCB z!a;(dcEQbccAg#5z!6UkgviG#vSMZ}>Kam8KT4&by`_%@_(AX+;dg-}islFxU-1OH zWt&pC-7t3}mWO^-7jZlTpIn^RwM(K|+S#2p`2yQqIBzb@eVKky(n7sJ_pXBS-&8T1 zO+Nf-kpaMl1U&lu+6MHOk78&enUY)hTTHUm zV$^hJT^`!h?kfa4q@O)Ok;!5`g?Jb3bntlJ;N|q14~k>4SXpLhRP%OGu(r%NWny_9 zxaW%Z{X|-7Yc;fbgoy9D99v4LV-3dDJncS*A4>fC{h>SurTjk9H1nk0%X6h&Y7)-E zV$)ot^Ki=~{{ZsQNgponyV`)eN0@vS(R^QR4bGLL8;6Hgie{PPJ7b)pWs`8_Pi*wf zeRCIp^xZK$Ijuz>_GR)#3QZK}cK6%LpHuED;?D(N-oCR0w)bCVhQdXdD$lZ9vBHg= zS$mK;ue&bwJx)C>WYn&cR8xlx6h_!SgQi6TC~L`iszZ0Cv^jxPf)$llb9y%1fWF|G z^X*qxI&h0mX$8gB0wicmkA)pyZ`~fG*GF&SQqsM)g>JV)sd;xIgXnlQfpoXJc)Y&V zwJ$N}JHK?QrZN4+z~l;cEhcg^>oDE@r6!qWdp)9P;w;4(x&jv`>0dnjSdK3dLm&2h zO>cE$heChWOU_BhV27o8CcWZ&D{*0?_h?r9szX=EehEX+4IuS^eGxiNryb3D$C;;VNLj#VVU}Fr z=dsA=BC6wQBld&#efa(1PmP`wg8trQi(0mfeYV|5#^68J#yiH}nw|}N#IoC!^9%5M z0bk9HroH1|gSxDKGVmSbx@M(salAZ7bW$P5635f#=-rrg=D%b=XD`~5!v6ptbP*GI zI!}vikwxa6xF~WsGh2hpMtYDrUi2>_RC^y@foQmJ**=8S?R1-Vf&i{DH3)O&NOvtW z`)bu#{F%>8o|H68M&$aagYV!D#Pd-NPC3W!*kJw@!C&8b(sK9*wQ_p@0E(i~ES^Z1 z$s&S&RV|Oeb)#Y~YkXb!sigcU@Lr?ho87bATEt!$PDpnrYG)k=;y$(cTK+rNJW=9{ z?-uK)&$-ru7mLg$HFX%=6z6US-N)VZuG{v(*7aFD2V_?9%=fyKQWcQx+_4S8K=cQ( zubloHUPG;3CarZ7&kQWl%?SI-%)B;7Z1Y*Uk8|nkUmHbxu3AAkF}2v+3Qdau);B?nQfZ?QlE1t;?#KFm zb(5%Tx~1?#bt#eJ7+m%gIXAFb9@iI-H0!Yo%>G>RB8FYK3i#x4?@Oroo;!9T+4pWt zJ_dXA8T|OKAkwsbds1axCfZ5fL$`9qSpoNKZ6BR_){F3}{_TMAJnb7W8&)DWq3#%t z2>Mc7#JDTmPYw90;z0yD6q4TD${WmzHr*iFa5oOa+x4%ZJRCKlZMR+qIb4z>AY}$W zygKHl@b;VGe+Aeg+rbT*s({mN0!Js+x{_{oeU)fR z(sVhjPcV~!YImLBRRCvqe@eTVn@basxC)Bz5<{@|sz}#Y17gS`9dp+|hiZ@#$_XKd zum1q9m|VquKK@10b)`QSn3g_r;>x*hrdonC}WJ9$E8-e0B%7wP!X5r+hrM(uad*`)e{=M-0De zkbt16UziSf0C8Rs@mIuJH;JvZv!TW(v9f`l+-D83Lb8$A1t5%jab1ta{bGGD!7%(S z@MLUnZjofX^8WzVDh1rT-0-2BmM4G(e3ITK&>+>9!8#mUY;E9J;GLY7xRx+{<|Oo2 zVs;Nttx9F2d;ESUn^X8H;(cGmS29m7w;Y!CsR7GJ@_`z$A9HpOCb#@Q;N2CxEudcg zlv)^VVRi!y%O=6Kw>LYx_2k#hmO}AXYfD%AHlL_T0Jwyc``yw67##son);_%xX~@G z63iKFY?0$g2^d!~e2OrCg!av7ox(>gr9(3760P0Uz1-2Wy1F96Gsee)>N=nHg?a#o zOS&uexMB_lMndk#w{k0kd#gHhQ_Y{{Vz) zR5ws7JYp3Mf_j2;l?U;mlzO6C+X-X1juetuRH|ng0fq?Ap%vmDF8Cj&+-iy9uZN8O z3h^v>lr#;SDGqRQ1~wDa;Jwvj9PpCwK=qA20aQPQaay8P_arbzd9lwjMpw`@q-e?xClywHsYq6-%-Rb{q+EFu}Vw<6k@YTST&LP-z;Wj{XSdNh7z^ z6kJ?EAmI5^A;!`arr5O^B>=Fnh! z{W3`k-f0AY@q^Y|LU;^2q4`@pVAm~crfMsx>N@9zkn4IDv9>QMWN4?2vywJ9DJ(~- z9=%5u_0{%=rs|32PMc&SB1GZ6x$jR;bb2 zYRWJ|VVdhmxqUuu(a57F8L}7xcq)A;B&7F- zE61|7ky)+KEQ#ck8Y%uA-FkXw70PQr6|~O>&Hah3-kTk3Dhl(v^b(F@>r(K1{qzcarppTa-nIMzK zPad^Ryffi+vYSquN`Y)=jgjCHfSVid06S*9!$`Eb_)QC2=-Q(qqu3{!qF<^lXewmrpmNpKKtG#NB}hw&@+aPYT@MEZt}99kZ^ zg2Am5b@W+J#yaPO4RPWFK`AXksIy0e1!Bk!NG3euN{qk zqKM#Ra=>nEewD&_&fmeSqg+Gc18Z)Qs{pd1lIN}z9;Thg%+7P+{{Y6D%|l1Em&A4} zeH5wl>N-=c%CmPS)Z$b=yFtZRhvWYM!(B^U8gx3tSp>?TwnWz3-0_9pJ9A$ZSbR3p zbywAOYb(anBeQHnXKQifFyH?GEewuIf`7YOT0g^Y8BQe7be|K)b2YHvC583Boe&Mk z8`yL2jI9GEpL{VpPv=>(YLcvy2q4?}xbxzsh-n%==hJ+e>IlS@hAv{HJNfLEj&zdT5?vWnjd!Fyr2-+}~QlnYewKtXsbkXqNGb+ZZH(KKP(E%ybn#iMk{y8u(^;iRgstY%7!Wrrg*K5J5A8_8<%@>|arM5PAhH1oy8`OZ`O!oTrs#j@d z+NwjRU8`H$qLly=Lk_8v#?#;4wk|Hloo?6nVXe_dL{YF~C$Smt>p_{+=za?D&xep* z#b;-1PIo_)t)1OQ=E*F3l1Vk`78=&4XKUtcg)JlLi+;Nv5u)K_XKcr!5w`o>%ZDtPxynQ zd_TCo)RNy$v1WoJZ@Hf5bGA>Jfv|lECciuc_tMM5gDSj0AM*VT5c(5x2&)O}>ANc91U*I>06@1+{ zT+**2KlIeE9^r=-=B?sJ^E}AGLTdH5if?&TY$^AtZJ9YU?azQ7Ao$_%;`YME4OZUf z&f0Z&km{=z#m)%Y`2{^eui2{)6Znqq#tXFZmY?R#ftnd145~=v21Xef?_bPhUM9PS zaV4yUTzZ_Jz}I7^{8sVJj>8VEa)CbXC15{FiS}BK4dsPb>Kpa9y7$<|fpL$J)Df>{r67+=vOZyE%&v!VM z(ov7d8f3o`{0Vl3JB?LgPC-`<6CbYNEAorOKk!g57g^gN)i33_ml<>jLXY=fJpMJT zzqeJ7h_xGQZD&tgp)7!Y`W2UGC#mm3VaR^8+4$4KSCOk)>UQj)00OY!4w$VJ*Ys!m zw`q^9d~>4wZTJHnkCMfIyfJ}~#aM;gW z0vj2}YSP2xKD7SX(SZK|kJ!KOu~R0wqXogdi|}A;!dO#~R{CVK3LQTf8Y@~X~EAood_R9U5?R5t$;K^?`un3-Pn_KE#&mQDf#;^Nz z{58`i2S)HUgay-bv{A)yV?BXBzS#GpkbH;fq@NW$4VGJb{{XbO=MgJDewYK;P+Fm4%n~ZH<&y?$Ldw z=Jg&pU3*BejOW|+u9s8s%)&Nnj~H3nhZzRe(Bo<8hm@b?U(O$kelvKt#4!UU=ajqm z?2kJ^&U^Rwsu28F@ubkU{c2?_2xTwwki!IRJY(>sVB}}?8GZ2^;oY+Ny04G#ubek4 z9nHL9NcB}4mlcPm{73jveQR^7X=W?=AXyKYdoj5(GMoh&VxW@%-#{S0>^*Dw`IE+a zxq)DpT)U1HB&<=)$clYJsQ`Wgujw8!ywhxMEbT9^KF@I5+48-hw3NB zpW9ad0Kv?fCYx}OT)MGn?4t<+sQ&<#L6?_iJy`Gsd{^Qx+SA3_&W0>3V@19Bl-w{a zAxHbeuLm9dYvzqlQ~uMEHj>?)A~*%QfO^v0Ydb8?pJ{B6`NR#!0RDZdk`7a_doLF2 zT0A=Sl(?{lK&2$P-ynYP^L+TvG+RQJcOv^(zTYP7l}@ZWkbbqv$1b-#@##bN54S3y z92FhGAA9Rl&*9xhG~ah158X-5Jq~>+aYN*1ORV_X#nIx@tb?KV#{u*EWG|?`t-&)ebYLKvWns)P1nRx^fFsIn9 zeIKfPO|j4}XV<(LtBp0T;va0Wx`S=3r3V{cH7Eh?mBmASiu61>UxZ!^@Fn_Mc)jkg zR_ZjLPt@Qa@hiGVUX02-#31lN!3VLg5b>smr)gT0W+>s)qM1vJcy3zc1?=0~k-M^< zYwF9tih6I0bZHHoFxa64URf^FWpX{^=!gBK#eA2l!)=DMF zZe>(+wrI)N8@>)J(=;Cx+1|tC>K6AeI3K__A^!mD*Ny8x%AG>{`Z4 zSPz%9Zcqs)<>v(S=7po!(MMDN(fn!t*YUovRqX6;q=rNCm;r2#oNeP3@BaV@z76=( z;wHBKAA!=`v#ac(>u} z_@e#|UJYXNO1-y@qgQ~2Tps%vW3O7{kHViF%&^5&?wllqybpe9`lkO-Q zJK68NE8zPzw~kLBM4>s!Cj+^z9X=xI9wWJzN$}i)?&1z-ZKNz?uq1(!YtA&g$fLNL z`9p<}vY>O5^~&d;!nR|&^59`;N=U~oB$n~Qq#7mXi)663U8Pp( zl4MX%%#7e}Q|NiGQ`5Xl;5+>z%hh#DEma?YB?@z%-o)1-to$VKR=;gD`dzToF7O#u zIgbs{`FSS>g3+O3*Ipd)1me$AOZzLe0R^#X+i@Hg3y=ZzCb@+0*Nrc)E+?B+`z&%1 zvOMlQp196O6^n16{7Lv(Bvw|&#`{N+j%2olk(72aDk*G_Y}aF7~}Sokm%%n+gz;e84!s9^LEBtu%WJriT9MP1UuT zDhlJv+x#j(>$lhQucS4pP0pdd<c-n1mSjq6t}nX^sa+Z@cYL*YI;M3QSNjAb>^a$(-eumVZk}bufgfO8637Nccn3q!UThtK$nJWR8a;6b+;F?%wj>&W&4T&S>ssJ=SuMR zopm%45My}VHmGx-m*?nxab7*(pM_o<)x0`BCVU_JUH+USY39>zHmtG%^E6P%zs7(a zs>24poAD=wuKYvctGVKq80PYxG+FQ>nH=Gxa(-N6BxG=F&3|Q8u<)L_)s65qtyR3B-IbPFU>yLpgGyfQlH zlf)hY@MW%_Gg@ge8A2Qq3v{j*OV>1?hJO~kS!v@~*G9JSL%}YSENV@>;dpVz z0=aHmy?Z_6t199b!W=iQLG(1l&ol6TqOYgLX0ckNasKUo%vgNGk{uX)t&DM9^b$ml z6oAsV-CW?Grg*P6@kBPh7`%sDv5Di7{esLRk1E>-4u8799zAQn()B@c0Fq@=c-qPe z-?+d--q54)vk5Xayzo8nHfd*iPfU%r_fqh-8yvMhzbKi=pN4wctxw_XsnLR zk-2xj0|V3!X*^M@#j0z1=ZtSBGCrj#a$A$NIKck^0bfOYCHNY%XqNsf@to&O(OQ~iTH}T5~rMtXF&~kz0Ku2Dmt$hpQ4~L!}@y~;$@bbt~CX5?7SC1g7{F^-i z@9SLNmEl-)FAPPb+ygDuwX|?e?G3QP&mct# z*cc3cY;`ytE2p;7w7oJ^zLMVO&ySBHFfu>spy)^)`TQ%ST|-W~TYFtL88%wU97D|N zj1SBM1IYuL?0mH#7WshnsuGdqmtGswwa+RU^!G z+<0E;Z#1QXWp%?P#L8KBXCONv+%R~}ch_1Dhp8?vETWmP23bKkt}^@KJ-pYgccbe! zT4WAGHKH+S7>?YX$`4PJf;)3bq1@^GC1IuM_tx(cTHCa$#0zCzyQ2HVkVwes$LU_E z&tZ3N(B9%e-~!GvaoA_jXMtW#;ZF|#0Ak(Txzm$PWcf#vBRq3wlPAo_liwpg_0@mE zO9q>$c{-G3Az_teUD^7IVr=xAYoTpx6|6FDjZ`WUbHLzpRxB-H7c#?--wZPY$ieSi zRh5>Rsa}m%)$i@%lm=*;Nh5{Wam+;H9@wtX+uc9s~^rf<#-_bnhh3*k7}O}z90C` zb7OaD9p(C?19%l%F1#|yvy_k?PeWc|KZbmJ@W$|5X-_7#r$RCkNk7uiFKDLVIP_QK zSJYY-futQ;_r!J@f=VRX1Ht=<UFXT_Ko>WK`k-+S(hw3ZIQ%?Bd;6^Xu+mG#SJ9h7}UMd}n z+#$)^>{Y&sC?YUtS>kU6U1-xgK#z3?P!$WZuf93Od7YKth?0BT{W4SttQIR+XGtXh z4q8~`3Pyj~cpC4HKO7WS#Yh72vB_fX=WUnHhm((cd^RG*@pTl?7rei1ArI;Pc zN!mTea<%HPd?C~3wP|#VnXR|(Qn!dCVyb>nPu|C-d9NDrhr<1PMxX5sq+LsHGRAE- zV9*Q>vcf?ieJBoQR@J;ctV>|_z8=;hVJ6?1^SgtSgC89CuGZ39%WF8&@r05hfXt%{ zkUM6)YS&8f)wnm_AG7;hD0ec!Di;8C%xnSAu&#zL8bxlx-(K@ACu{~uL&byjVX%H; zf%7xe;l13$Cyw>xHrhppitn{uQtI+M`>5qHTD$z~3~F%6<@5(5uUhUj%iCMacet_- zI;5gJreBu(yKpx+Ki&(pdepX>9+hQtFt&;-Nv1ob3-YrZ_Xix(V@&ZqXF%{RpNQjv zXyMb7PX7Q*y0ek8mu#RI-2ppWY0n3m^t*NN=Z~!8)-QC}cf#N3@|>jLdV;%16%UR+ z64`jl2xfWO3#(}sSf<(-ji);ZJyiSGR}PJL3I>~I-~c-Y20)~c?sIeK+P0rJoukP3 zVYQXqup``_YtQ^=ZW`M@EAaHXovc}PZ!Kq4Bh`oR5Pc1MM3LPfBpu$>M&?A~RD4(H95T33ViMAlz!(PbR8G0QBL$3BYn(AruHT*U>#%$~0j2?l)`KsfZzO7&Z- z8)*=^j7Go2PyYa3u#SgsaWC#CP&e_7{d5 zg$2d~mdgS4@A%iGTxdB(i5M0>qd%QegG#=FU7lJ00Dz7u321!(0H}Cx#+rT2wXtQp z23!v;62yVPA+or~rYq32PYDBYH}=MrGF<=+Z0L%6WCmT>2EDIN(r*eEHd8+AbF>V8 zHPKr5dscT11+KzRSs(feVBOCui^JNEl^5Eqt|D7daLY0?I-dAr#y+*FU@i3pW-}(D z$ixkY;2hr?Ks6gKxVf_Nk%s^jW;uDaL48cv-M zNp0lRWo#Xwsr<L*fgnD^#ul28zz9W1@x$%svZ{^1gqzB{? zuF!q|0R43NMRUkMX^#|5$6RJfN3A0J(5 zjdK#rgfg!I$4|s{6`6UZ$z~M!h~SQ(@;;)vZDP+<@b0HJovg$|FG*oJ1Rnl}>0HJ9 zmeQaJ^RWIrZ8-N7mDYz;FR_#(EO5O2YW#XV?A%7G$Ivj%XRiLjwRHJzt!DFM`EoJu zRVQOwh#K?Ju`M+!WFii0Bs8QKm2>T|{_tlEyE z?X+j187xm9oqG4|{iRFdkBfdCv7R9I*7K~gr|^|UVoB@9deTz4i>TVv_UoV6f8uqL zG`2UIUZjdf+&qz%Q-hzGNEPPC;0KKktv-owpvQG}Zoo4~IwUL)_he!N5_k)Ylfdg= zt|_XuinxXFW>r^7WD;ZnjBVg!@b6sRt(w7j%@dn@1H!=@kce9(x}YAtvsKO9!OZ-$ zpZ0h0+)cCo5c{c^=Wv2#kVrhr-W@J{y8ty;DfP(&3MB25UKtWdY!q z3czvCTzl8*R=?uE6X`c%4+Ls9cbeo(43@WQ1I-40ZJ`MYKEc3|UyLoNYusQpMRY+yesQhc?UlHhj7rECHO4jswG`s7ts{`5= zj@n(vD(-=>fajLr55lLB6Dqo&I?1I(jF&K5Y-rAK#4;RujMW?6W*qK1a@)Rs^kW~T zeJywJvcmS}Ju249^Guc%%#3Ca9D}|YvNPZBVyMUP^TH6pJU1G_Ng@DX!mj&|p+Z4F zUOi~`XiBm3dibMKl|(NupBjU-O_Ed}N{&5J^_)C+zF8}L z%Nt#PPSh6v08Y4I8H9TsGlP;bfI08awPyHp_IR@KRm^s}ey;K}0$M~1<;Hu4$PM^_ zbK07TvZ#*?yVSJJrL}K1=;MU7xiH}Ro$<-~R~I$df08ZYB_yi5?#JVS&)_TUdym-< zS{DKvU0UAZbAysY{zMA6pRy}MJW=0V-GpQ3B#g1(bJW*A z@UQl7u^);$YQJl;Oz$lWK(byu@G$eNwpihh6Qk({{RhK z+i&Ho&pXK7)Zl?%xtcHh6OZ#NV>+ zmmVYVJQo3R%=Z@(o;}Q;og9dnRgXjY)}5C1lG4T#B&6Y0M&~}j4oz9p{5h>^(oMUJNERi@Q#_J-YCM)9kLmLK9VplKA_Zh zdW5zY4-K`bH?pCS`AR-+{{S!;>V3YnSrhe+$KWr9{sa7G)?6j0fv*<_@7*Wahvzoh z`U^w-jy^3;2-j!Qv_%7U1<1OPjAsF1&QG_keu#L3SGtlJZuN~?Ju>Bv*y8enhB@FC zQb!%@gYh+-+76W-sM`0Pc<8dL+dfq1hB@GkxyP*<8Op4i(D;wXe+0fCd?PmY{{Rp? zL3yicGog|@D>N3Hv4hEMzTVr%euIkg4+d&p3b$+fZ9~IW(#L+zWAlk?i*{}k%bPow z93Br`=Oc>iz9Z&2K#HUwlu{G3N=6hP;zm@NbK)H8?DO%x%2X z^8~2ENS!;7%f>Bcrr7BB@oMRl z_I83$uOR*?iEI$V`={{Dd(VPe$HnbEv^U4V-YnDG4A(KdQB2%^?(q`@0!S+=jIUm3 zDah~@@aCDS0e4|_1^u5T)G<~b$GA1W;oW=1e+_4r@4+*Ds@`FXiyM%$qetBca6v*k zjy|>6d_?$b@h8I)e`)xa!*g27&Sr~J)5=L_a1IVu=G{zhp17Gq4D~hPb9m2P)Gj{R zZdqE;m1&G%Hb-YE^8Wyh7BgpO0I=>)#kCNhrW2pL%~oY1p1PrlU{>wD~wFQV~$2hq3BmL zS{;U!VR?9Bvx-8gHWM)c=BYivHT5o=Y2pnQ%G<-*mxxBArO3EjZAC~K?9t4eqmOgV zcwfU*v$)if=I9aS9IKDvKDG4ysj`1E;_CR$Toq)%*z4%Xct26iM4BO=IC%HrM}f8X zx`GXI<4N&7pWe5+B1k3&kYj&(`6~CrImE{#EyXiu^TatVgy5EV1&j zNI)R=*(Xts!=-$aFNpX_hv^?%k|)Ij$951f8Fa=A>Lbtcscm6+FKp84(O_dLZ6$V}yeQJ@vxI61GU{uamLch@0J21SmbZW2i}bVv;rt+rCT?c^UjGk(>=^ex2*y z571ABf3*BnCB>D{D+k(uQ#Sby00SF(p1+x{`@%jP@a};%mVbj&leX>FO+lwN;X7y3#s`2uk zcIVcSn>`}mTksUtvRXqVS5Sr}EyEQgp~1mmHxPT~op*g5)N@^0S)wq?!tyGXRK_{k z*N(jNUo`5P-m@O5apEl|&hFCQ?Xx|N>`JHr<8*Q+K|THZnvP!>eWD*G64S~@?jwp) zi5A||UKk+^0M zpa7oXK{*xBXwY8y8|HI$wN;pTSZtoa_XDPDrqgwY7xxyiS;=J#cnVt^oa2+;gf$YR z+I`NIrZvce$w>Gc$K5Bf#d)Twb>qABhTBVcq@L~e$K}EMv_aLR%Z{G8t^G#!=fxf( zmJ8cknRI5);l!Hz zMdVuqwNuHMu_XThvJ?*fxvwv88o!0_W6~Pt)9p7Wca?c?6_r^CG- z??azY@cpf>iE#L6Zf)(NCMRFI+eqXNpGx_wS-0^wg7v$P_(?oTCA^arj9gl2P32q{ z=j42qR`mlIuc4yxR;zVA#f$8<)Dc5QVh+g4-^2?H9D5p)&sf#%t>?Azb=(&aM$Evx zW6L?{N+06)6pBaBJ}T93^!*CYREA5doiQ-2=f@GBON z8{CCgF^H3J=^13m1bgvb$*Xv;;f9eMlFJpilO(T}rZtg|TxTdh8u`=27vBui%)O4q z<9W^srl4QT4ctV#LHy{r(z)fnE%6tH^!-+7M~Bbat=W}jH_q5S3Bqyp9V>#f)NUZV z8l|#J6RvijFuJKd2nV?AYuj|M1bjAIhrGIx?_;=5JnxlIp7{<&f6gnfwf_KxccV-q z(_)TR00659m+{D;8nNZNFT)K-#WrcG>(|!{1;-(G63jZ1+54l@iuJ2c3wUS4Hpp}h zHr&d9W!P_Xk5+0;N5%Tv@3zr=J$W!?+9X^=tPiLo?*28QqIhq|I{XoRx$U&57~z9I znCYMP7n4+&H_+v5{86ZC*HUTMwyhKqOd&^z?m)f4EIwbty!YZ4o27Vy-@}$LNqPWR zSmIMGj9BnH^X*?HS)Mj8LcL5jKw&ysnWAQ5Z8{mAfCXc4atN70A z53<@Lb2YFWU=xreW79kiwVIHwc*ny(f}SSvg|u?`k4vAzb`iv-rMQfFta~aU{vthk zRZkjxCD6710F53L_-CS7n@u7h9{GVXT*;nU=8*JLjsW0irG2~M9b?2kJkrcsy^Y?0 z_TgJ}ff`0<8TnaBP)DI0dQ@Hm)BG{vYyDeN)a)*#@g2)Bkhy8vQ zdD+xSrrGFvCY|AJKgzSUNdC_V;S@%h&IT|te_FzmPiQP9dq>Q^V#G@@DmczYJ7TDK zqSsdO1;mYIq%NXvV|0-VgfJ^`%8W=ra85`En(!SjRq;21{7*K8s=d4EvjkY~KGr6f zc_Rr7iZF$deo)KKI@1$p9r3^8PKkZsy<5Q-7gOkZ-Mclc)@{LHTZu>R45 zsEnJdM2sdf364_4hQ~a01E&@BrLTmv>nLs4PPB%~J9xxuu`a>4(*uuwloF&-@fL~U ze--J?p?HeI+f=oGo6492jQ3O3PoW1jkvsK;vgxdJpDSb}=}0ibN~9|rh>J$ftO4eI;s^=O==mb08m zf;lOl;XR7+>0Pakh;(>X8*!A6fUZe6`k(7v7l=F|;Qs)K5JxTgCDqIr@-E^gJD3Rm zP4M@RJU+8qYL`)K)*;W7>~`HOUAJ+EB7j7(cy~={WSOD!7H(uom&`1G z*=*!v(zKULu|`%)X!5^wlo=Hw#Ki+ex+2{}5~O}z4Pe|`c;?hkb7gUDsY4hBIN32d z^$bn}anO!xS_80zvWy<}Z662a>0EV>i+n#c!pBj)ipKk+Th887XWM==_*OrNd}(WD zTGPVuHnpfX8zA|jhu&E_06hjt>53eRN1^I^?wg@$(`uTW-c7x_mUcY!>^({Jub;oO zHNTBl(CW9+9W%og@&v|uLJY*7Y5z938_W2^-G!R*jb}|so zN2wKeP1e)Fa4wUfIn=cohdBrLYjATikexVJ?ZGA39)Hb5G^{$ksgImTyym*1oT@*7aYDemb{~KRVMxvIR}N zEtS}q!I0x_PBDSdSCafI_#fiS{W;p=*X%IdA$6KljqG}0b;rGZf8ehLf5IneZKl4Y zw>L1M6DXH#Xvd&bIQ&V^wP={l%}VYq8&96?MkBUNfzwrtsF8qgguXu@yyQ zBW_~O#Qow)>S_p&nHX@{Q_{5MyqtWa3_a^CD2d$^A1s~9I}G&{2(=rGVy=np>}{Un z?ok{Nsb_aQC>_bHgD;o!dRLt5)`_fY&`IK5V1H($WrdCecI@lXo=k$+Jrs^;1*Yes z_;1EKZ;NeaztRbNIOH*;jmMZrQU|4VNRZBfWmRF^-WcqXvMmJ@xjTZzDtt6XlGN?}5!#i!q=jvTGw< zx3iwXfg$m$9lZO3AG zuR~dUU!iJ^qxd^O*88#ZN8a3hF`wmMI$Ua+ABX%x);gpTTFx6ja*W5g z@_u#WKF6B&8%wC=i6*w3%8oJ^6U|W^%+#Mn(yp#Y+HJ&y3=y}l^{$ssw$m)ZNCcMW zwi%8-pqze{nFgzI6eT6ZfQ~l}*sB&=jilv#^uZr{9SJ^zjADT%x}6%!ZsaPR#CK3f z=qdXUICU6d+*dEB&8cZxl+JwJLek;BKmxFf^5+%4JVm5=raP7}u+13cx~rvG7vC{q*jee$F-HQlBvfFtgPH`-Y5hVI#;Qs(x^UY6R_(c`elk3-3aNgrDysJsU z#sOTDK(2h7r0YI4)%7E#uZJ}o8R1e{rTx@xx6#SkbL?wNT=Acb^!pXLUk}{bJYTzI z+AboHe|vyf9Q5a!_3Pgid<(Rc+*xXO#%$!IGDz^BqA}Vl3h%~03hv7RuiV5Kbr$U# zkN6Td^q_YQ*4lBqNQd3|BVZ5E;+==idk&DE9`PU_ z*>_Of9B0eU8~*t<(Ifj6`QH15~|e;WA`<5Gqe65C5GtT`X(@yGh3W}jj42VAtg zossS(hGhz{DDu?^{vga){v#Bu4x#mQT4#rC=00uGiDl$$%jX0AfJaYy)v?laX941v zGT@vs*l;_Lc^{2@buWngMSmQz&eE(hbw-|2NFJ;lpVU`LqWIGLMzd=xJqpCbAtpeo zQJkKo-*)Ewb5E2`S3azQ>%++Lt+c5rl#rzXWhedN#cC$8rzmJG<7X;xS}6Bq_Zd7_ zfm?iR)@|+5*4M)Naufh7J3A`+VFwkl;opn5EvTg4BtBFw*>$!-f;|8|1r`zQr&!gD zc(BtpB8-=ufyb|4D~;AXX=$gan^x7Mjnw}DsI@+1xcoRDoqEB!@W+ibR(m^^TV0%^ z#Icj<^JLejqGD^-}#ytmm%CPYSI=Cxjk~0pf=urN( z<9h!9ioPvg-Vvc_ms)+EKI_G~i+9|ArEyYeUllcdPBW=mU7|T2V1S5nx#tb{LHg9( zY6qwIr&PVyFJDE4lFB%KSDog-8RYOVPCY4>nool4?jxE_PwkfohcSoW=3sMxJJl;6 zhml@Q9Cx}z_K~RuN$##h(l$E%*3I!otf^fs)#Aft_Vhk^%d{TNtHw zJr1d~uLSE>4s79D#Fc(!2NIz50P+a0B)a%3KBmIw!)&o7vcL1Qt#D6Fl>P>sZmbQKowbk|gNnT6a*$9ux z<=H^t26K|fsXXGK{@3`gt=ow0v}iQTYq)?6?he!=1mU^PJ7cXk5&LG*^NfNWq+2(d z-2hSZepU2$!EX^>ct2hK*V8m3s9!^ABE@YP-zz(eZgM{8_Um15hdd9W=&F|zMzh~C z;z>yA$G9B_;a_rm8`15wjRsq-F_O~eP{9TUg;u7?Jxtk~$9 zR1?6CE^Z>bM@{1-Hd-P18JO9nI~$fu(D0un95M7C8erU#s(8 zp|4uqU)wdM+>LguerA?Jvh5L8V*IrCdO5q(FSQKsydT>k-h7hN&U$ zRMa2saEo}n%V?@v!NxAU-#Mk-^DA#ui73G=)xs-wYD$<7X*Zq|M zS6@Gb{L6@SX(BT{xyqf#0RI5HoPJ`bxBFeS+;^F8HYVJsJw19-w3HZ$3mqtTxeHWORJu(+6NcAGJ zW4XT4Zlt*Ju7uMSZZ!=U#*%IHXn{u~*BPzdXG+xdDI#4y^_3H<&5{l~3|6I|hJ!|} zbC#KSAqgUyPhxD!nkU5%vg$VW*3e#?IfyB>URi>UrQ>g(-{lQn;RlLz?Rv;w_+D5w zh?L>>$`#eSh8W79Vk?f*JR4@gXO;pP4)u08WMR;$9D`hrui%{%Nbz2s;w$TmiH=@B zKG+nNGI<8&kd4Ezf56otIJ4H}(DeOIQ9PEht2x(cR?-&B2JrEJP*RWQVY{_3As3y&LshE56H4(xZQ%^UiDtj#CLPfEOdmB zMdoca!*=Qk8|qIYbgf3Fsb9`ScYp zV@^}smb@mm}ORV@-9T{ZNua2Ol1Ty9k#yQ-m-*@T-7cMrr0evhXg>_~j}1bu*IG^bH~Q;| z3qvmM$Ts7S*u{La<39r3={nop_(lfRqe4kRv^Ti}xUPF0agoqy>*2`|P2#;4TcnVN zGg>$9*e^JdMj1%{^7CCy_J!fU5NLAhz8JgIZMEGsa8l;y&r@hQ*%a6wX21#CFDLGU zkzQ-2c#hn|EuOQd-sv+S0Dy$XPfk?!&sy|<4C?l`S1YXP`n9xrox3mEAet}SOAsIx zkesV4jt&NYon3+~=zIa zTd=g%CM|(BlIf)Cs=n}?TV0Oe96xIEZxdWc;13s1eWiGM-si*mv`ciBkTANpieLF@ z0O4I@e|?Rzo$cUWD?$8;abjTXN3=PH)2FSm^4^dJSSTHn)RzaR%pBz zsM~87R;*a*_lN8{m;;;}X>bYmQo#1FOYnxf;7<;P(!MeHTIa)(WCx$fl2th4Bq-p0 zE8VB~iQ!#3INv!KyF8GJeMUAOkH!VOl_T8)QGcLCMC9ws4&a9`b>;RVNdEf%we#o2KO5-& zBDGsdba|f4pP0`Z!ap)NG$TaMii8%?Cz}l09E_OUZXZBuy`PA6oijh#_qP_l(a3iH z0N*_;w($;wqlNoMkS4cQniok50tv07sY*z@bFR;R#r0SsyJOY%2;}0JI zl3qku{n7KDyxc%%n@ogj z8iaya8C2vmt^w|RuzGz(eo*LEmpWC%*7J!YA<0%!dLKpU_}9_?6!^2^Z3Y-DBamHL zMmG6!fDS+205|JW(M=zCX&yQkdIW67-t}Cz*+yM<6Tr#uj{)I9TC6rc4tH0V# zOV1==7GwR@90eVPa~i(0;#(_LhS$VVs~i&ZK!lI?Kw-{E8SiO*y5gAl2f4?IIQ-vM6 zel^?JYM&1D$%WU5b=z%6RhQ-jpj;8#abDi_p+Cbvk3KcBxV7+KfUedMyJ5V#c&zP? zda)BoB;&9P&!u;M2K|OUE8N-1aq%-<@WqgkTXM8=T}+++`h;FSri6u}Iq3C`J5)n^ z70OE>BqWJ8)=`hTyyHKGdEM@VZ+mei&85Zdgs9<=&Q{?I{{VPrf%G-(_n)(;!A}m! z{f)0{66+I2GG594%K;VeFkPVjH3o&_&l!AChD}f5 zEcbeLhQujDey*n+;Hg$|{&QC-g-P7;?-KZT#GVia>eEP)?GT-|^IPO?@3?NrJ-Qm@ zAn}ZrZ5FNKEd%V<6G`Q+$V^`|U~N+1WQ_F5uVL{=jC@1k-F`0y>Ds2BbK>cOnC*7G z*&B{G+)n=hEMWD*sVBF3=rzBF+ONd#0!!hqiq@{$wY=t7WYeTD0V@5+L!5D*;|CeQ zr5KrW95vs@J##}b4+Lq@XrUJ#WUcmz<;d#nMg}_pj8~Em5NqkF%dA~pL-vcOK4r)& zy;%3bIRIDE-UR)ZyaVCA3IXB^X*KOnW@VE0c{cAn@Tx%LrFxB*hI|E~TRb*?7qBy+ zz}au-6#BDg_2!#^?sz|gd~M==MVT&qZFIJ_2tr!hTeOC3!R!@R-JzKzD zHP^MMVz?R>rxZpQuo5e0LzluFZ3p|@liw65SVlL-4;p+-_;cWRA(^!68;i$FTRV6S z&CK~HC4|H%3)_NeY3!P2rG0O7auJq)HF1ssE;kTA zI=cwP{g=K9{{X@|vUt~Bn&mY~WMHwhgeXr&jC{PFbJSPb6Fj-w!iwa47h`v$cxuN? z)MxYOw~u2;MhlVL^VYB5Yx+i?3te7Zh~tktvJOT% z95xR%=4R(LfKE86%u|NrR86=97{Uf#N@d-Xrnjn@jhp z^8m=>@~<+V;fAf@InjO_c%lS0-@$h#IqH68>VB(U{{Z40KjJ^cJFATb#SVet$jK62 z5@Wcy+x!uyBq8o=$+b^~J`3=8X|DWLEu_e&48diScj1Fj%SR8Z`0wIfqzxa6JV$47 zct7xp&CLJ>2*qnOc*N=FsRF3;o zad&hsl(5y1*_$Jgmym%`5l{65pHVb?q>qC;cmWtExB%!G^;R$|9!{43J+{{Za& z0PM@3w`4}~ux8xL$5J;hBR%ofw&e>SHT+8W$EaG|U-)amDvfnv5NnCul~qHXyJI=~ z`6JiA6=Op1^I3RC&d=gBR@br!)ykx0jC=Vi(*`W<&n=J%?O2wx_>OrOOwjxdrsl?%Z*t>waFVLW+_u))O(98kBDB(Unc}n4 zyftRFnnjeJXjI5gFpuHSCq3)1x-v$9pO|{_ir;m&w$tK`RZ=8SqiGvPJ;iZ4uDhaI zU5z^8_A7Z@ZVMx-XX%qvE0Gs6H$2kG0&ZDZhUFORfr`sFM$u%P4?YkJZbBU6*aOef zxcM}R{86es_M>-k9ilGL2#u|ju72ss$@ioYW|xR!@idW@@a(pwToA@k#gz6d*#0%m zS!hplZ#A!qZK0Z5jib&mpcxX5Qnc#7`LTmE^dUY?lZqR~DP_?Jv=@OZxV;EWKn zlduu&r;%OD_?Ae@!Tp_n&Df=@vi@R-JX@$K44PH*C$HJh=|zV0M&^g%zZhAz`^|sM z3ydUj0Eg?ln(r-V*W+I*XGzBHqy!*)W36$PJ}MHA-@$QiM^PjtKgPBb#X4X+TJ2E! zK3D$$Ld6D1^jKw#F5*92)#R2pO^l(`^#o*oM!8EZPTF|4MB+tm>OmivHKz^Qw@#fi zkwHnFWDfd1(KNew6jp-_=nlmW2JbPi9Rv-M?sO3?PBIp{1J`Z z`V(F?;vd>S#1|$@eFD}iSV+Ri!!mvYpr^`9XVJbd)HKZw2D{W*AwV)ikO>3QzIxPt zJn3>Lk39yorTQG`iF^OwRE-erMkS81IG=xB(mqO zdH_A@y`HzO>NgD?rjL}5hHHz3P(8j}ocmOoq<44lG*)7=4Rx#{vfiAoM_hfN;$+c{Qm%eBbvugh%kBL&g(|Fv~%8U zDre9!;F{`H$ipp1e+|B+Z1!4&OK}99QTYa%uw9g!#oB$o=8^|cJqXA@%O8zvX*&Lo ztE;t?q`YSgr-CZ9P+CK7Em9ToK)_67V0~*o(@4^+9p1*-ZQc5m;GeA;4(9f+b2X)l z+}pY#7{faNpy$4GRufsbXqH@VRs-i;6(n`W-lIO1&T1NTT7`s~e3)pYAduPX>ygb< zlT^_3W`f>(g@#0Jy#-X8QMWA`tQ0R++^u+VmloFm#kD|-yGw9~;#Mfu;u_pti@UqK z1ecJ${O6tf-g)=FWF$LZM)us2Z|t$x+H1|JR>nQTb)NeVV8n=){k$HGFrvg+4hsONT@v2469K+!x%yR&1^9H1h$qR>zdGApK)yzuwY1_gjfXl7cri=xaR`xAykSJM3R)m$#-Sx`l0WtEE1T-5X7tza!d5tdPXNj_k*60bM#-ujcrF7fLQts zmn-h0PyKNLt|%>L@7%Vo6)KmZ77sp=vu-7!6E2>J!~o&js?Oyq*kAetB(C$>tHKe~ zEO1E0Z8qce^W{T&L0b4%oXpVI-hdT~QCwFFwEJxP*+}kAK$gztN(>c`2^c|h zO@azWeCOM4@raF>n3Scu`LilMo+4&ecM?o+T4dP{_uQ8+47>(Z4HcbL6rkaL|#=FiLK8O zU5RKKd$^ZsWKd|uAt7~~iS87`53*G;;T@5&Yjs?OAsHb%^D8iQ&0HtFRoA=svwi;W zbF3IO7M)}fVs~N8E?q3OFcNS+cBMBmNd)I{YkMUas${=m9k$tYFRE{p{#vMdxzoHA zU#?W4GK#I3F^r_t8pT8$@e?cCJzh+2O)^A%MAu_D*$ zE0r2}hfGATAyI#tkQ4(pXax>IP;z5wYg^Jkr%`C@eX+ra;7VZ%R8MCOS}gRS#A=yq z7u$N}QSFSgzB6~goKbxl{?*LQX?H80T4(FGUFkvRxUC?aEESrx@nvtEETDmGyNfNl z#g^h6eBtm18EHaRs3e*CdY06yapzQLp?;X1p@9>fEf0aU^kq9@!vv^*B-6Dj%H?Uz zyRh)y*}kVUg~+=rR5EJw^%7DQr&*h>=7xl~h0w*)b%iI3vkm7Y5GNZg-59DYz#SXz zTODuihlM#$%>q9+u*$)+@z_u;Pq_O4 z!-Jqy{iZkwWrzEHm+Xr0!YRBdx=5EHDzTx9l_l2C*+s={Lp%{p*$18yUT+c`55)w* zURQDvcb9Ob<8+T!WqpQ@``P->qcigs)F!rIgK;{jxh zqD_&q)y)^;Av4XZ?EKnujRTI<=mEafadLBuOSwzVW$U_+A^o{RW(+Z(W-d4xss8~m zRH${+*FuIA%l|x1ZeNB~71z$fsBCeJs}n!C6i)h#mC?EWK`dxct@U`d=AMMf4x_{Y@J<#r7KEDPDr*HoeRnz* z73@vTzA%F6{_0>VkkHMdMxV`gV~ApcT7D-69F~Rc`LQOoPF2>A2DVoA8Wj2D$Ph85 zR66H*`A*s%1d}+vmFS3Gr}6jM8~OpGtt+@X2r1E1qBw6=921uxvw7)|V#QItt10yY z%T0faqu^TDm+wi{DZPDO5L_&r~0^P-E6o0t$@;OXUuH3B-BsV>|8T`EjDvt zU+rSbgl;W5T)Nw9*pAD1)>i<>xVr+&Y!;o(`lmdjOs%Ps(NTi30 zdfy(Wpu$hnLrKvRk?L7Sd^81oP?o8h>&-gzEb4iLM#1>j5J@~%!W+O#H=rwxHM#|2 zw3qh4&q=LYg&U4+P9f2;I@4xv-g}DDw8Ge;Yq269marecSm?}YDi)hEyP;Pe5!;)+ zyrTP6fHK=UP9*o=9JH!s7XN!^xhRBw%B69er0Es-$%rk7t)ml8hR^;LH^q1fm7-OL z%x@>(-i`w{N*4a)f_*b2$}C8zAS#o$PG~!4E9(#@+Z%BCV@ul(GF|Ap1$;k@3qK${ zJ9=Whej|}6#_~g)Xd(F_{kb55oFcK;8?Ff(RL*VUrIuUt&~aBM&-1CJivr@;p$fT-1V1d0E>(ATc^z2LD{d^z9pGYL9Kj2;(Q6Pl>`F=qAA3&>m&hqk)JTQsS(A`+bv6OtVT85$q)AEOaD0cUko%hhU ze`1{kpJXhi`9)ofOtvX&;5KS+VW zP$U^0H&DJCp1|M6<>`(D{!HL_$zL0HhPgvWz4pF>GPRwop zn`eG%JdIgh`vy7K?*s1sCJt{`R9b7{-Dba-zL@OFcf@sCWN&HriHjjI*44@}GLNz= zk;D+aQc>$0@}?r2p`4jGvYP^$Mg7dxaA}hioQ#`psxRGTm#$`JTpMe$8lU0}M1syQ zFIYLh%<%fD)Rip{`3`ciT&h2kN9Vk)KNsfhF>n_~rz-w02+m_RVq zM7RifCP?YZAivf|eQ2Lc4zmKiT5yQAvFbZ%Z02Z@u>x+kOR_W)Ky1F5`dO1`B|N2C zFlpnx)I$i09qe=Sbfq`C>CA8W1WLpUi9&4C5%{X`<2L5Qfp50ihM%}zkX-BR*_>Z~ z(J#5stA#D6ls`{r{o%R}Om5M>MBEy_k|m8g*Sw;-;+hJk*k6MPf_eT|H= zT^WoiF8=moz$wy!I zbxyc=fP!Tj!)l@GdN-uuGt%j#M3@&iN}T2NIdtHT$tloYGfEL>SOMlHf^d2BIEeFB zpP@P1e&(a3{5ARWAq8-urT#Ua&5e^UufaBBe{Y;OEKu+)oAn^k-M&hG`uJJwELomg z|HFa5pQLA25o^cZnzm)mB3`yW;Tzv7=TB$YpcmBpPmdWVF31lO-Z>*j`A1_# zmH%@afHLFsdGY5Ye@*G+fr4O@^0#5G9{OibzI)0bxN1a4Fz0=dyFw4DQ>zHK@b(*2 zG27`gsL<7EU*f^4YHh3Zr6HwzNrFntNn; z?lAbF_*GQ6W?AJi8%H64wkSI5a)zyd7^7N!e}h zTC7Gd7aR2c`91<`9Db`b7|C8}C^T8G6QbHBp0ANQd#>S&cSoGvTQQ~*BnZd<+`X&f zlPQk8^S-!~52}mV3o9hk>dZJ-C^&XG(k?eI)R(U5#H^yX@c7D=#+k;n$=5_!J|f!k z?&GZ(OF#ET?~2v?nI#-{R1A_`sxa4w75mC-Vvh6OX7#~kb(5zMeIgj<6nN{L{wDV6PbQ4i;pXPlc zRoIvjpimN(gcb8;!sw>%(a6+8eOWJtwpz+6uU32BS78-}edEsxo}wdLA3hX#4F!w6G#!CL-EXe z{!B%AhPV+F=jl+}+)2VY_OTE7f8tfSOx~G*tQQ@`4c@}w_XpDED~j`Te18C;5o^an zAq(wY&kE{(wA9oqLOX;%ws6q0qg6gp_*x>>MPQRs6z6OHNQ-aLZ7j9~p0i2zqOoAD zHSzjMxTlz;g~#M<);tkJT>V>PQ)-Wx5s9o=Gw&JWWPQ8Li|mP~&6Jl1f&~tuT%W)q z;a=use;3iI6~yGkg8coTpX2 zIzf;7meF`v4i5sFgnoiBs<2$G=u4)vzTOVspLmV)pY+bB7R+%JrV3|YQ*;%vG}Inp zdg!hcoQcH$x)~=8&sKCg*2i8V7 zBjb$nudMG6yY<;>GiaKdL!0Q!k#c8(jwTIjyXxj>@%5o6epdl3OOb>~XvTP*XxD)E z`r~Vo9>@WTQBZ;1x3z3g85#{$fs5lui@-g(DT}?lJyMj7%b%_$LIc~ml#cAL9f7`= z=Fge}8_baSuy>!FOQqblwwPmo=03g$6q@?-`7-)3I&N!?Rn^36NbW)^#B>H){d4}1 zNjg@MrQ(8yA8R3xIwA2QKw}7kZ=BjW>2AR`-^^{=ZPI5w zxi9IoljtI^s50-e;b6a{RVOQhQOK}34Fism?p=CQ3%RB{>!E)t3D_y=_^u0F>*uyhO- z*}ENcxU1#3d9&heKkOz3%Y896a)zMxxekPOdc_2|t8N>DV0_c|29@oS1hLR7Aw!1yM1(A&kxaRp085xbY%Zn2JCcxo}Eiop^`B?F(#fiQl}0l zA-`a-+etazAoQNYs%v`xjyy6qocCK<-lr{hR9b;P(8#HMv2X&qJ@OUN8 z^g6%3re?PO5v3yq4ITWQJlDl%-cPBYR5l^((o%CsW|GYh#mjFoj`YMJo}plNxrZzf zxx&SJP!+{>QXm3M%cJy~Pk;K59ZbHvDylyAUao8%q+b^mt!I7COtD-oq4>A?F{8`` zu||rb^P~Smz+k)V&H-UUjNd@O%BhiR>b8onc9gM*MX8p|NcF zF?fQ+#^ryn^Zlj3`8xWR^)x=xQ<(PDR${3i6VtgiEEUe48hDxs*?h-Wlv|bUvGDB6 z`aAxP3FFDtU_~Mdga+o-q2%+^(ak|5p~a6pAD$FRbXq!JC~~2Hmgu7twz@qc>R$1_v7|lVzO$63APm|bvb!U^!%m0re1;&?@V-ow4bPAScv9c5I49qN z)6E|Pc$OJD>eHBmVy~GMgzng1Z8jsiwo$Lj`KrLh!=7F^Jks0K&4(nS{)7U|<+U=2+3&+{Md0!(9;(RiS1us{rnQ8W%cm}=N?#H?gxc0iwI^R#jpvDiMaAs5U)cQ@ zboas%L1Pp#ImKfp9g~HihpqB>EH72<1VcmHMU_z_LwWqJ!==it@q7iGir*EGOUXgF z7v5l@cDR{ZT1@I0AvMD?SqJ8H#xY3GFS7?*&zUrsyk=X*{mpu0?Mg+sL0|cn+%t4Ur5T zBiqHwjxlGSGNt){{^c4c3q!hNEU`AhX*gG1Vf9_tSU@BG`ll%){vkTH_@-)N5l-pP z$7)iiP`YGdfH0X>8!Xpii10L5&(zX;Ds^V8KJ0`*trl=-*~axa|Zb+uLPvcwvB3gs8;IgXCdd@S8c(Bs{8gK)0P zXCT79Jrqq*SzE(ILi&kf9aerMbjwOzte_r_yR=Ru7upEG({p%?6k~H4&pt-J>Uw~~ z!JVSkEAre1{fY8|{j+Zb#Yb2PU~}ShM&bsx27e2qO@1Pwen9=YhcC%<8>4&$b9SW2 z;uvY`n*J6Wj_Q1H&6=9KwnC!6z7KF+!>M(c*|D$l0>~HcA&W-gr*RvRF?jZE4aqaq#Y|>m9Pz zy8@rEdvKXvbvRmk@GD`|E~LswMQY%ZgKkcAPU2?5&Of}R#X({zoot=!i@g_whz(bd9KQaLkjHo<+x)H*hAH9C#?2%Aw%xAF59thDOy1BOQc)?< zw}Bgdz$j~(9jUd-Dr5!(0KA33Izre|PMxU* z6lz6u3tJ@e`i%Lwk6)AmR$}ROaOL8FLSLqCW|EQndOArUjcJ=JE`}4011^7NBt+r6 ze4zo47)aef4%ysz)(m}(6M@lZ4M`jqqGxT7j1sSOwcL^UcDZ}Jtjdo17_!h?Gc#@S zUKj!V~y_Ozgc?{Mm1 zfOy2xqLwA(W&1YCT&>CXZBI{OQRuIWI z^e1<}ulRMj{L&{*)24TKy8iy;xck$dEKScOnK~88@MZ2`tepALFJLq!Ldyq;O=1u= ziqdGPOrlO z=EsKMXn(+oG45b%pHUKCy*KmCdaNr~e+16b^&4wxS;e>VVmj|rXUSkvWr*x%Qt+zv{V@a@dh+q;NfHrFrQBWj9dPy4QK$T;ArmhW)QKM80vZqWefMf>yx8XxRuDI2(5Xp>k@1zD z>g7RSTU$qa7OiN3lVjqe_7}?8$v?EY3qLb!Ai!V{kLOj_4r^t6Wbsu|h>%B!(tIVu zhk;JDQaa_HD6zNVS)Sl2TW0Y^L}BhRUCR&HIL%d_`n59+<03CS+I4Xkn@;vs*siC| z@8q^@Cv>(sBfkDRCuO*U#dRl@+q#{^+~Tyu>VILFxULv6c(7E)1HpHH_@YzY2lzx~?b_O3Z45_bea(bSCjXe@n7Ol+hElZIRNFcA`~EkEdiCaU%`{{; zaGX8|K~IkvecQL>+9}@vA2XxnTB+K+-dsuz-IdgM zh?6Wf0HeiO;Us0U(;W60@y{(B6bMXlaWZNlTaJU-rrNT#HI1^!7tL*`lvy7bJ5O&o z)vxV;i)XM&{4Pa)I1C|YJwuZyMNAC`VYt7DgWP8W(`X7#&}BUaT>ftU!m2lT6xb1n z$RlcPj40J#lXUr3>y`~5-wT5~(I)&@FKhUgsXj^<@O)I2q&i3X2Uz&i4MHdbNkh)p zYnQyAOQc^)(vk-IPShnTIl{K#xIG{{B4zD+{FT!hv25HHI8XP$5!L)fe{n5wgT^8j`%7$J=_us`_ zVkQp;JNPB=9&P&eo4Nuiw+p2u(yW^{-+?&I9V|K)*#7|V8@{2$iE(AkC}UH=&mVFD z$EAmBYa2%P$WQ)Ol0$3vgndli@#hbIvimew=Vc0w8!H1^*}I0W^o2i@HuX<0{YAa- zreMd1ZKi89bT{+?EIp1Z{C!_?&qx_#oCBBvq4CsPx1!8t80q%@Z;l!fbae+jbRMg| zSu(A~1-C8n8hOe$%Db_$zh5&4j9DQ2eMT5?c}9%_8I`XeYE4zSjr!*ew{uO}2_i+` zKAl5fKG_Am`9$J|N9pr=A@r<8&81{Up!mTsrp?r>$KDQ0VJ$d;|fbEb169|l@@EHg$sI}+HbctMyd1nXQv8M6)^|x zU3)d{eBZNupS&&GmNCR*)I57WyGUtjX?IV2tS8`^OKBfzz8ykH3Pss7b;t-oB~`IszB!pDiD3(gBs z(*VBSvKqe(z?If}1UwTFyUuQmtt+9%S7)X(f1|RTh!G_e0VkJyj`-aIUExLQ=gwpS zEQ7g&PWo9V!bWGrFq-#w(6?Z`xlUHwMXbgd6J|eI+mLw>5Nu=q0Cx$C$?irML?zx* z7DHmXJ@gbfbA$l<#*7*giZ}KKyTZ!LQ;p-eNBvZLGG22D<+qI<>f2dHWv7K-&-f`Cza zsw-S|Lw&#BqP5EA#7{td#6h$WNs|r3Rp3V?!Rzcr2`RW!j*m?K>v(p`bQmC2m!I5y zc=)#L<5437y6FXeXsHA;2Z#PB`*5qDCXxo1I&!o$;a*iv?b>ixhaMB&J$0IXM>d}1 zqW9NQ-%hR8aK)uslYUirQz=I7#mx){)6w|QDpX#^Bn z_fxy0PU;}N6pJo!y@-6PH;n)#eS%`!^t%qAp9j;&`fTeUiMOklFt%p$sMy-$ejCMI z`j&iK=DgXS2tUlB-P*M-~H)=!#cUGSZ6!2^|yv{88z=7SvxS>`NwRU3=)Oid^2lYh+tsE*E~rr6$Y#gvjtA_@s0E5p$;s!M;8pzkTgj3@7dII8 z?rQ9Zfb}VyO`T1mk_k#HGVMPHgYal7xQJ>wDHVUWy>C6lYw6S zh+eSrvA#_S<9+Sy=M{MBDYeC9Df`^3jid0JLlUU4o>xRv3$n_wboT2-yaMs z2h#rP(6%J>Lx_}zYWHY06bZ&VEP8D`}g@)y>woXAG$%fRX%KC68vpO{V_h|Wvi5*{Hez?lApAxr* z`Ouo{Nh5xngvCE(5t28$Q}UIB>f)%Y#f4;9_FA)1{%W_a_JL%&O}d1^wph7 z)~Q9KpCsQ+q62+3zQ4+?DJvLV2)8HmzzV z?UtXmEJSd2Sf}x2ua?Ks7Vh_Q{Ix2cZYhX!`Oef5k2AGd)0nbs{Hc8-@K=$^!bt_5 zh79AH%P7B(&xF_@{S62gTrxkB@o_n7rRd$$Wiba6m#69brKbEkr(5zvc=Bs5Hoc+4 z=zE5>6&cj)XzLKsU;VCuM}?dk*A##pAvsZ`J;l~Z#K~ofpG%-Mh9Po{J1`(!^N@rh zVHFU=2KKlL<3%oXUHm$*dH2iMr6zZAyBR?T^h;Q2OWJ9-&C9gB0LUC>Td#hI1T%c;9JTO z+rJwd%x}dtEEkFS_}T^DkN;BG3xS(ua=<+q^6)gd5)&^S9nSCK`5@gW`7kNkdC~N$z1~2&MPZH#q~ISBH9YuJ4rYq;Bweq*29cHNQU33$~+~ zZ=cuMP|_=zu(FxkmaHAl+JxlhfhoNTQ+9TCtb>MW6*7XDN~tqJPV^=xDNIvlnMEAt zi*VlcI#ZeYm3&J?g`#WxD2iNe{^;*2wF`!{COG}b)Xmk(Whi1kD9QZ-5JcymgN{@>Og z6MEZ+i{{}3dtWe}LSFCJfcpcV7;-u|1dI!mauSRG0m`xy<-n5=PJ^_Mxn}iII<=@K zlLtaj8x@J2h?x32*5XN&s(==}kqe{Upj3w=p9{$_O-*Z%!37db5yVyn3wLd zrFNP6$7MO|fMCI}PrZ3+2x7iE49>ea6vjyRxp+ndqIPgq@GuwqV*TcQoA)#9lWS~U zQU3s>#^Y#n{Dqwhd&=3W-ekm7?g0rEt1WkFD}T1v9+)JiqJ!Kb7qk0c72v^hIxz0O+v@Pg!|7!0ygbFKTpj5U>#{_NNH<;qHQQA&`2PdYXhHv$&76ocvcqDFWk_=ZylI$j3(ulFz7H=pZS8O5A;%BGF2-}6{Q3^CGJerk7Ri(j%fl$J&KT^JMdu zj)6HuVBmf_+!4{}v#_ZlTrzEl;2%KvzWGmNSyCY6_)9z2TfKS7uQ+tk1|g!+R6o*d zxQG1m_)5$W;NiK0e*G3r`2EI25Ggj&3OdkZBrVXREyM|Rgy7pDWy89DNz(eLrQqFw zr6KHuZa+za9FEO_d7~n?^yw zF-2Y4&|>D1$rs3ZW?0u%YE?<}$3fP9`WNVQrKj`XLlU7q?-ethx0gwzN5M5#7aCXNU;$SO?Tj*PFdd#J6a9J~-jaU8fSs5A{Gw7og5+bl_w+^J@-ZOvA0Psz% zK)=r08_8zxj7!ovSLYCT5UZj1R{#sFJ?&8D3%&$&26g?cvVkAQQQ|jem^V+`6{;;G zobP_cQNAwDv?iDg zQI*qJh)uqID(45TniyM4tF5kZF_9a<|FI*jy9yZcmBvuJ)qCW)gB2d=Lfy_4RWJv& zx5X7KXRJ8nUN_=eU+DAUq;^*$FmhRoadsVV^@IT*GGqth+E2qxmep zCk9T;q4TU^wv4+0U*w@;f+pNvFBk84W8fK^nM)D9Im8pH$yWZ=Opn?H#za@E9J7Th z+szU!pI(`hTp>`u4*t~|i#`QE zvcy>))ySV0tR(*VrXM&DDD;6_957}meY0$upQtjBz9CfEzuVW?QAd@ccG0 zC$BO^>A8w^b+@5Gnt?{%5Kf?U z%^BmV5y2=QxrZ<691nFnNHd8rA#6alI&2TY>cKNi+g*G$xG^!Z)3jI-#;MfQGi)uT zLtRo^qT*PABF{5EHQ2kF{sR>I$%6M(2F_UY&A5=pJ;KHw3-}jKD z0>Ob?Jw-pyygD_8mBpkdB53?@(7PwTbOC&)I(Txmx_J0-5_>*$z#Jp8#`;ovVCILSRCnTe`dv zuSs3ICT>R1(g9PkvFX$gOCo_sBAFaS;xrN%Ape5!=_2*h9+>pJ`PJeO_2CPp8R`q) z1N+5qkErY6`0ju(rzZW2ia0HYw~v-c#R?cUgx-X$)ve5r z%S7SCpLQV#Wc0CTHwZ?!FWeQyH|w_C?!S?{txvBcIt`0`t-%_2SDTb|WP*-mr;pXp$TydN zx)Jo*GYac`*)J~S+EpozCY~@jyF6BX_wm@^JHFV5w;9KuKg;*Nh-f@<9vh*i1ZCiLfJEgu~oL9t?`%dt}TA7>j zpy{3|FW<}u9dOt=$@x(7BAWku+>KJ-M~&{&N&@*)^zK4gQ7U4cA|0i9R+54c6wCdR z6rnddW)!Fh=ru6p;8NzVz}9XWp{8J7C2&Iw{22PhytMFopF+jqoH8X$^Ns)^qUP1Q zNXWTQ`!JR2!Rk66cFq{seO+`{h&zT2b-G!sH53h39fMehNr7eNq14Atyy{ks$xKzoJ~WJ3KPN4zoNAtu7^u&t&r!}CRP&d@AImB zwW66FtTeAD3pvwlCQyh8k(A3c9|+bXW-9TlhVx`pVvj$`A{FZY3DPYcSB%LmRA}&H zULwOnB31X;b1#Ew+I80=%1IpqhX+NzBv%43e->&XYldchd6(mzhw|YkAXtW3ch4vm zZ?{<0di_($E`5%QNOYh006O?0J70WBVxs&X;QP8_cj0NtE%jFz64gXKX;H)_P9a)Q zBnZpBr12qPE#9l{`GU`bGZg3~2UV2rf2IqdW^Jfz&U`0Y%sOdvi$$g0`Gu0vVV>iY zWy{_>5N20GJX7Cru8y|J0Si1Ft!La(ex~YvUTR7Rh*W_8yOQJoRtXhA|KHW${df7_5atn-G8qCC-Arb4H*0X1Iz%&`fp%sdsEBruAKi9e{5LU`#*U9t5nv) z^!R`A3E*|#0(v9qbrKfT-QW5n0y2US0c8IV{(t(Z{(s<`S-aVrI`Qy-~7)Aj6-r2mrtU91H;XzW^1QC=mbv literal 0 HcmV?d00001 diff --git a/ohos-jszip/entry/src/main/resources/zh_CN/element/string.json b/ohos-jszip/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 00000000..597ecf95 --- /dev/null +++ b/ohos-jszip/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos-jszip/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 00000000..6d0d9e39 --- /dev/null +++ b/ohos-jszip/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + + it('assertContain',0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/ohosTest/ets/test/List.test.ets b/ohos-jszip/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 00000000..b9a51de9 --- /dev/null +++ b/ohos-jszip/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import fileTest from './file.test' +import filterTest from './filter.test' +import forEachTest from './forEach.test' +import constructorTest from './constructor.test' +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() + constructorTest() + forEachTest() + filterTest() + fileTest() +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/ohosTest/ets/test/constructor.test.ets b/ohos-jszip/entry/src/ohosTest/ets/test/constructor.test.ets new file mode 100644 index 00000000..edb3c15f --- /dev/null +++ b/ohos-jszip/entry/src/ohosTest/ets/test/constructor.test.ets @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' +import JSZip from "jszip"; +export default function constructorTest() { + describe('constructorTest', () => { + + it('JSZip_exists', 0, () => { + expect(!!JSZip).assertTrue(); + }) + + it('new_JSZip', 0, () => { + const zip = new JSZip(); + expect(zip instanceof JSZip).assertTrue(); + }) + + it('JSZip', 0, () => { + const zip = JSZip(); + expect(zip instanceof JSZip).assertTrue(); + }) + }) +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/ohosTest/ets/test/file.test.ets b/ohos-jszip/entry/src/ohosTest/ets/test/file.test.ets new file mode 100644 index 00000000..9930cde4 --- /dev/null +++ b/ohos-jszip/entry/src/ohosTest/ets/test/file.test.ets @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' +import JSZip, { JSZipFileOptions } from "jszip"; + +type Done = () => void + +export default function fileTest() { + describe('fileTest', () => { + it('add_file_wrong_string_as_base64', 0, (done: Done) => { + let zip = new JSZip(); + zip.file("text.txt", "a random string", { + base64: true + }); + zip.generateAsync({ + type: "binarystring" + }).then(() => { + expect(false).assertTrue(); + done(); + }).catch((e: Error) => { + console.log(`出现异常${e.message}`); + expect(e.message).assertEqual("Invalid base64 input, bad content length."); + done(); + }); + }) + it('add_file_data_url_instead_of_base64', 0, (done: Done) => { + const zip = new JSZip(); + zip.file("text.txt", "data:image/png;base64,YmFzZTY0", { + base64: true + }); + zip.generateAsync({ + type: "binarystring" + }).then(() => { + expect(false).assertTrue(); + done(); + }).catch((e: Error) => { + expect(e.message).assertEqual("Invalid base64 input, it looks like a data url."); + done(); + }); + }) + it('Zip_folder_should_not_throw_an_exception', 0, () => { + const zip = new JSZip(); + try { + zip.folder(""); + expect(true).assertTrue(); + } catch (err) { + expect(false).assertTrue(); + } + }) + it('file_creates_a_folder_with_dir_true', 0, () => { + const zip = new JSZip(); + const options: JSZipFileOptions = { + dir: true + } + zip.file("folder", null, options); + expect(!!zip.files["folder/"].dir).assertTrue(); + }) + it('file_creates_a_folder_with_the_right_unix_permissions', 0, () => { + const zip = new JSZip(); + const options: JSZipFileOptions = { + unixPermissions: 16704 + } + zip.file("folder", null, options); + expect(!!zip.files["folder/"].dir).assertTrue(); + }) + it('file_creates_a_folder_with_the_right_dos_permissions', 0, () => { + const zip = new JSZip(); + const options: JSZipFileOptions = { + dosPermissions: 16 + } + zip.file("folder", null, options); + expect(zip.files["folder/"].dir).assertTrue(); + }) + it('A_folder_stays_a_folder_when_created_with_file', 0, (done: Done) => { + const referenceDate = new Date("July 17, 2009 14:36:56"); + const referenceComment = "my comment"; + const zip = new JSZip(); + const options: JSZipFileOptions = { + dir: true, + date: referenceDate, + comment: referenceComment, + unixPermissions: 16704 + } + zip.file("folder", null, options); + + expect(!!zip.files["folder/"].dir).assertTrue(); + expect(zip.files["folder/"].date.getTime()).assertEqual(referenceDate.getTime()); + expect(zip.files["folder/"].comment).assertEqual(referenceComment); + expect(zip.files["folder/"]?.unixPermissions?.toString(8)).assertEqual("40500"); + + zip.generateAsync({ + type: "string", platform: "UNIX" + }) + .then(JSZip.loadAsync) + .then((reloaded) => { + expect(reloaded.files["folder/"].dir).assertTrue(); + + expect(reloaded.files["folder/"].dir).assertTrue(); + expect(reloaded.files["folder/"].date.getTime()).assertEqual(referenceDate.getTime()); + expect(reloaded.files["folder/"].comment).assertEqual(referenceComment); + expect(reloaded.files["folder/"]?.unixPermissions?.toString(8)).assertEqual("40500"); + done(); + }).catch(() => { + expect(false).assertTrue() + done(); + }); + }) + it('file_adds_a_slash_for_directories', 0, () => { + const zip = new JSZip(); + const options: JSZipFileOptions = { + dir: true + } + zip.file("folder_without_slash", null, options); + zip.file("folder_with_slash/", null, options); + expect(!!zip.files["folder_without_slash/"]).assertTrue(); + expect(!!zip.files["folder_with_slash/"]).assertTrue(); + }) + it('folder_does_not_overwrite_existing_entries', 0, () => { + const referenceComment = "my comment"; + const zip = new JSZip(); + const options: JSZipFileOptions = { + dir: true, + comment: referenceComment, + unixPermissions: 16704 + } + zip.file("folder", null, options); + + // calling folder() doesn't override it + zip.folder("folder"); + + expect(zip.files["folder/"].comment).assertEqual(referenceComment); + expect(zip.files["folder/"]?.unixPermissions?.toString(8)).assertEqual("40500"); + }) + it('createFolders_works_on_a_file', 0, () => { + const zip = new JSZip(); + zip.file("false/0/1/2/file", "content", { + createFolders: false, unixPermissions: "644" + }); + zip.file("true/0/1/2/file", "content", { + createFolders: true, unixPermissions: "644" + }); + + expect(!zip.files["false/"]).assertTrue(); + expect(!!zip.files["true/"]).assertTrue(); + expect(zip.files["true/"].unixPermissions).assertEqual(null); + }) + it('createFolders_works_on_a_folder', 0, () => { + const zip = new JSZip(); + const options1: JSZipFileOptions = { + createFolders: false, unixPermissions: "777", dir: true + } + const options2: JSZipFileOptions = { + createFolders: true, unixPermissions: "777", dir: true + } + + zip.file("false/0/1/2/folder", null, options1); + zip.file("true/0/1/2/folder", null, options2); + + expect(!zip.files["false/"]).assertTrue(); + expect(!!zip.files["true/"]).assertTrue(); + expect(zip.files["true/"].unixPermissions).assertEqual(null); + }) + + + it('folder_follows_the_default_createFolders_settings', 0, () => { + const zip = new JSZip(); + zip.folder("true/0/1/2/folder"); + expect(!!zip.files["true/"]).assertTrue() + }) + it('A_folder_stays_a_folder', 0, (done: Done) => { + const zip = new JSZip(); + zip.folder("folder/"); + expect(!!zip.files["folder/"].dir).assertTrue(); + zip.generateAsync({ + type: "binarystring" + }) + .then(JSZip.loadAsync) + .then((reloaded) => { + expect(!!reloaded.files["folder/"].dir).assertTrue(); + done(); + }).catch(() => { + expect(false).assertTrue(); + }); + }) + it('Folders_are_created_by_default', 0, () => { + const zip = new JSZip(); + zip.file("test/Readme", "Hello World!\n"); + expect(!!zip.files["test/"]).assertTrue(); + expect(!!zip.files["test/Readme"]).assertTrue(); + }) + it('Folders_can_be_avoided_with_createFolders', 0, () => { + const zip = new JSZip(); + zip.file("test/Readme", "Hello World!\n", { + createFolders: false + }); + expect(!!zip.files["test/Readme"]).assertTrue(); + expect(!zip.files["test/"]).assertTrue(); + }) + it('Finding_a_file', 0, (done: Done) => { + const zip = new JSZip(); + zip.file("Readme", "Hello World!\n"); + zip.file("Readme.French", "Bonjour tout le monde!\n"); + zip.file("Readme.Pirate", "Ahoy m'hearty!\n"); + + zip.file("Readme.French")?.async("string")?.then((content) => { + expect(content).assertEqual("Bonjour tout le monde!\n"); + done(); + }).catch(() => { + expect(false).assertTrue() + }); + expect(zip.file("Readme.Deutsch")).assertEqual(null); + expect(zip.file(new RegExp("Readme\..")).length).assertEqual(2); + expect(zip.file(new RegExp("pirate", "i")).length).assertEqual(1); + }) + it('Finding_a_file_text_search_with_a_relative_folder', 0, (done:Done) => { + const zip = new JSZip(); + zip.folder("files/default")?.file("Readme", "Hello World!\n"); + zip.folder("files/translation")?.file("Readme.French", "Bonjour tout le monde!\n"); + zip.folder("files")?.folder("translation")?.file("Readme.Pirate", "Ahoy m'hearty!\n"); + + zip.file("files/translation/Readme.French")?.async("string").then((content) => { + expect(content).assertEqual("Bonjour tout le monde!\n"); + done(); + }).catch(() => { + expect(false).assertTrue(); + }); + }) + it('Finding_files_regex_with_a_relative_folder', 0, () => { + const zip = new JSZip(); + zip.folder("files/default")?.file("Readme", "Hello World!\n"); + zip.folder("files/translation")?.file("Readme.French", "Bonjour tout le monde!\n"); + zip.folder("files")?.folder("translation")?.file("Readme.Pirate", "Ahoy m'hearty!\n"); + + expect(zip.file(new RegExp("Readme")).length).assertEqual(3); + expect(zip.folder("files/translation")?.file(new RegExp("Readme")).length).assertEqual(2); + expect(zip.folder("files")?.folder("translation")?.file(new RegExp("Readme")).length).assertEqual(2); + expect(zip.folder("files/translation")?.file(new RegExp("pirate","i")).length).assertEqual(1); + expect(zip.folder("files/translation")?.file(new RegExp("^readme","i")).length).assertEqual(2); + expect(zip.folder("files/default")?.file(new RegExp("pirate","i")).length).assertEqual(0); + + }) + it('Finding_folders', 0, () => { + const zip = new JSZip(); + zip.folder("root/")?.folder("sub1/"); + zip.folder("root/sub2/subsub1"); + + expect(zip.folder(new RegExp("sub2\/$")).length).assertEqual(1); + expect(zip.folder(new RegExp("sub1")).length).assertEqual(2); + expect(zip.folder(new RegExp("root")).length).assertEqual(4); + + + }) + it('Finding_folders_with_relative_path', 0, () => { + const zip = new JSZip(); + zip.folder("root/")?.folder("sub1/"); + zip.folder("root/sub2/subsub1"); + const root = zip.folder("root/sub2"); + + expect(root?.folder(new RegExp("sub2\/$")).length).assertEqual(0); + expect(root?.folder(new RegExp("sub1")).length).assertEqual(1); + expect(root?.folder(new RegExp("^subsub1")).length).assertEqual(1); + expect(root?.folder(new RegExp("root")).length).assertEqual(0); + + }) + + it('generate_uses_updated_ZipObject_date_attribute', 0, (done: Done) => { + const date = new Date("July 17, 2009 14:36:57"); + const zip = new JSZip(); + zip.file("Hello.txt", "Hello World\n", { + comment: "my comment" + }); // date = now + zip.files["Hello.txt"].date = date; + zip.generateAsync({ + type: "binarystring" + }) + .then(JSZip.loadAsync) + .then( () => { + expect(true).assertTrue(); + done(); + }).catch(() => { + expect(false).assertTrue(); + }); + + }) + + }) +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/ohosTest/ets/test/filter.test.ets b/ohos-jszip/entry/src/ohosTest/ets/test/filter.test.ets new file mode 100644 index 00000000..4a9a4092 --- /dev/null +++ b/ohos-jszip/entry/src/ohosTest/ets/test/filter.test.ets @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' +import JSZip,{JSZipObject} from "jszip"; + +export default function filterTest() { + describe('filterTest', () => { + it('Filtering_a_zip', 0, () => { + const zip = new JSZip(); + zip.file("1.txt", "1\n"); + zip.file("2.txt", "2\n"); + zip.file("3.log", "3\n"); + const result = zip.filter((relativeFilename) => { + return relativeFilename.indexOf(".txt") !== -1; + }); + expect(result.length).assertEqual(2); + expect(result[0].name.indexOf(".txt") !== -1).assertTrue(); + expect(result[1].name.indexOf(".txt") !== -1).assertTrue(); + }) + it('Filtering_a_zip_from_a_relative_path2', 0, () => { + + + const zip = new JSZip(); + zip.file("foo/1.txt", "1\n"); + zip.file("foo/2.txt", "2\n"); + zip.file("foo/3.log", "3\n"); + zip.file("1.txt", "1\n"); + zip.file("2.txt", "2\n"); + zip.file("3.log", "3\n"); + + let count = 0; + const result:Array|undefined = zip.folder("foo")?.filter((relativeFilename) => { + count++; + return relativeFilename.indexOf("3") !== -1; + }); + expect(count).assertEqual(3); + expect(result?.length).assertEqual(1); + expect(result && result.length && result[0].name).assertEqual("foo/3.log"); + }) + + it('Filtering_a_zip_from_a_relative_path', 0, () => { + const zip = new JSZip(); + zip.file("foo/1.txt", "1\n"); + zip.file("foo/2.txt", "2\n"); + zip.file("foo/3.log", "3\n"); + zip.file("1.txt", "1\n"); + zip.file("2.txt", "2\n"); + zip.file("3.log", "3\n"); + + const result:Array|undefined = zip.folder("foo")?.filter((relativeFilename, file) => { + return file.name.indexOf("3") !== -1; + }); + expect(result?.length).assertEqual(1); + expect(result && result.length && result[0].name).assertEqual("foo/3.log"); + }) + }) +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/ohosTest/ets/test/forEach.test.ets b/ohos-jszip/entry/src/ohosTest/ets/test/forEach.test.ets new file mode 100644 index 00000000..aafe0ca2 --- /dev/null +++ b/ohos-jszip/entry/src/ohosTest/ets/test/forEach.test.ets @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' +import JSZip from "jszip"; + +const createZipAll =() => { + const zip = new JSZip(); + zip.file("Hello.txt", "Hello World\n"); + zip.folder("images")?.file("smile.gif", "R0lGODdhBQAFAIACAAAAAP/eACwAAAAABQAFAAACCIwPkWerClIBADs=", {base64: true}); + return zip; +}; +export default function forEachTest() { + describe('forEachTest', () => { + it('forEach_works_on', 0, () => { + const zip = createZipAll(); + let count:number = 0; + const calls:string[] = []; + + zip.forEach( (path, elt) => { + expect(path).assertEqual(elt.name); + count++; + calls.push(path); + }); + + expect(count).assertEqual(3); + }) + + it('forEach_works_on_a_sub_folder', 0, () => { + const zip = new JSZip(); + const sub = zip.folder("subfolder"); + sub && sub.file("Hello.txt", "Hello World\n"); + sub && sub.folder("images")?.file("smile.gif", "R0lGODdhBQAFAIACAAAAAP/eACwAAAAABQAFAAACCIwPkWerClIBADs=", {base64: true}); + let count:number = 0; + let calls:string[] = []; + + expect(!!zip.file("subfolder/Hello.txt")).assertTrue(); + + sub && sub.forEach((path, elt) => { + expect(path).assertEqual(elt.name.substr("subfolder/".length)); + count++; + calls.push(path); + }); + + expect(count).assertEqual(3); + }) + }) +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos-jszip/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 00000000..ea333bee --- /dev/null +++ b/ohos-jszip/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; +import Want from '@ohos.app.ability.Want'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; + +export default class TestAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos-jszip/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 00000000..4ca1473b --- /dev/null +++ b/ohos-jszip/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos-jszip/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos-jszip/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 00000000..063887cf --- /dev/null +++ b/ohos-jszip/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/ohosTest/module.json5 b/ohos-jszip/entry/src/ohosTest/module.json5 new file mode 100644 index 00000000..4fc97017 --- /dev/null +++ b/ohos-jszip/entry/src/ohosTest/module.json5 @@ -0,0 +1,37 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos-jszip/entry/src/ohosTest/resources/base/element/color.json b/ohos-jszip/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 00000000..3c712962 --- /dev/null +++ b/ohos-jszip/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/ohosTest/resources/base/element/string.json b/ohos-jszip/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 00000000..65d8fa5a --- /dev/null +++ b/ohos-jszip/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos-jszip/entry/src/ohosTest/resources/base/media/icon.png b/ohos-jszip/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c GIT binary patch literal 6790 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"a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos-jszip/hvigorfile.ts b/ohos-jszip/hvigorfile.ts new file mode 100644 index 00000000..e02832f2 --- /dev/null +++ b/ohos-jszip/hvigorfile.ts @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos-jszip/hvigorw b/ohos-jszip/hvigorw new file mode 100644 index 00000000..54aadd22 --- /dev/null +++ b/ohos-jszip/hvigorw @@ -0,0 +1,48 @@ +#!/bin/bash + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos-jszip/hvigorw.bat b/ohos-jszip/hvigorw.bat new file mode 100644 index 00000000..6861293e --- /dev/null +++ b/ohos-jszip/hvigorw.bat @@ -0,0 +1,64 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos-jszip/library/.gitignore b/ohos-jszip/library/.gitignore new file mode 100644 index 00000000..26c27a4a --- /dev/null +++ b/ohos-jszip/library/.gitignore @@ -0,0 +1,8 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test +package-lock.json +oh-package-lock.json5 \ No newline at end of file diff --git a/ohos-jszip/library/Index.js b/ohos-jszip/library/Index.js new file mode 100644 index 00000000..344229c1 --- /dev/null +++ b/ohos-jszip/library/Index.js @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {default as default } from "./src/main/dist/dist"; \ No newline at end of file diff --git a/ohos-jszip/library/build-profile.json5 b/ohos-jszip/library/build-profile.json5 new file mode 100644 index 00000000..08f43dcb --- /dev/null +++ b/ohos-jszip/library/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": true, + "files": [ + "./obfuscation-rules.txt" + ] + }, + "consumerFiles": [ + "./consumer-rules.txt" + ] + } + } + }, + ], + "targets": [ + { + "name": "default" + } + ] +} diff --git a/ohos-jszip/library/consumer-rules.txt b/ohos-jszip/library/consumer-rules.txt new file mode 100644 index 00000000..e69de29b diff --git a/ohos-jszip/library/hvigorfile.ts b/ohos-jszip/library/hvigorfile.ts new file mode 100644 index 00000000..7bea9707 --- /dev/null +++ b/ohos-jszip/library/hvigorfile.ts @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { harTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/ohos-jszip/library/obfuscation-rules.txt b/ohos-jszip/library/obfuscation-rules.txt new file mode 100644 index 00000000..985b2aeb --- /dev/null +++ b/ohos-jszip/library/obfuscation-rules.txt @@ -0,0 +1,18 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file diff --git a/ohos-jszip/library/oh-package.json5 b/ohos-jszip/library/oh-package.json5 new file mode 100644 index 00000000..953f2279 --- /dev/null +++ b/ohos-jszip/library/oh-package.json5 @@ -0,0 +1,27 @@ +{ + "name": "@ohos/jszip", + "keywords": [ + "OpenHarmony", + "HarmonyOS", + "zip", + "rar", + ], + "author": "ohos_tpc", + "ohos": { + "org": "opensource" + }, + "description": "A library for creating, reading and editing .zip files with JavaScript, with a lovely and simple API.", + "main": "Index.js", + "types": "./src/main/type", + "repository": "https://gitee.com/openharmony-tpc/openharmony_tpc_samples/tree/master/ohos-jszip", + "type": "module", + "version": "1.0.0", + "tags": [ + "Tool" + ], + "license": "MIT", + "dependencies": { + "@ohos/node-polyfill": "^1.0.0" + }, + "devDependencies": {} +} \ No newline at end of file diff --git a/ohos-jszip/library/package.json b/ohos-jszip/library/package.json new file mode 100644 index 00000000..2806210c --- /dev/null +++ b/ohos-jszip/library/package.json @@ -0,0 +1,23 @@ +{ + "name": "ohos-jszip", + "version": "1.0.0", + "description": "", + "main": "rollup.config.js", + "scripts": { + "build":"rollup -c ./rollup.config.js" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "@rollup/plugin-alias": "^5.0.1", + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-node-resolve": "^15.2.3", + "rollup": "^4.5.1" + }, + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } +} diff --git a/ohos-jszip/library/rollup.config.js b/ohos-jszip/library/rollup.config.js new file mode 100644 index 00000000..21bd27de --- /dev/null +++ b/ohos-jszip/library/rollup.config.js @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const path = require("path"); +const alias = require("@rollup/plugin-alias"); +const resolve = require("@rollup/plugin-node-resolve"); +const commonjs = require("@rollup/plugin-commonjs"); + +const input = path.resolve(__dirname,"./src/main/core/jszip-master/lib/index.js") +const output = { + file:path.resolve(__dirname,"./src/main/dist/dist.js"), + format:"es" +} + +module.exports = { + input, + output, + external:[ + /^@ohos\/node-polyfill\/src\/main\/dist\/.+/ + ], + plugins:[ + alias({ + entries:{ + "buffer":"@ohos/node-polyfill/src/main/dist/buffer", + "crypto":"@ohos/node-polyfill/src/main/dist/crypto", + "events":"@ohos/node-polyfill/src/main/dist/events", + "net":"@ohos/node-polyfill/src/main/dist/net", + "path":"@ohos/node-polyfill/src/main/dist/path", + "process":"@ohos/node-polyfill/src/main/dist/process", + "querystring":"@ohos/node-polyfill/src/main/dist/querystring", + "stream":"@ohos/node-polyfill/src/main/dist/stream", + "string_decoder":"@ohos/node-polyfill/src/main/dist/string_decoder", + "timers":"@ohos/node-polyfill/src/main/dist/timers", + "url":"@ohos/node-polyfill/src/main/dist/url", + "util":"@ohos/node-polyfill/src/main/dist/util", + } + }), + commonjs(), + resolve() + ] + +} \ No newline at end of file diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/aes.js b/ohos-jszip/library/src/main/core/jszip-master/lib/aes.js new file mode 100644 index 00000000..4fca0645 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/aes.js @@ -0,0 +1,141 @@ +"use strict"; +var sjcl = require("./sjcl"); +var utils = require("./utils"); +var GenericWorker = require("./stream/GenericWorker"); + +var passwordVerifierLen = 2; +var authCodeLen = 10; + +/** + * Create a worker that uses sjcl to process file data. + * @constructor + * @param dir The direction, 0 for decrypt and 1 for encrypt. + * @param {Object|bitArray} param the aesKey for decrypt or the options for encrypt. + */ +function AesWorker(dir, param) { + GenericWorker.call(this, "AesWorker"); + + this._aes = null; + this._aesKey = null; + this._mac = null; + this._dir = dir; + + if (this._dir) { + this._password = param.password; + this._keyLen = this._macLen = 8 * param.strength + 8; + this._saltLen = this._keyLen /2; + } else { + this._aesKey = param; + } + + // the `meta` object from the last chunk received + // this allow this worker to pass around metadata + this.meta = {}; +} + +utils.inherits(AesWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +AesWorker.prototype.processChunk = function (chunk) { + this.meta = chunk.meta; + + if (this._aes === null) { + this._createAes(); + } + var result = this._aes.update(sjcl.codec.bytes.toBits(chunk.data)); + if (this._dir) { + this._mac.update(result); + } + + this.push({ + data : new Uint8Array(sjcl.codec.bytes.fromBits(result)), + meta : this.meta + }); +}; + +/** + * @see GenericWorker.flush + */ +AesWorker.prototype.flush = function () { + GenericWorker.prototype.flush.call(this); + + if (this._dir) { + if (this._aes === null) { + this._createAes(); + } + var macData = this._mac.digest(); + macData = sjcl.bitArray.clamp(macData, authCodeLen * 8); + + this.push({ + data : new Uint8Array(sjcl.codec.bytes.fromBits(macData)), + meta : {percent: 100} + }); + } +}; + +/** + * @see GenericWorker.cleanUp + */ +AesWorker.prototype.cleanUp = function () { + GenericWorker.prototype.cleanUp.call(this); + this._aes = null; + this._aesKey = null; + this._mac = null; +}; + +/** + * Create the _aes object. + */ +AesWorker.prototype._createAes = function () { + if (this._dir) { + var salt = sjcl.random.randomWords(this._saltLen); + var derivedKey = sjcl.misc.pbkdf2(this._password, salt, 1000, (this._macLen + this._keyLen + passwordVerifierLen) * 8); + this._aesKey = sjcl.bitArray.bitSlice(derivedKey, 0, this._keyLen * 8); + var macKey = sjcl.bitArray.bitSlice(derivedKey, this._keyLen * 8, (this._keyLen + this._macLen) * 8); + var derivedPassVerifier = sjcl.bitArray.bitSlice(derivedKey, (this._keyLen + this._macLen) * 8); + this._mac = new sjcl.misc.hmac(macKey); + + this.push({ + data : new Uint8Array(sjcl.codec.bytes.fromBits(sjcl.bitArray.concat(salt, derivedPassVerifier))), + meta : {percent: 0} + }); + } + + this._aes = new sjcl.mode.ctrGladman(new sjcl.cipher.aes(this._aesKey), [0, 0, 0, 0]); +}; + +exports.EncryptWorker = function (options) { + return new AesWorker(1, options); +}; + +exports.DecryptWorker = function (key) { + return new AesWorker(0, key); +}; + +/** + * Verify the password of file using sjcl. + * @param {Uint8Array} data the data to verify. + * @param {Object} options the options when verifying. + * @return {Object} the aes key and encrypted file data. + */ +exports.verifyPassword = function (data, options) { + var password = options.password; + var keyLen = 8 * options.strength + 8; + var macLen = keyLen; + var saltLen = keyLen / 2; + + var salt = sjcl.codec.bytes.toBits(data.subarray(0, saltLen)); + var derivedKey = sjcl.misc.pbkdf2(password, salt, 1000, (macLen + keyLen + passwordVerifierLen) * 8); + var derivedPassVerifier = sjcl.bitArray.bitSlice(derivedKey, (keyLen + macLen) * 8); + var passVerifyValue = sjcl.codec.bytes.toBits(data.subarray(saltLen, saltLen + passwordVerifierLen)); + if (!sjcl.bitArray.equal(passVerifyValue, derivedPassVerifier)) { + throw new Error("Encrypted zip: incorrect password"); + } + + return { + key: sjcl.bitArray.bitSlice(derivedKey, 0, keyLen * 8), + data: data.subarray(saltLen + passwordVerifierLen, -authCodeLen) + }; +}; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/base64.js b/ohos-jszip/library/src/main/core/jszip-master/lib/base64.js new file mode 100644 index 00000000..6f46deaa --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/base64.js @@ -0,0 +1,106 @@ +"use strict"; +var utils = require("./utils"); +var support = require("./support"); +// private property +var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + + +// public method for encoding +exports.encode = function(input) { + var output = []; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0, len = input.length, remainingBytes = len; + + var isArray = utils.getTypeOf(input) !== "string"; + while (i < input.length) { + remainingBytes = len - i; + + if (!isArray) { + chr1 = input.charCodeAt(i++); + chr2 = i < len ? input.charCodeAt(i++) : 0; + chr3 = i < len ? input.charCodeAt(i++) : 0; + } else { + chr1 = input[i++]; + chr2 = i < len ? input[i++] : 0; + chr3 = i < len ? input[i++] : 0; + } + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = remainingBytes > 1 ? (((chr2 & 15) << 2) | (chr3 >> 6)) : 64; + enc4 = remainingBytes > 2 ? (chr3 & 63) : 64; + + output.push(_keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4)); + + } + + return output.join(""); +}; + +// public method for decoding +exports.decode = function(input) { + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0, resultIndex = 0; + + var dataUrlPrefix = "data:"; + + if (input.substr(0, dataUrlPrefix.length) === dataUrlPrefix) { + // This is a common error: people give a data url + // (data:image/png;base64,iVBOR...) with a {base64: true} and + // wonders why things don't work. + // We can detect that the string input looks like a data url but we + // *can't* be sure it is one: removing everything up to the comma would + // be too dangerous. + throw new Error("Invalid base64 input, it looks like a data url."); + } + + input = input.replace(/[^A-Za-z0-9+/=]/g, ""); + + var totalLength = input.length * 3 / 4; + if(input.charAt(input.length - 1) === _keyStr.charAt(64)) { + totalLength--; + } + if(input.charAt(input.length - 2) === _keyStr.charAt(64)) { + totalLength--; + } + if (totalLength % 1 !== 0) { + // totalLength is not an integer, the length does not match a valid + // base64 content. That can happen if: + // - the input is not a base64 content + // - the input is *almost* a base64 content, with a extra chars at the + // beginning or at the end + // - the input uses a base64 variant (base64url for example) + throw new Error("Invalid base64 input, bad content length."); + } + var output; + if (support.uint8array) { + output = new Uint8Array(totalLength|0); + } else { + output = new Array(totalLength|0); + } + + while (i < input.length) { + + enc1 = _keyStr.indexOf(input.charAt(i++)); + enc2 = _keyStr.indexOf(input.charAt(i++)); + enc3 = _keyStr.indexOf(input.charAt(i++)); + enc4 = _keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output[resultIndex++] = chr1; + + if (enc3 !== 64) { + output[resultIndex++] = chr2; + } + if (enc4 !== 64) { + output[resultIndex++] = chr3; + } + + } + + return output; +}; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/compressedObject.js b/ohos-jszip/library/src/main/core/jszip-master/lib/compressedObject.js new file mode 100644 index 00000000..9019bb11 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/compressedObject.js @@ -0,0 +1,99 @@ +"use strict"; + +var external = require("./external"); +var DataWorker = require("./stream/DataWorker"); +var Crc32Probe = require("./stream/Crc32Probe"); +var DataLengthProbe = require("./stream/DataLengthProbe"); +var aes = require("./aes"); + +/** + * Represent a compressed object, with everything needed to decompress it. + * @constructor + * @param {number} compressedSize the size of the data compressed. + * @param {number} uncompressedSize the size of the data after decompression. + * @param {number} crc32 the crc32 of the decompressed file. + * @param {object} compression the type of compression, see lib/compressions.js. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the compressed data. + * @param {Object} decryptOptions the compressed object decrypt options. + */ +function CompressedObject(compressedSize, uncompressedSize, crc32, compression, data, decryptOptions) { + this.compressedSize = compressedSize; + this.uncompressedSize = uncompressedSize; + this.crc32 = crc32; + this.compression = compression; + this.compressedContent = data; + this.decryptOptions = decryptOptions; +} + +CompressedObject.prototype = { + /** + * Create a worker to get the uncompressed content. + * @return {GenericWorker} the worker. + */ + getContentWorker: function () { + var worker; + if (this.decryptOptions.strength) { + if (!(this.decryptOptions.password && typeof this.decryptOptions.password === "string" )) { + throw new Error("Encrypted zip: need password"); + } + var result = aes.verifyPassword(this.compressedContent, this.decryptOptions); + + worker = new DataWorker(external.Promise.resolve(result.data)) + .pipe(aes.DecryptWorker(result.key)) + .pipe(this.compression.uncompressWorker()) + .pipe(new DataLengthProbe("data_length")); + } else { + worker = new DataWorker(external.Promise.resolve(this.compressedContent)) + .pipe(this.compression.uncompressWorker()) + .pipe(new DataLengthProbe("data_length")); + } + + var that = this; + worker.on("end", function () { + if (this.streamInfo["data_length"] !== that.uncompressedSize) { + throw new Error("Bug : uncompressed data size mismatch"); + } + }); + return worker; + }, + /** + * Create a worker to get the compressed content. + * @return {GenericWorker} the worker. + */ + getCompressedWorker: function () { + return new DataWorker(external.Promise.resolve(this.compressedContent)) + .withStreamInfo("compressedSize", this.compressedSize) + .withStreamInfo("uncompressedSize", this.uncompressedSize) + .withStreamInfo("crc32", this.crc32) + .withStreamInfo("compression", this.compression) + ; + } +}; + +/** + * Chain the given worker with other workers to compress the content with the + * given compression. + * @param {GenericWorker} uncompressedWorker the worker to pipe. + * @param {Object} compression the compression object. + * @param {Object} compressionOptions the options to use when compressing. + * @return {GenericWorker} the new worker compressing the content. + */ +CompressedObject.createWorkerFrom = function (uncompressedWorker, compression, compressionOptions, encryptOptions) { + if (encryptOptions.password !== null) { + return uncompressedWorker + .pipe(new DataLengthProbe("uncompressedSize")) + .pipe(compression.compressWorker(compressionOptions)) + .pipe(aes.EncryptWorker(encryptOptions)) + .pipe(new DataLengthProbe("compressedSize")) + .withStreamInfo("compression", compression); + } else { + return uncompressedWorker + .pipe(new Crc32Probe()) + .pipe(new DataLengthProbe("uncompressedSize")) + .pipe(compression.compressWorker(compressionOptions)) + .pipe(new DataLengthProbe("compressedSize")) + .withStreamInfo("compression", compression); + } +}; + +module.exports = CompressedObject; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/compressions.js b/ohos-jszip/library/src/main/core/jszip-master/lib/compressions.js new file mode 100644 index 00000000..81c67b4e --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/compressions.js @@ -0,0 +1,14 @@ +"use strict"; + +var GenericWorker = require("./stream/GenericWorker"); + +exports.STORE = { + magic: "\x00\x00", + compressWorker : function () { + return new GenericWorker("STORE compression"); + }, + uncompressWorker : function () { + return new GenericWorker("STORE decompression"); + } +}; +exports.DEFLATE = require("./flate"); diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/crc32.js b/ohos-jszip/library/src/main/core/jszip-master/lib/crc32.js new file mode 100644 index 00000000..fc111e9b --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/crc32.js @@ -0,0 +1,77 @@ +"use strict"; + +var utils = require("./utils"); + +/** + * The following functions come from pako, from pako/lib/zlib/crc32.js + * released under the MIT license, see pako https://github.com/nodeca/pako/ + */ + +// Use ordinary array, since untyped makes no boost here +function makeTable() { + var c, table = []; + + for(var n =0; n < 256; n++){ + c = n; + for(var k =0; k < 8; k++){ + c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); + } + table[n] = c; + } + + return table; +} + +// Create table on load. Just 255 signed longs. Not a problem. +var crcTable = makeTable(); + + +function crc32(crc, buf, len, pos) { + var t = crcTable, end = pos + len; + + crc = crc ^ (-1); + + for (var i = pos; i < end; i++ ) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +} + +// That's all for the pako functions. + +/** + * Compute the crc32 of a string. + * This is almost the same as the function crc32, but for strings. Using the + * same function for the two use cases leads to horrible performances. + * @param {Number} crc the starting value of the crc. + * @param {String} str the string to use. + * @param {Number} len the length of the string. + * @param {Number} pos the starting position for the crc32 computation. + * @return {Number} the computed crc32. + */ +function crc32str(crc, str, len, pos) { + var t = crcTable, end = pos + len; + + crc = crc ^ (-1); + + for (var i = pos; i < end; i++ ) { + crc = (crc >>> 8) ^ t[(crc ^ str.charCodeAt(i)) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +} + +module.exports = function crc32wrapper(input, crc) { + if (typeof input === "undefined" || !input.length) { + return 0; + } + + var isArray = utils.getTypeOf(input) !== "string"; + + if(isArray) { + return crc32(crc|0, input, input.length, 0); + } else { + return crc32str(crc|0, input, input.length, 0); + } +}; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/defaults.js b/ohos-jszip/library/src/main/core/jszip-master/lib/defaults.js new file mode 100644 index 00000000..8fb6c1e7 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/defaults.js @@ -0,0 +1,11 @@ +"use strict"; +exports.base64 = false; +exports.binary = false; +exports.dir = false; +exports.createFolders = true; +exports.date = null; +exports.compression = null; +exports.compressionOptions = null; +exports.comment = null; +exports.unixPermissions = null; +exports.dosPermissions = null; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/external.js b/ohos-jszip/library/src/main/core/jszip-master/lib/external.js new file mode 100644 index 00000000..c846f5fa --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/external.js @@ -0,0 +1,18 @@ +"use strict"; + +// load the global object first: +// - it should be better integrated in the system (unhandledRejection in node) +// - the environment may have a custom Promise implementation (see zone.js) +var ES6Promise = null; +if (typeof Promise !== "undefined") { + ES6Promise = Promise; +} else { + ES6Promise = require("lie"); +} + +/** + * Let the user use/change some implementations. + */ +module.exports = { + Promise: ES6Promise +}; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/flate.js b/ohos-jszip/library/src/main/core/jszip-master/lib/flate.js new file mode 100644 index 00000000..cd9e062c --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/flate.js @@ -0,0 +1,85 @@ +"use strict"; +var USE_TYPEDARRAY = (typeof Uint8Array !== "undefined") && (typeof Uint16Array !== "undefined") && (typeof Uint32Array !== "undefined"); + +var pako = require("pako"); +var utils = require("./utils"); +var GenericWorker = require("./stream/GenericWorker"); + +var ARRAY_TYPE = USE_TYPEDARRAY ? "uint8array" : "array"; + +exports.magic = "\x08\x00"; + +/** + * Create a worker that uses pako to inflate/deflate. + * @constructor + * @param {String} action the name of the pako function to call : either "Deflate" or "Inflate". + * @param {Object} options the options to use when (de)compressing. + */ +function FlateWorker(action, options) { + GenericWorker.call(this, "FlateWorker/" + action); + + this._pako = null; + this._pakoAction = action; + this._pakoOptions = options; + // the `meta` object from the last chunk received + // this allow this worker to pass around metadata + this.meta = {}; +} + +utils.inherits(FlateWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +FlateWorker.prototype.processChunk = function (chunk) { + this.meta = chunk.meta; + if (this._pako === null) { + this._createPako(); + } + this._pako.push(utils.transformTo(ARRAY_TYPE, chunk.data), false); +}; + +/** + * @see GenericWorker.flush + */ +FlateWorker.prototype.flush = function () { + GenericWorker.prototype.flush.call(this); + if (this._pako === null) { + this._createPako(); + } + this._pako.push([], true); +}; +/** + * @see GenericWorker.cleanUp + */ +FlateWorker.prototype.cleanUp = function () { + GenericWorker.prototype.cleanUp.call(this); + this._pako = null; +}; + +/** + * Create the _pako object. + * TODO: lazy-loading this object isn't the best solution but it's the + * quickest. The best solution is to lazy-load the worker list. See also the + * issue #446. + */ +FlateWorker.prototype._createPako = function () { + this._pako = new pako[this._pakoAction]({ + raw: true, + level: this._pakoOptions.level || -1 // default compression + }); + var self = this; + this._pako.onData = function(data) { + self.push({ + data : data, + meta : self.meta + }); + }; +}; + +exports.compressWorker = function (compressionOptions) { + return new FlateWorker("Deflate", compressionOptions); +}; +exports.uncompressWorker = function () { + return new FlateWorker("Inflate", {}); +}; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/generate/ZipFileWorker.js b/ohos-jszip/library/src/main/core/jszip-master/lib/generate/ZipFileWorker.js new file mode 100644 index 00000000..45bb660d --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/generate/ZipFileWorker.js @@ -0,0 +1,559 @@ +"use strict"; + +var utils = require("../utils"); +var GenericWorker = require("../stream/GenericWorker"); +var utf8 = require("../utf8"); +var crc32 = require("../crc32"); +var signature = require("../signature"); + +/** + * Transform an integer into a string in hexadecimal. + * @private + * @param {number} dec the number to convert. + * @param {number} bytes the number of bytes to generate. + * @returns {string} the result. + */ +var decToHex = function(dec, bytes) { + var hex = "", i; + for (i = 0; i < bytes; i++) { + hex += String.fromCharCode(dec & 0xff); + dec = dec >>> 8; + } + return hex; +}; + +/** + * Generate the UNIX part of the external file attributes. + * @param {Object} unixPermissions the unix permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute : + * + * TTTTsstrwxrwxrwx0000000000ADVSHR + * ^^^^____________________________ file type, see zipinfo.c (UNX_*) + * ^^^_________________________ setuid, setgid, sticky + * ^^^^^^^^^________________ permissions + * ^^^^^^^^^^______ not used ? + * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only + */ +var generateUnixExternalFileAttr = function (unixPermissions, isDir) { + + var result = unixPermissions; + if (!unixPermissions) { + // I can't use octal values in strict mode, hence the hexa. + // 040775 => 0x41fd + // 0100664 => 0x81b4 + result = isDir ? 0x41fd : 0x81b4; + } + return (result & 0xFFFF) << 16; +}; + +/** + * Generate the DOS part of the external file attributes. + * @param {Object} dosPermissions the dos permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * Bit 0 Read-Only + * Bit 1 Hidden + * Bit 2 System + * Bit 3 Volume Label + * Bit 4 Directory + * Bit 5 Archive + */ +var generateDosExternalFileAttr = function (dosPermissions) { + // the dir flag is already set for compatibility + return (dosPermissions || 0) & 0x3F; +}; + +/** + * Generate the various parts used in the construction of the final zip file. + * @param {Object} streamInfo the hash with information about the compressed file. + * @param {Boolean} streamedContent is the content streamed ? + * @param {Boolean} streamingEnded is the stream finished ? + * @param {number} offset the current offset from the start of the zip file. + * @param {String} platform let's pretend we are this platform (change platform dependents fields) + * @param {Function} encodeFileName the function to encode the file name / comment. + * @return {Object} the zip parts. + */ +var generateZipParts = function(streamInfo, streamedContent, streamingEnded, offset, platform, encodeFileName) { + var file = streamInfo["file"], + compression = streamInfo["compression"], + useCustomEncoding = encodeFileName !== utf8.utf8encode, + encodedFileName = utils.transformTo("string", encodeFileName(file.name)), + utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)), + comment = file.comment, + encodedComment = utils.transformTo("string", encodeFileName(comment)), + utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)), + useUTF8ForFileName = utfEncodedFileName.length !== file.name.length, + useUTF8ForComment = utfEncodedComment.length !== comment.length, + dosTime, + dosDate, + extraFields = "", + unicodePathExtraField = "", + unicodeCommentExtraField = "", + dir = file.dir, + date = file.date, + encryptOptions = streamInfo.file.encryptOptions, + isEncrypt = encryptOptions.password !== null; + + + var dataInfo = { + crc32 : 0, + compressedSize : 0, + uncompressedSize : 0 + }; + + // if the content is streamed, the sizes/crc32 are only available AFTER + // the end of the stream. + if (!streamedContent || streamingEnded) { + dataInfo.crc32 = streamInfo["crc32"]; + dataInfo.compressedSize = streamInfo["compressedSize"]; + dataInfo.uncompressedSize = streamInfo["uncompressedSize"]; + } + + var bitflag = 0; + if (isEncrypt) { + bitflag |= 0x0001; + } + if (streamedContent) { + // Bit 3: the sizes/crc32 are set to zero in the local header. + // The correct values are put in the data descriptor immediately + // following the compressed data. + bitflag |= 0x0008; + } + if (!useCustomEncoding && (useUTF8ForFileName || useUTF8ForComment)) { + // Bit 11: Language encoding flag (EFS). + bitflag |= 0x0800; + } + + + var extFileAttr = 0; + var versionMadeBy = 0; + if (dir) { + // dos or unix, we set the dos dir flag + extFileAttr |= 0x00010; + } + if (platform === "UNIX") { + versionMadeBy = 0x031E; // UNIX, version 3.0 + extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir); + } else { // DOS or other, fallback to DOS + versionMadeBy = 0x0014; // DOS, version 2.0 + extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir); + } + + // date + // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html + + dosTime = date.getUTCHours(); + dosTime = dosTime << 6; + dosTime = dosTime | date.getUTCMinutes(); + dosTime = dosTime << 5; + dosTime = dosTime | date.getUTCSeconds() / 2; + + dosDate = date.getUTCFullYear() - 1980; + dosDate = dosDate << 4; + dosDate = dosDate | (date.getUTCMonth() + 1); + dosDate = dosDate << 5; + dosDate = dosDate | date.getUTCDate(); + + if (useUTF8ForFileName) { + // set the unicode path extra field. unzip needs at least one extra + // field to correctly handle unicode path, so using the path is as good + // as any other information. This could improve the situation with + // other archive managers too. + // This field is usually used without the utf8 flag, with a non + // unicode path in the header (winrar, winzip). This helps (a bit) + // with the messy Windows' default compressed folders feature but + // breaks on p7zip which doesn't seek the unicode path extra field. + // So for now, UTF-8 everywhere ! + unicodePathExtraField = + // Version + decToHex(1, 1) + + // NameCRC32 + decToHex(crc32(encodedFileName), 4) + + // UnicodeName + utfEncodedFileName; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x70" + + // size + decToHex(unicodePathExtraField.length, 2) + + // content + unicodePathExtraField; + } + + if (useUTF8ForComment) { + + unicodeCommentExtraField = + // Version + decToHex(1, 1) + + // CommentCRC32 + decToHex(crc32(encodedComment), 4) + + // UnicodeName + utfEncodedComment; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x63" + + // size + decToHex(unicodeCommentExtraField.length, 2) + + // content + unicodeCommentExtraField; + } + + if (isEncrypt) { + extraFields += "\x01" + String.fromCharCode(0x99); + extraFields += "\x07\x00"; + extraFields += "\x02\x00"; + extraFields += "AE"; + extraFields += String.fromCharCode(encryptOptions.strength); + extraFields += compression.magic; + } + + var header = ""; + + // version needed to extract + if (isEncrypt) { + header += "\x33\x00"; + } else { + header += "\x0A\x00"; + } + // general purpose bit flag + header += decToHex(bitflag, 2); + // compression method + if (isEncrypt) { + header += "\x63\x00"; + } else { + header += compression.magic; + } + // last mod file time + header += decToHex(dosTime, 2); + // last mod file date + header += decToHex(dosDate, 2); + // crc-32 + header += decToHex(dataInfo.crc32, 4); + // compressed size + header += decToHex(dataInfo.compressedSize, 4); + // uncompressed size + header += decToHex(dataInfo.uncompressedSize, 4); + // file name length + header += decToHex(encodedFileName.length, 2); + // extra field length + header += decToHex(extraFields.length, 2); + + + var fileRecord = signature.LOCAL_FILE_HEADER + header + encodedFileName + extraFields; + + var dirRecord = signature.CENTRAL_FILE_HEADER + + // version made by (00: DOS) + decToHex(versionMadeBy, 2) + + // file header (common to file and central directory) + header + + // file comment length + decToHex(encodedComment.length, 2) + + // disk number start + "\x00\x00" + + // internal file attributes TODO + "\x00\x00" + + // external file attributes + decToHex(extFileAttr, 4) + + // relative offset of local header + decToHex(offset, 4) + + // file name + encodedFileName + + // extra field + extraFields + + // file comment + encodedComment; + + return { + fileRecord: fileRecord, + dirRecord: dirRecord + }; +}; + +/** + * Generate the EOCD record. + * @param {Number} entriesCount the number of entries in the zip file. + * @param {Number} centralDirLength the length (in bytes) of the central dir. + * @param {Number} localDirLength the length (in bytes) of the local dir. + * @param {String} comment the zip file comment as a binary string. + * @param {Function} encodeFileName the function to encode the comment. + * @return {String} the EOCD record. + */ +var generateCentralDirectoryEnd = function (entriesCount, centralDirLength, localDirLength, comment, encodeFileName) { + var dirEnd = ""; + var encodedComment = utils.transformTo("string", encodeFileName(comment)); + + // end of central dir signature + dirEnd = signature.CENTRAL_DIRECTORY_END + + // number of this disk + "\x00\x00" + + // number of the disk with the start of the central directory + "\x00\x00" + + // total number of entries in the central directory on this disk + decToHex(entriesCount, 2) + + // total number of entries in the central directory + decToHex(entriesCount, 2) + + // size of the central directory 4 bytes + decToHex(centralDirLength, 4) + + // offset of start of central directory with respect to the starting disk number + decToHex(localDirLength, 4) + + // .ZIP file comment length + decToHex(encodedComment.length, 2) + + // .ZIP file comment + encodedComment; + + return dirEnd; +}; + +/** + * Generate data descriptors for a file entry. + * @param {Object} streamInfo the hash generated by a worker, containing information + * on the file entry. + * @return {String} the data descriptors. + */ +var generateDataDescriptors = function (streamInfo) { + var descriptor = ""; + descriptor = signature.DATA_DESCRIPTOR + + // crc-32 4 bytes + decToHex(streamInfo["crc32"], 4) + + // compressed size 4 bytes + decToHex(streamInfo["compressedSize"], 4) + + // uncompressed size 4 bytes + decToHex(streamInfo["uncompressedSize"], 4); + + return descriptor; +}; + + +/** + * A worker to concatenate other workers to create a zip file. + * @param {Boolean} streamFiles `true` to stream the content of the files, + * `false` to accumulate it. + * @param {String} comment the comment to use. + * @param {String} platform the platform to use, "UNIX" or "DOS". + * @param {Function} encodeFileName the function to encode file names and comments. + */ +function ZipFileWorker(streamFiles, comment, platform, encodeFileName) { + GenericWorker.call(this, "ZipFileWorker"); + // The number of bytes written so far. This doesn't count accumulated chunks. + this.bytesWritten = 0; + // The comment of the zip file + this.zipComment = comment; + // The platform "generating" the zip file. + this.zipPlatform = platform; + // the function to encode file names and comments. + this.encodeFileName = encodeFileName; + // Should we stream the content of the files ? + this.streamFiles = streamFiles; + // If `streamFiles` is false, we will need to accumulate the content of the + // files to calculate sizes / crc32 (and write them *before* the content). + // This boolean indicates if we are accumulating chunks (it will change a lot + // during the lifetime of this worker). + this.accumulate = false; + // The buffer receiving chunks when accumulating content. + this.contentBuffer = []; + // The list of generated directory records. + this.dirRecords = []; + // The offset (in bytes) from the beginning of the zip file for the current source. + this.currentSourceOffset = 0; + // The total number of entries in this zip file. + this.entriesCount = 0; + // the name of the file currently being added, null when handling the end of the zip file. + // Used for the emitted metadata. + this.currentFile = null; + + this._sources = []; +} +utils.inherits(ZipFileWorker, GenericWorker); + +/** + * @see GenericWorker.push + */ +ZipFileWorker.prototype.push = function (chunk) { + + var currentFilePercent = chunk.meta.percent || 0; + var entriesCount = this.entriesCount; + var remainingFiles = this._sources.length; + + if (this.accumulate) { + this.contentBuffer.push(chunk); + } else { + this.bytesWritten += chunk.data.length; + + GenericWorker.prototype.push.call(this, { + data : chunk.data, + meta : { + currentFile : this.currentFile, + percent : entriesCount ? (currentFilePercent + 100 * (entriesCount - remainingFiles - 1)) / entriesCount : 100 + } + }); + } +}; + +/** + * The worker started a new source (an other worker). + * @param {Object} streamInfo the streamInfo object from the new source. + */ +ZipFileWorker.prototype.openedSource = function (streamInfo) { + this.currentSourceOffset = this.bytesWritten; + this.currentFile = streamInfo["file"].name; + + var streamedContent = this.streamFiles && !streamInfo["file"].dir; + + // don't stream folders (because they don't have any content) + if(streamedContent) { + var record = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName); + this.push({ + data : record.fileRecord, + meta : {percent:0} + }); + } else { + // we need to wait for the whole file before pushing anything + this.accumulate = true; + } +}; + +/** + * The worker finished a source (an other worker). + * @param {Object} streamInfo the streamInfo object from the finished source. + */ +ZipFileWorker.prototype.closedSource = function (streamInfo) { + this.accumulate = false; + var streamedContent = this.streamFiles && !streamInfo["file"].dir; + var record = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName); + + this.dirRecords.push(record.dirRecord); + if (streamedContent) { + // after the streamed file, we put data descriptors + this.push({ + data : generateDataDescriptors(streamInfo), + meta : {percent:100} + }); + } else { + // the content wasn't streamed, we need to push everything now + // first the file record, then the content + this.push({ + data : record.fileRecord, + meta : {percent:0} + }); + while(this.contentBuffer.length) { + this.push(this.contentBuffer.shift()); + } + } + this.currentFile = null; +}; + +/** + * @see GenericWorker.flush + */ +ZipFileWorker.prototype.flush = function () { + + var localDirLength = this.bytesWritten; + for(var i = 0; i < this.dirRecords.length; i++) { + this.push({ + data : this.dirRecords[i], + meta : {percent:100} + }); + } + var centralDirLength = this.bytesWritten - localDirLength; + + var dirEnd = generateCentralDirectoryEnd(this.dirRecords.length, centralDirLength, localDirLength, this.zipComment, this.encodeFileName); + + this.push({ + data : dirEnd, + meta : {percent:100} + }); +}; + +/** + * Prepare the next source to be read. + */ +ZipFileWorker.prototype.prepareNextSource = function () { + this.previous = this._sources.shift(); + this.openedSource(this.previous.streamInfo); + if (this.isPaused) { + this.previous.pause(); + } else { + this.previous.resume(); + } +}; + +/** + * @see GenericWorker.registerPrevious + */ +ZipFileWorker.prototype.registerPrevious = function (previous) { + this._sources.push(previous); + var self = this; + + previous.on("data", function (chunk) { + self.processChunk(chunk); + }); + previous.on("end", function () { + self.closedSource(self.previous.streamInfo); + if(self._sources.length) { + self.prepareNextSource(); + } else { + self.end(); + } + }); + previous.on("error", function (e) { + self.error(e); + }); + return this; +}; + +/** + * @see GenericWorker.resume + */ +ZipFileWorker.prototype.resume = function () { + if(!GenericWorker.prototype.resume.call(this)) { + return false; + } + + if (!this.previous && this._sources.length) { + this.prepareNextSource(); + return true; + } + if (!this.previous && !this._sources.length && !this.generatedError) { + this.end(); + return true; + } +}; + +/** + * @see GenericWorker.error + */ +ZipFileWorker.prototype.error = function (e) { + var sources = this._sources; + if(!GenericWorker.prototype.error.call(this, e)) { + return false; + } + for(var i = 0; i < sources.length; i++) { + try { + sources[i].error(e); + } catch(e) { + // the `error` exploded, nothing to do + } + } + return true; +}; + +/** + * @see GenericWorker.lock + */ +ZipFileWorker.prototype.lock = function () { + GenericWorker.prototype.lock.call(this); + var sources = this._sources; + for(var i = 0; i < sources.length; i++) { + sources[i].lock(); + } +}; + +module.exports = ZipFileWorker; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/generate/index.js b/ohos-jszip/library/src/main/core/jszip-master/lib/generate/index.js new file mode 100644 index 00000000..fe2bb41a --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/generate/index.js @@ -0,0 +1,70 @@ +"use strict"; + +var compressions = require("../compressions"); +var ZipFileWorker = require("./ZipFileWorker"); +var utils = require("../utils"); + +/** + * Find the compression to use. + * @param {String} fileCompression the compression defined at the file level, if any. + * @param {String} zipCompression the compression defined at the load() level. + * @return {Object} the compression object to use. + */ +var getCompression = function (fileCompression, zipCompression) { + + var compressionName = fileCompression || zipCompression; + var compression = compressions[compressionName]; + if (!compression) { + throw new Error(compressionName + " is not a valid compression method !"); + } + return compression; +}; + +/** + * Create a worker to generate a zip file. + * @param {JSZip} zip the JSZip instance at the right root level. + * @param {Object} options to generate the zip file. + * @param {String} comment the comment to use. + */ +exports.generateWorker = function (zip, options, comment) { + var encryptOptions = { + password: options.password, + strength: options.encryptStrength + }; + var zipFileWorker = new ZipFileWorker(options.streamFiles, comment, options.platform, options.encodeFileName); + var entriesCount = 0; + try { + + zip.forEach(function (relativePath, file) { + entriesCount++; + var compression = getCompression(file.options.compression, options.compression); + var compressionOptions = file.options.compressionOptions || options.compressionOptions || {}; + var dir = file.dir, date = file.date; + var fileEncryptOptions = utils.extend(file.encryptOptions || {}, encryptOptions); + if (!fileEncryptOptions.password) { + fileEncryptOptions.password = null; + } else if (typeof fileEncryptOptions.password !== "string") { + throw new Error("Password is not a valid string."); + }else{ + fileEncryptOptions.strength = fileEncryptOptions.strength || 3; + } + + file._compressWorker(compression, compressionOptions, fileEncryptOptions) + .withStreamInfo("file", { + name : relativePath, + dir : dir, + date : date, + comment : file.comment || "", + unixPermissions : file.unixPermissions, + dosPermissions : file.dosPermissions, + encryptOptions : fileEncryptOptions + }) + .pipe(zipFileWorker); + }); + zipFileWorker.entriesCount = entriesCount; + } catch (e) { + zipFileWorker.error(e); + } + + return zipFileWorker; +}; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/index.js b/ohos-jszip/library/src/main/core/jszip-master/lib/index.js new file mode 100644 index 00000000..358ba82e --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/index.js @@ -0,0 +1,55 @@ +"use strict"; + +/** + * Representation a of zip file in js + * @constructor + */ +function JSZip() { + // if this constructor is used without `new`, it adds `new` before itself: + if(!(this instanceof JSZip)) { + return new JSZip(); + } + + if(arguments.length) { + throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide."); + } + + // object containing the files : + // { + // "folder/" : {...}, + // "folder/data.txt" : {...} + // } + // NOTE: we use a null prototype because we do not + // want filenames like "toString" coming from a zip file + // to overwrite methods and attributes in a normal Object. + this.files = Object.create(null); + + this.comment = null; + + // Where we are in the hierarchy + this.root = ""; + this.clone = function() { + var newObj = new JSZip(); + for (var i in this) { + if (typeof this[i] !== "function") { + newObj[i] = this[i]; + } + } + return newObj; + }; +} +JSZip.prototype = require("./object"); +JSZip.prototype.loadAsync = require("./load"); +JSZip.support = require("./support"); +JSZip.defaults = require("./defaults"); + +// TODO find a better way to handle this version, +// a require('package.json').version doesn't work with webpack, see #327 +JSZip.version = "3.10.1"; + +JSZip.loadAsync = function (content, options) { + return new JSZip().loadAsync(content, options); +}; + +JSZip.external = require("./external"); +module.exports = JSZip; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/license_header.js b/ohos-jszip/library/src/main/core/jszip-master/lib/license_header.js new file mode 100644 index 00000000..7aab4ae8 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/license_header.js @@ -0,0 +1,11 @@ +/*! + +JSZip v__VERSION__ - A JavaScript class for generating and reading zip files + + +(c) 2009-2016 Stuart Knightley +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown. + +JSZip uses the library pako released under the MIT license : +https://github.com/nodeca/pako/blob/main/LICENSE +*/ diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/load.js b/ohos-jszip/library/src/main/core/jszip-master/lib/load.js new file mode 100644 index 00000000..c1dd2ce0 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/load.js @@ -0,0 +1,93 @@ +"use strict"; +var utils = require("./utils"); +var external = require("./external"); +var utf8 = require("./utf8"); +var ZipEntries = require("./zipEntries"); +var Crc32Probe = require("./stream/Crc32Probe"); +var nodejsUtils = require("./nodejsUtils"); + +/** + * Check the CRC32 of an entry. + * @param {ZipEntry} zipEntry the zip entry to check. + * @return {Promise} the result. + */ +function checkEntryCRC32(zipEntry) { + return new external.Promise(function (resolve, reject) { + if (zipEntry.options.aes.version === 2) { + reject(new Error("Encrypted zip : no CRC32 stored")); + return; + } + var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe()); + worker.on("error", function (e) { + reject(e); + }) + .on("end", function () { + if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) { + reject(new Error("Corrupted zip : CRC32 mismatch")); + } else { + resolve(); + } + }) + .resume(); + }); +} + +module.exports = function (data, options) { + var zip = this; + options = utils.extend(options || {}, { + base64: false, + password: null, + checkCRC32: false, + optimizedBinaryString: false, + createFolders: false, + decodeFileName: utf8.utf8decode + }); + + if (nodejsUtils.isNode && nodejsUtils.isStream(data)) { + return external.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")); + } + + return utils.prepareContent("the loaded zip file", data, true, options.optimizedBinaryString, options.base64) + .then(function (data) { + var zipEntries = new ZipEntries(options); + zipEntries.load(data); + return zipEntries; + }).then(function checkCRC32(zipEntries) { + var promises = [external.Promise.resolve(zipEntries)]; + var files = zipEntries.files; + if (options.checkCRC32) { + for (var i = 0; i < files.length; i++) { + promises.push(checkEntryCRC32(files[i])); + } + } + return external.Promise.all(promises); + }).then(function addFiles(results) { + var zipEntries = results.shift(); + var files = zipEntries.files; + for (var i = 0; i < files.length; i++) { + var input = files[i]; + + var unsafeName = input.fileNameStr; + var safeName = utils.resolve(input.fileNameStr); + + zip.file(safeName, input.decompressed, { + binary: true, + optimizedBinaryString: true, + date: input.date, + dir: input.dir, + comment: input.fileCommentStr.length ? input.fileCommentStr : null, + unixPermissions: input.unixPermissions, + dosPermissions: input.dosPermissions, + createFolders: options.createFolders + }); + if (!input.dir) { + zip.file(safeName).unsafeOriginalName = unsafeName; + } + } + if (zipEntries.zipComment.length) { + zip.comment = zipEntries.zipComment; + } + + return zip; + }); +}; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/nodejs/NodejsStreamInputAdapter.js b/ohos-jszip/library/src/main/core/jszip-master/lib/nodejs/NodejsStreamInputAdapter.js new file mode 100644 index 00000000..635c5047 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/nodejs/NodejsStreamInputAdapter.js @@ -0,0 +1,74 @@ +"use strict"; + +var utils = require("../utils"); +var GenericWorker = require("../stream/GenericWorker"); + +/** + * A worker that use a nodejs stream as source. + * @constructor + * @param {String} filename the name of the file entry for this stream. + * @param {Readable} stream the nodejs stream. + */ +function NodejsStreamInputAdapter(filename, stream) { + GenericWorker.call(this, "Nodejs stream input adapter for " + filename); + this._upstreamEnded = false; + this._bindStream(stream); +} + +utils.inherits(NodejsStreamInputAdapter, GenericWorker); + +/** + * Prepare the stream and bind the callbacks on it. + * Do this ASAP on node 0.10 ! A lazy binding doesn't always work. + * @param {Stream} stream the nodejs stream to use. + */ +NodejsStreamInputAdapter.prototype._bindStream = function (stream) { + var self = this; + this._stream = stream; + stream.pause(); + stream + .on("data", function (chunk) { + self.push({ + data: chunk, + meta : { + percent : 0 + } + }); + }) + .on("error", function (e) { + if(self.isPaused) { + this.generatedError = e; + } else { + self.error(e); + } + }) + .on("end", function () { + if(self.isPaused) { + self._upstreamEnded = true; + } else { + self.end(); + } + }); +}; +NodejsStreamInputAdapter.prototype.pause = function () { + if(!GenericWorker.prototype.pause.call(this)) { + return false; + } + this._stream.pause(); + return true; +}; +NodejsStreamInputAdapter.prototype.resume = function () { + if(!GenericWorker.prototype.resume.call(this)) { + return false; + } + + if(this._upstreamEnded) { + this.end(); + } else { + this._stream.resume(); + } + + return true; +}; + +module.exports = NodejsStreamInputAdapter; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/nodejs/NodejsStreamOutputAdapter.js b/ohos-jszip/library/src/main/core/jszip-master/lib/nodejs/NodejsStreamOutputAdapter.js new file mode 100644 index 00000000..e6aafb9b --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/nodejs/NodejsStreamOutputAdapter.js @@ -0,0 +1,42 @@ +"use strict"; + +var Readable = require("readable-stream").Readable; + +var utils = require("../utils"); +utils.inherits(NodejsStreamOutputAdapter, Readable); + +/** +* A nodejs stream using a worker as source. +* @see the SourceWrapper in http://nodejs.org/api/stream.html +* @constructor +* @param {StreamHelper} helper the helper wrapping the worker +* @param {Object} options the nodejs stream options +* @param {Function} updateCb the update callback. +*/ +function NodejsStreamOutputAdapter(helper, options, updateCb) { + Readable.call(this, options); + this._helper = helper; + + var self = this; + helper.on("data", function (data, meta) { + if (!self.push(data)) { + self._helper.pause(); + } + if(updateCb) { + updateCb(meta); + } + }) + .on("error", function(e) { + self.emit("error", e); + }) + .on("end", function () { + self.push(null); + }); +} + + +NodejsStreamOutputAdapter.prototype._read = function() { + this._helper.resume(); +}; + +module.exports = NodejsStreamOutputAdapter; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/nodejsUtils.js b/ohos-jszip/library/src/main/core/jszip-master/lib/nodejsUtils.js new file mode 100644 index 00000000..6d9b3c3f --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/nodejsUtils.js @@ -0,0 +1,57 @@ +"use strict"; + +module.exports = { + /** + * True if this is running in Nodejs, will be undefined in a browser. + * In a browser, browserify won't include this file and the whole module + * will be resolved an empty object. + */ + isNode : typeof Buffer !== "undefined", + /** + * Create a new nodejs Buffer from an existing content. + * @param {Object} data the data to pass to the constructor. + * @param {String} encoding the encoding to use. + * @return {Buffer} a new Buffer. + */ + newBufferFrom: function(data, encoding) { + if (Buffer.from && Buffer.from !== Uint8Array.from) { + return Buffer.from(data, encoding); + } else { + if (typeof data === "number") { + // Safeguard for old Node.js versions. On newer versions, + // Buffer.from(number) / Buffer(number, encoding) already throw. + throw new Error("The \"data\" argument must not be a number"); + } + return new Buffer(data, encoding); + } + }, + /** + * Create a new nodejs Buffer with the specified size. + * @param {Integer} size the size of the buffer. + * @return {Buffer} a new Buffer. + */ + allocBuffer: function (size) { + if (Buffer.alloc) { + return Buffer.alloc(size); + } else { + var buf = new Buffer(size); + buf.fill(0); + return buf; + } + }, + /** + * Find out if an object is a Buffer. + * @param {Object} b the object to test. + * @return {Boolean} true if the object is a Buffer, false otherwise. + */ + isBuffer : function(b){ + return Buffer.isBuffer(b); + }, + + isStream : function (obj) { + return obj && + typeof obj.on === "function" && + typeof obj.pause === "function" && + typeof obj.resume === "function"; + } +}; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/object.js b/ohos-jszip/library/src/main/core/jszip-master/lib/object.js new file mode 100644 index 00000000..414d5c2d --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/object.js @@ -0,0 +1,386 @@ +"use strict"; +var utf8 = require("./utf8"); +var utils = require("./utils"); +var GenericWorker = require("./stream/GenericWorker"); +var StreamHelper = require("./stream/StreamHelper"); +var defaults = require("./defaults"); +var CompressedObject = require("./compressedObject"); +var ZipObject = require("./zipObject"); +var generate = require("./generate"); +var nodejsUtils = require("./nodejsUtils"); +var NodejsStreamInputAdapter = require("./nodejs/NodejsStreamInputAdapter"); + + +/** + * Add a file in the current folder. + * @private + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file + * @param {Object} originalOptions the options of the file + * @return {Object} the new file. + */ +var fileAdd = function(name, data, originalOptions) { + // be sure sub folders exist + var dataType = utils.getTypeOf(data), + parent; + + + /* + * Correct options. + */ + + var o = utils.extend(originalOptions || {}, defaults); + o.date = o.date || new Date(); + if (o.compression !== null) { + o.compression = o.compression.toUpperCase(); + } + + if (typeof o.unixPermissions === "string") { + o.unixPermissions = parseInt(o.unixPermissions, 8); + } + + // UNX_IFDIR 0040000 see zipinfo.c + if (o.unixPermissions && (o.unixPermissions & 0x4000)) { + o.dir = true; + } + // Bit 4 Directory + if (o.dosPermissions && (o.dosPermissions & 0x0010)) { + o.dir = true; + } + + if (o.dir) { + name = forceTrailingSlash(name); + } + if (o.createFolders && (parent = parentFolder(name))) { + folderAdd.call(this, parent, true); + } + + var isUnicodeString = dataType === "string" && o.binary === false && o.base64 === false; + if (!originalOptions || typeof originalOptions.binary === "undefined") { + o.binary = !isUnicodeString; + } + + + var isCompressedEmpty = (data instanceof CompressedObject) && data.uncompressedSize === 0; + + if (isCompressedEmpty || o.dir || !data || data.length === 0) { + o.base64 = false; + o.binary = true; + data = ""; + o.compression = "STORE"; + dataType = "string"; + } + + /* + * Convert content to fit. + */ + + var zipObjectContent = null; + if (data instanceof CompressedObject || data instanceof GenericWorker) { + zipObjectContent = data; + } else if (nodejsUtils.isNode && nodejsUtils.isStream(data)) { + zipObjectContent = new NodejsStreamInputAdapter(name, data); + } else { + zipObjectContent = utils.prepareContent(name, data, o.binary, o.optimizedBinaryString, o.base64); + } + + var object = new ZipObject(name, zipObjectContent, o); + this.files[name] = object; + /* + TODO: we can't throw an exception because we have async promises + (we can have a promise of a Date() for example) but returning a + promise is useless because file(name, data) returns the JSZip + object for chaining. Should we break that to allow the user + to catch the error ? + + return external.Promise.resolve(zipObjectContent) + .then(function () { + return object; + }); + */ +}; + +/** + * Find the parent folder of the path. + * @private + * @param {string} path the path to use + * @return {string} the parent folder, or "" + */ +var parentFolder = function (path) { + if (path.slice(-1) === "/") { + path = path.substring(0, path.length - 1); + } + var lastSlash = path.lastIndexOf("/"); + return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; +}; + +/** + * Returns the path with a slash at the end. + * @private + * @param {String} path the path to check. + * @return {String} the path with a trailing slash. + */ +var forceTrailingSlash = function(path) { + // Check the name ends with a / + if (path.slice(-1) !== "/") { + path += "/"; // IE doesn't like substr(-1) + } + return path; +}; + +/** + * Add a (sub) folder in the current folder. + * @private + * @param {string} name the folder's name + * @param {boolean=} [createFolders] If true, automatically create sub + * folders. Defaults to false. + * @return {Object} the new folder. + */ +var folderAdd = function(name, createFolders) { + createFolders = (typeof createFolders !== "undefined") ? createFolders : defaults.createFolders; + + name = forceTrailingSlash(name); + + // Does this folder already exist? + if (!this.files[name]) { + fileAdd.call(this, name, null, { + dir: true, + createFolders: createFolders + }); + } + return this.files[name]; +}; + +/** +* Cross-window, cross-Node-context regular expression detection +* @param {Object} object Anything +* @return {Boolean} true if the object is a regular expression, +* false otherwise +*/ +function isRegExp(object) { + return Object.prototype.toString.call(object) === "[object RegExp]"; +} + +// return the actual prototype of JSZip +var out = { + /** + * @see loadAsync + */ + load: function() { + throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); + }, + + + /** + * Call a callback function for each entry at this folder level. + * @param {Function} cb the callback function: + * function (relativePath, file) {...} + * It takes 2 arguments : the relative path and the file. + */ + forEach: function(cb) { + var filename, relativePath, file; + // ignore warning about unwanted properties because this.files is a null prototype object + /* eslint-disable-next-line guard-for-in */ + for (filename in this.files) { + file = this.files[filename]; + relativePath = filename.slice(this.root.length, filename.length); + if (relativePath && filename.slice(0, this.root.length) === this.root) { // the file is in the current root + cb(relativePath, file); // TODO reverse the parameters ? need to be clean AND consistent with the filter search fn... + } + } + }, + + /** + * Filter nested files/folders with the specified function. + * @param {Function} search the predicate to use : + * function (relativePath, file) {...} + * It takes 2 arguments : the relative path and the file. + * @return {Array} An array of matching elements. + */ + filter: function(search) { + var result = []; + this.forEach(function (relativePath, entry) { + if (search(relativePath, entry)) { // the file matches the function + result.push(entry); + } + + }); + return result; + }, + + /** + * Add a file to the zip file, or search a file. + * @param {string|RegExp} name The name of the file to add (if data is defined), + * the name of the file to find (if no data) or a regex to match files. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded + * @param {Object} o File options + * @return {JSZip|Object|Array} this JSZip object (when adding a file), + * a file (when searching by string) or an array of files (when searching by regex). + */ + file: function(name, data, o) { + if (arguments.length === 1) { + if (isRegExp(name)) { + var regexp = name; + return this.filter(function(relativePath, file) { + return !file.dir && regexp.test(relativePath); + }); + } + else { // text + var obj = this.files[this.root + name]; + if (obj && !obj.dir) { + return obj; + } else { + return null; + } + } + } + else { // more than one argument : we have data ! + name = this.root + name; + fileAdd.call(this, name, data, o); + } + return this; + }, + + /** + * Add a directory to the zip file, or search. + * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. + * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. + */ + folder: function(arg) { + if (!arg) { + return this; + } + + if (isRegExp(arg)) { + return this.filter(function(relativePath, file) { + return file.dir && arg.test(relativePath); + }); + } + + // else, name is a new folder + var name = this.root + arg; + var newFolder = folderAdd.call(this, name); + + // Allow chaining by returning a new object with this folder as the root + var ret = this.clone(); + ret.root = newFolder.name; + return ret; + }, + + /** + * Delete a file, or a directory and all sub-files, from the zip + * @param {string} name the name of the file to delete + * @return {JSZip} this JSZip object + */ + remove: function(name) { + name = this.root + name; + var file = this.files[name]; + if (!file) { + // Look for any folders + if (name.slice(-1) !== "/") { + name += "/"; + } + file = this.files[name]; + } + + if (file && !file.dir) { + // file + delete this.files[name]; + } else { + // maybe a folder, delete recursively + var kids = this.filter(function(relativePath, file) { + return file.name.slice(0, name.length) === name; + }); + for (var i = 0; i < kids.length; i++) { + delete this.files[kids[i].name]; + } + } + + return this; + }, + + /** + * @deprecated This method has been removed in JSZip 3.0, please check the upgrade guide. + */ + generate: function() { + throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); + }, + + /** + * Generate the complete zip file as an internal stream. + * @param {Object} options the options to generate the zip file : + * - compression, "STORE" by default. + * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. + * @return {StreamHelper} the streamed zip file. + */ + generateInternalStream: function (options) { + var worker, opts = {}; + try { + opts = utils.extend(options || {}, { + streamFiles: false, + compression: "STORE", + compressionOptions : null, + password: null, + encryptStrength: null, + type: "", + platform: "DOS", + comment: null, + mimeType: "application/zip", + encodeFileName: utf8.utf8encode + }); + + opts.type = opts.type.toLowerCase(); + opts.compression = opts.compression.toUpperCase(); + + // "binarystring" is preferred but the internals use "string". + if (opts.type === "binarystring") { + opts.type = "string"; + } + + if (!opts.type) { + throw new Error("No output type specified."); + } + + utils.checkSupport(opts.type); + + // accept nodejs `process.platform` + if ( + opts.platform === "darwin" || + opts.platform === "freebsd" || + opts.platform === "linux" || + opts.platform === "sunos" + ) { + opts.platform = "UNIX"; + } + if (opts.platform === "win32") { + opts.platform = "DOS"; + } + + var comment = opts.comment || this.comment || ""; + worker = generate.generateWorker(this, opts, comment); + } catch (e) { + worker = new GenericWorker("error"); + worker.error(e); + } + return new StreamHelper(worker, opts.type || "string", opts.mimeType); + }, + /** + * Generate the complete zip file asynchronously. + * @see generateInternalStream + */ + generateAsync: function(options, onUpdate) { + return this.generateInternalStream(options).accumulate(onUpdate); + }, + /** + * Generate the complete zip file asynchronously. + * @see generateInternalStream + */ + generateNodeStream: function(options, onUpdate) { + options = options || {}; + if (!options.type) { + options.type = "nodebuffer"; + } + return this.generateInternalStream(options).toNodejsStream(onUpdate); + } +}; +module.exports = out; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/readable-stream-browser.js b/ohos-jszip/library/src/main/core/jszip-master/lib/readable-stream-browser.js new file mode 100644 index 00000000..a07d91ab --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/readable-stream-browser.js @@ -0,0 +1,10 @@ +"use strict"; +/* + * This file is used by module bundlers (browserify/webpack/etc) when + * including a stream implementation. We use "readable-stream" to get a + * consistent behavior between nodejs versions but bundlers often have a shim + * for "stream". Using this shim greatly improve the compatibility and greatly + * reduce the final size of the bundle (only one stream implementation, not + * two). + */ +module.exports = require("stream"); diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/reader/ArrayReader.js b/ohos-jszip/library/src/main/core/jszip-master/lib/reader/ArrayReader.js new file mode 100644 index 00000000..32a9569b --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/reader/ArrayReader.js @@ -0,0 +1,57 @@ +"use strict"; +var DataReader = require("./DataReader"); +var utils = require("../utils"); + +function ArrayReader(data) { + DataReader.call(this, data); + for(var i = 0; i < this.data.length; i++) { + data[i] = data[i] & 0xFF; + } +} +utils.inherits(ArrayReader, DataReader); +/** + * @see DataReader.byteAt + */ +ArrayReader.prototype.byteAt = function(i) { + return this.data[this.zero + i]; +}; +/** + * @see DataReader.lastIndexOfSignature + */ +ArrayReader.prototype.lastIndexOfSignature = function(sig) { + var sig0 = sig.charCodeAt(0), + sig1 = sig.charCodeAt(1), + sig2 = sig.charCodeAt(2), + sig3 = sig.charCodeAt(3); + for (var i = this.length - 4; i >= 0; --i) { + if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) { + return i - this.zero; + } + } + + return -1; +}; +/** + * @see DataReader.readAndCheckSignature + */ +ArrayReader.prototype.readAndCheckSignature = function (sig) { + var sig0 = sig.charCodeAt(0), + sig1 = sig.charCodeAt(1), + sig2 = sig.charCodeAt(2), + sig3 = sig.charCodeAt(3), + data = this.readData(4); + return sig0 === data[0] && sig1 === data[1] && sig2 === data[2] && sig3 === data[3]; +}; +/** + * @see DataReader.readData + */ +ArrayReader.prototype.readData = function(size) { + this.checkOffset(size); + if(size === 0) { + return []; + } + var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = ArrayReader; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/reader/DataReader.js b/ohos-jszip/library/src/main/core/jszip-master/lib/reader/DataReader.js new file mode 100644 index 00000000..b61b839b --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/reader/DataReader.js @@ -0,0 +1,116 @@ +"use strict"; +var utils = require("../utils"); + +function DataReader(data) { + this.data = data; // type : see implementation + this.length = data.length; + this.index = 0; + this.zero = 0; +} +DataReader.prototype = { + /** + * Check that the offset will not go too far. + * @param {string} offset the additional offset to check. + * @throws {Error} an Error if the offset is out of bounds. + */ + checkOffset: function(offset) { + this.checkIndex(this.index + offset); + }, + /** + * Check that the specified index will not be too far. + * @param {string} newIndex the index to check. + * @throws {Error} an Error if the index is out of bounds. + */ + checkIndex: function(newIndex) { + if (this.length < this.zero + newIndex || newIndex < 0) { + throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?"); + } + }, + /** + * Change the index. + * @param {number} newIndex The new index. + * @throws {Error} if the new index is out of the data. + */ + setIndex: function(newIndex) { + this.checkIndex(newIndex); + this.index = newIndex; + }, + /** + * Skip the next n bytes. + * @param {number} n the number of bytes to skip. + * @throws {Error} if the new index is out of the data. + */ + skip: function(n) { + this.setIndex(this.index + n); + }, + /** + * Get the byte at the specified index. + * @param {number} i the index to use. + * @return {number} a byte. + */ + byteAt: function() { + // see implementations + }, + /** + * Get the next number with a given byte size. + * @param {number} size the number of bytes to read. + * @return {number} the corresponding number. + */ + readInt: function(size) { + var result = 0, + i; + this.checkOffset(size); + for (i = this.index + size - 1; i >= this.index; i--) { + result = (result << 8) + this.byteAt(i); + } + this.index += size; + return result; + }, + /** + * Get the next string with a given byte size. + * @param {number} size the number of bytes to read. + * @return {string} the corresponding string. + */ + readString: function(size) { + return utils.transformTo("string", this.readData(size)); + }, + /** + * Get raw data without conversion, bytes. + * @param {number} size the number of bytes to read. + * @return {Object} the raw data, implementation specific. + */ + readData: function() { + // see implementations + }, + /** + * Find the last occurrence of a zip signature (4 bytes). + * @param {string} sig the signature to find. + * @return {number} the index of the last occurrence, -1 if not found. + */ + lastIndexOfSignature: function() { + // see implementations + }, + /** + * Read the signature (4 bytes) at the current position and compare it with sig. + * @param {string} sig the expected signature + * @return {boolean} true if the signature matches, false otherwise. + */ + readAndCheckSignature: function() { + // see implementations + }, + /** + * Get the next date. + * @return {Date} the date. + */ + readDate: function() { + var dostime = this.readInt(4); + return new Date(Date.UTC( + ((dostime >> 25) & 0x7f) + 1980, // year + ((dostime >> 21) & 0x0f) - 1, // month + (dostime >> 16) & 0x1f, // day + (dostime >> 11) & 0x1f, // hour + (dostime >> 5) & 0x3f, // minute + (dostime & 0x1f) << 1)); // second + } +}; +module.exports = DataReader; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/reader/NodeBufferReader.js b/ohos-jszip/library/src/main/core/jszip-master/lib/reader/NodeBufferReader.js new file mode 100644 index 00000000..cbedf258 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/reader/NodeBufferReader.js @@ -0,0 +1,19 @@ +"use strict"; +var Uint8ArrayReader = require("./Uint8ArrayReader"); +var utils = require("../utils"); + +function NodeBufferReader(data) { + Uint8ArrayReader.call(this, data); +} +utils.inherits(NodeBufferReader, Uint8ArrayReader); + +/** + * @see DataReader.readData + */ +NodeBufferReader.prototype.readData = function(size) { + this.checkOffset(size); + var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = NodeBufferReader; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/reader/StringReader.js b/ohos-jszip/library/src/main/core/jszip-master/lib/reader/StringReader.js new file mode 100644 index 00000000..fc90784a --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/reader/StringReader.js @@ -0,0 +1,38 @@ +"use strict"; +var DataReader = require("./DataReader"); +var utils = require("../utils"); + +function StringReader(data) { + DataReader.call(this, data); +} +utils.inherits(StringReader, DataReader); +/** + * @see DataReader.byteAt + */ +StringReader.prototype.byteAt = function(i) { + return this.data.charCodeAt(this.zero + i); +}; +/** + * @see DataReader.lastIndexOfSignature + */ +StringReader.prototype.lastIndexOfSignature = function(sig) { + return this.data.lastIndexOf(sig) - this.zero; +}; +/** + * @see DataReader.readAndCheckSignature + */ +StringReader.prototype.readAndCheckSignature = function (sig) { + var data = this.readData(4); + return sig === data; +}; +/** + * @see DataReader.readData + */ +StringReader.prototype.readData = function(size) { + this.checkOffset(size); + // this will work because the constructor applied the "& 0xff" mask. + var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = StringReader; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/reader/Uint8ArrayReader.js b/ohos-jszip/library/src/main/core/jszip-master/lib/reader/Uint8ArrayReader.js new file mode 100644 index 00000000..2bf2bdcf --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/reader/Uint8ArrayReader.js @@ -0,0 +1,22 @@ +"use strict"; +var ArrayReader = require("./ArrayReader"); +var utils = require("../utils"); + +function Uint8ArrayReader(data) { + ArrayReader.call(this, data); +} +utils.inherits(Uint8ArrayReader, ArrayReader); +/** + * @see DataReader.readData + */ +Uint8ArrayReader.prototype.readData = function(size) { + this.checkOffset(size); + if(size === 0) { + // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. + return new Uint8Array(0); + } + var result = this.data.subarray(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = Uint8ArrayReader; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/reader/readerFor.js b/ohos-jszip/library/src/main/core/jszip-master/lib/reader/readerFor.js new file mode 100644 index 00000000..7558eb4f --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/reader/readerFor.js @@ -0,0 +1,28 @@ +"use strict"; + +var utils = require("../utils"); +var support = require("../support"); +var ArrayReader = require("./ArrayReader"); +var StringReader = require("./StringReader"); +var NodeBufferReader = require("./NodeBufferReader"); +var Uint8ArrayReader = require("./Uint8ArrayReader"); + +/** + * Create a reader adapted to the data. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data to read. + * @return {DataReader} the data reader. + */ +module.exports = function (data) { + var type = utils.getTypeOf(data); + utils.checkSupport(type); + if (type === "string" && !support.uint8array) { + return new StringReader(data); + } + if (type === "nodebuffer") { + return new NodeBufferReader(data); + } + if (support.uint8array) { + return new Uint8ArrayReader(utils.transformTo("uint8array", data)); + } + return new ArrayReader(utils.transformTo("array", data)); +}; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/signature.js b/ohos-jszip/library/src/main/core/jszip-master/lib/signature.js new file mode 100644 index 00000000..a799611f --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/signature.js @@ -0,0 +1,7 @@ +"use strict"; +exports.LOCAL_FILE_HEADER = "PK\x03\x04"; +exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; +exports.CENTRAL_DIRECTORY_END = "PK\x05\x06"; +exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07"; +exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; +exports.DATA_DESCRIPTOR = "PK\x07\x08"; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/sjcl.js b/ohos-jszip/library/src/main/core/jszip-master/lib/sjcl.js new file mode 100644 index 00000000..463be236 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/sjcl.js @@ -0,0 +1,1056 @@ +/** @fileOverview Javascript cryptography implementation. + * + * Crush to remove comments, shorten variable names and + * generally reduce transmission size. + * + * @author Emily Stark + * @author Mike Hamburg + * @author Dan Boneh + */ + +"use strict"; +/* Define global function getRandomValues if not use in support js env(browser or node.js) */ +/* global getRandomValues */ +var crypto = require("crypto"); + +/** + * The Stanford Javascript Crypto Library, top-level namespace. + * @namespace + */ +var sjcl = { + /** + * Symmetric ciphers. + * @namespace + */ + cipher: {}, + + /** + * Hash functions. + * @namespace + */ + hash: {}, + + /** + * Key exchange functions. Right now only SRP is implemented. + * @namespace + */ + keyexchange: {}, + + /** + * Cipher modes of operation. + * @namespace + */ + mode: {}, + + /** + * Miscellaneous. HMAC and PBKDF2. + * @namespace + */ + misc: {}, + + /** + * Bit array encoders and decoders. + * @namespace + * + * @description + * The members of this namespace are functions which translate between + * SJCL's bitArrays and other objects (usually strings). Because it + * isn't always clear which direction is encoding and which is decoding, + * the method names are "fromBits" and "toBits". + */ + codec: {}, + + /** + * Exceptions. + * @namespace + */ + exception: { + /** + * Ciphertext is corrupt. + * @constructor + */ + corrupt: function (message) { + this.toString = function () { return "CORRUPT: " + this.message; }; + this.message = message; + }, + + /** + * Invalid parameter. + * @constructor + */ + invalid: function (message) { + this.toString = function () { return "INVALID: " + this.message; }; + this.message = message; + }, + + /** + * Bug or missing feature in SJCL. + * @constructor + */ + bug: function (message) { + this.toString = function () { return "BUG: " + this.message; }; + this.message = message; + }, + + /** + * Something isn't ready. + * @constructor + */ + notReady: function (message) { + this.toString = function () { return "NOT READY: " + this.message; }; + this.message = message; + } + } +}; + +/** @fileOverview Arrays of bits, encoded as arrays of Numbers. + * + * @author Emily Stark + * @author Mike Hamburg + * @author Dan Boneh + */ + +/** + * Arrays of bits, encoded as arrays of Numbers. + * @namespace + * @description + *

    + * These objects are the currency accepted by SJCL's crypto functions. + *

    + * + *

    + * Most of our crypto primitives operate on arrays of 4-byte words internally, + * but many of them can take arguments that are not a multiple of 4 bytes. + * This library encodes arrays of bits (whose size need not be a multiple of 8 + * bits) as arrays of 32-bit words. The bits are packed, big-endian, into an + * array of words, 32 bits at a time. Since the words are double-precision + * floating point numbers, they fit some extra data. We use this (in a private, + * possibly-changing manner) to encode the number of bits actually present + * in the last word of the array. + *

    + * + *

    + * Because bitwise ops clear this out-of-band data, these arrays can be passed + * to ciphers like AES which want arrays of words. + *

    + */ +sjcl.bitArray = { + /** + * Array slices in units of bits. + * @param {bitArray} a The array to slice. + * @param {Number} bstart The offset to the start of the slice, in bits. + * @param {Number} bend The offset to the end of the slice, in bits. If this is undefined, + * slice until the end of the array. + * @return {bitArray} The requested slice. + */ + bitSlice: function (a, bstart, bend) { + a = sjcl.bitArray._shiftRight(a.slice(bstart / 32), 32 - (bstart & 31)).slice(1); + return (bend === undefined) ? a : sjcl.bitArray.clamp(a, bend - bstart); + }, + + /** + * Concatenate two bit arrays. + * @param {bitArray} a1 The first array. + * @param {bitArray} a2 The second array. + * @return {bitArray} The concatenation of a1 and a2. + */ + concat: function (a1, a2) { + if (a1.length === 0 || a2.length === 0) { + return a1.concat(a2); + } + + var last = a1[a1.length - 1], shift = sjcl.bitArray.getPartial(last); + if (shift === 32) { + return a1.concat(a2); + } else { + return sjcl.bitArray._shiftRight(a2, shift, last | 0, a1.slice(0, a1.length - 1)); + } + }, + + /** + * Find the length of an array of bits. + * @param {bitArray} a The array. + * @return {Number} The length of a, in bits. + */ + bitLength: function (a) { + var l = a.length, x; + if (l === 0) { return 0; } + x = a[l - 1]; + return (l - 1) * 32 + sjcl.bitArray.getPartial(x); + }, + + /** + * Truncate an array. + * @param {bitArray} a The array. + * @param {Number} len The length to truncate to, in bits. + * @return {bitArray} A new array, truncated to len bits. + */ + clamp: function (a, len) { + if (a.length * 32 < len) { return a; } + a = a.slice(0, Math.ceil(len / 32)); + var l = a.length; + len = len & 31; + if (l > 0 && len) { + a[l - 1] = sjcl.bitArray.partial(len, a[l - 1] & 0x80000000 >> (len - 1), 1); + } + return a; + }, + + /** + * Make a partial word for a bit array. + * @param {Number} len The number of bits in the word. + * @param {Number} x The bits. + * @param {Number} [_end=0] Pass 1 if x has already been shifted to the high side. + * @return {Number} The partial word. + */ + partial: function (len, x, _end) { + if (len === 32) { return x; } + return (_end ? x | 0 : x << (32 - len)) + len * 0x10000000000; + }, + + /** + * Get the number of bits used by a partial word. + * @param {Number} x The partial word. + * @return {Number} The number of bits used by the partial word. + */ + getPartial: function (x) { + return Math.round(x / 0x10000000000) || 32; + }, + + /** + * Compare two arrays for equality in a predictable amount of time. + * @param {bitArray} a The first array. + * @param {bitArray} b The second array. + * @return {boolean} true if a == b; false otherwise. + */ + equal: function (a, b) { + if (sjcl.bitArray.bitLength(a) !== sjcl.bitArray.bitLength(b)) { + return false; + } + var x = 0, i; + for (i = 0; i < a.length; i++) { + x |= a[i] ^ b[i]; + } + return (x === 0); + }, + + /** Shift an array right. + * @param {bitArray} a The array to shift. + * @param {Number} shift The number of bits to shift. + * @param {Number} [carry=0] A byte to carry in + * @param {bitArray} [out=[]] An array to prepend to the output. + * @private + */ + _shiftRight: function (a, shift, carry, out) { + var i, last2 = 0, shift2; + if (out === undefined) { out = []; } + + for (; shift >= 32; shift -= 32) { + out.push(carry); + carry = 0; + } + if (shift === 0) { + return out.concat(a); + } + + for (i = 0; i < a.length; i++) { + out.push(carry | a[i] >>> shift); + carry = a[i] << (32 - shift); + } + last2 = a.length ? a[a.length - 1] : 0; + shift2 = sjcl.bitArray.getPartial(last2); + out.push(sjcl.bitArray.partial(shift + shift2 & 31, (shift + shift2 > 32) ? carry : out.pop(), 1)); + return out; + } +}; + +/** @fileOverview Bit array codec implementations. + * + * @author Emily Stark + * @author Mike Hamburg + * @author Dan Boneh + */ + +/** + * Arrays of bytes + * @namespace + */ +sjcl.codec.bytes = { + /** Convert from a bitArray to an array of bytes. */ + fromBits: function (arr) { + var out = [], bl = sjcl.bitArray.bitLength(arr), i, tmp; + for (i = 0; i < bl / 8; i++) { + if ((i & 3) === 0) { + tmp = arr[i / 4]; + } + out.push(tmp >>> 24); + tmp <<= 8; + } + return out; + }, + /** Convert from an array of bytes to a bitArray. */ + toBits: function (bytes) { + var out = [], i, tmp = 0; + for (i = 0; i < bytes.length; i++) { + tmp = tmp << 8 | bytes[i]; + if ((i & 3) === 3) { + out.push(tmp); + tmp = 0; + } + } + if (i & 3) { + out.push(sjcl.bitArray.partial(8 * (i & 3), tmp)); + } + return out; + } +}; + +/** @fileOverview Bit array codec implementations. + * + * @author Emily Stark + * @author Mike Hamburg + * @author Dan Boneh + */ + +/** + * UTF-8 strings + * @namespace + */ +sjcl.codec.utf8String = { + /** Convert from a bitArray to a UTF-8 string. */ + fromBits: function (arr) { + var out = "", bl = sjcl.bitArray.bitLength(arr), i, tmp; + for (i = 0; i < bl / 8; i++) { + if ((i & 3) === 0) { + tmp = arr[i / 4]; + } + out += String.fromCharCode(tmp >>> 8 >>> 8 >>> 8); + tmp <<= 8; + } + return decodeURIComponent(escape(out)); + }, + + /** Convert from a UTF-8 string to a bitArray. */ + toBits: function (str) { + str = unescape(encodeURIComponent(str)); + var out = [], i, tmp = 0; + for (i = 0; i < str.length; i++) { + tmp = tmp << 8 | str.charCodeAt(i); + if ((i & 3) === 3) { + out.push(tmp); + tmp = 0; + } + } + if (i & 3) { + out.push(sjcl.bitArray.partial(8 * (i & 3), tmp)); + } + return out; + } +}; + +/** @fileOverview Javascript SHA-1 implementation. + * + * Based on the implementation in RFC 3174, method 1, and on the SJCL + * SHA-256 implementation. + * + * @author Quinn Slack + */ + +/** + * Context for a SHA-1 operation in progress. + * @constructor + */ +sjcl.hash.sha1 = function (hash) { + if (hash) { + this._h = hash._h.slice(0); + this._buffer = hash._buffer.slice(0); + this._length = hash._length; + } else { + this.reset(); + } +}; + +/** + * Hash a string or an array of words. + * @static + * @param {bitArray|String} data the data to hash. + * @return {bitArray} The hash value, an array of 5 big-endian words. + */ +sjcl.hash.sha1.hash = function (data) { + return (new sjcl.hash.sha1()).update(data).finalize(); +}; + +sjcl.hash.sha1.prototype = { + /** + * The hash's block size, in bits. + * @constant + */ + blockSize: 512, + + /** + * Reset the hash state. + * @return this + */ + reset: function () { + this._h = this._init.slice(0); + this._buffer = []; + this._length = 0; + return this; + }, + + /** + * Input several words to the hash. + * @param {bitArray|String} data the data to hash. + * @return this + */ + update: function (data) { + if (typeof data === "string") { + data = sjcl.codec.utf8String.toBits(data); + } + var i, b = this._buffer = sjcl.bitArray.concat(this._buffer, data), + ol = this._length, + nl = this._length = ol + sjcl.bitArray.bitLength(data); + if (nl > 9007199254740991) { + throw new sjcl.exception.invalid("Cannot hash more than 2^53 - 1 bits"); + } + + if (typeof Uint32Array !== "undefined") { + var c = new Uint32Array(b); + var j = 0; + for (i = this.blockSize + ol - ((this.blockSize + ol) & (this.blockSize - 1)); i <= nl; + i += this.blockSize) { + this._block(c.subarray(16 * j, 16 * (j + 1))); + j += 1; + } + b.splice(0, 16 * j); + } else { + for (i = this.blockSize + ol - ((this.blockSize + ol) & (this.blockSize - 1)); i <= nl; + i += this.blockSize) { + this._block(b.splice(0, 16)); + } + } + return this; + }, + + /** + * Complete hashing and output the hash value. + * @return {bitArray} The hash value, an array of 5 big-endian words. TODO + */ + finalize: function () { + var i, b = this._buffer, h = this._h; + + // Round out and push the buffer + b = sjcl.bitArray.concat(b, [sjcl.bitArray.partial(1, 1)]); + // Round out the buffer to a multiple of 16 words, less the 2 length words. + for (i = b.length + 2; i & 15; i++) { + b.push(0); + } + + // append the length + b.push(Math.floor(this._length / 0x100000000)); + b.push(this._length | 0); + + while (b.length) { + this._block(b.splice(0, 16)); + } + + this.reset(); + return h; + }, + + /** + * The SHA-1 initialization vector. + * @private + */ + _init: [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0], + + /** + * The SHA-1 hash key. + * @private + */ + _key: [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6], + + /** + * The SHA-1 logical functions f(0), f(1), ..., f(79). + * @private + */ + _f: function (t, b, c, d) { + if (t <= 19) { + return (b & c) | (~b & d); + } else if (t <= 39) { + return b ^ c ^ d; + } else if (t <= 59) { + return (b & c) | (b & d) | (c & d); + } else if (t <= 79) { + return b ^ c ^ d; + } + }, + + /** + * Circular left-shift operator. + * @private + */ + _S: function (n, x) { + return (x << n) | (x >>> 32 - n); + }, + + /** + * Perform one cycle of SHA-1. + * @param {Uint32Array|bitArray} words one block of words. + * @private + */ + _block: function (words) { + var t, tmp, a, b, c, d, e, + h = this._h; + var w; + if (typeof Uint32Array !== "undefined") { + // When words is passed to _block, it has 16 elements. SHA1 _block + // function extends words with new elements (at the end there are 80 elements). + // The problem is that if we use Uint32Array instead of Array, + // the length of Uint32Array cannot be changed. Thus, we replace words with a + // normal Array here. + w = Array(80); // do not use Uint32Array here as the instantiation is slower + for (var j = 0; j < 16; j++) { + w[j] = words[j]; + } + } else { + w = words; + } + + a = h[0]; b = h[1]; c = h[2]; d = h[3]; e = h[4]; + + for (t = 0; t <= 79; t++) { + if (t >= 16) { + w[t] = this._S(1, w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]); + } + tmp = (this._S(5, a) + this._f(t, b, c, d) + e + w[t] + + this._key[Math.floor(t / 20)]) | 0; + e = d; + d = c; + c = this._S(30, b); + b = a; + a = tmp; + } + + h[0] = (h[0] + a) | 0; + h[1] = (h[1] + b) | 0; + h[2] = (h[2] + c) | 0; + h[3] = (h[3] + d) | 0; + h[4] = (h[4] + e) | 0; + } +}; + +/** @fileOverview Low-level AES implementation. + * + * This file contains a low-level implementation of AES, optimized for + * size and for efficiency on several browsers. It is based on + * OpenSSL's aes_core.c, a public-domain implementation by Vincent + * Rijmen, Antoon Bosselaers and Paulo Barreto. + * + * An older version of this implementation is available in the public + * domain, but this one is (c) Emily Stark, Mike Hamburg, Dan Boneh, + * Stanford University 2008-2010 and BSD-licensed for liability + * reasons. + * + * @author Emily Stark + * @author Mike Hamburg + * @author Dan Boneh + */ + +/** + * Schedule out an AES key for both encryption and decryption. This + * is a low-level class. Use a cipher mode to do bulk encryption. + * + * @constructor + * @param {Array} key The key as an array of 4, 6 or 8 words. + */ +sjcl.cipher.aes = function (key) { + if (!this._tables[0][0][0]) { + this._precompute(); + } + + var i, j, tmp, + encKey, decKey, + sbox = this._tables[0][4], decTable = this._tables[1], + keyLen = key.length, rcon = 1; + + if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) { + throw new sjcl.exception.invalid("invalid aes key size"); + } + + this._key = [encKey = key.slice(0), decKey = []]; + + // schedule encryption keys + for (i = keyLen; i < 4 * keyLen + 28; i++) { + tmp = encKey[i - 1]; + + // apply sbox + if (i % keyLen === 0 || (keyLen === 8 && i % keyLen === 4)) { + tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255]; + + // shift rows and add rcon + if (i % keyLen === 0) { + tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24; + rcon = rcon << 1 ^ (rcon >> 7) * 283; + } + } + + encKey[i] = encKey[i - keyLen] ^ tmp; + } + + // schedule decryption keys + for (j = 0; i; j++, i--) { + tmp = encKey[j & 3 ? i : i - 4]; + if (i <= 4 || j < 4) { + decKey[j] = tmp; + } else { + decKey[j] = decTable[0][sbox[tmp >>> 24]] ^ + decTable[1][sbox[tmp >> 16 & 255]] ^ + decTable[2][sbox[tmp >> 8 & 255]] ^ + decTable[3][sbox[tmp & 255]]; + } + } +}; + +sjcl.cipher.aes.prototype = { + // public + /* Something like this might appear here eventually + name: "AES", + blockSize: 4, + keySizes: [4,6,8], + */ + + /** + * Encrypt an array of 4 big-endian words. + * @param {Array} data The plaintext. + * @return {Array} The ciphertext. + */ + encrypt: function (data) { return this._crypt(data, 0); }, + + /** + * Decrypt an array of 4 big-endian words. + * @param {Array} data The ciphertext. + * @return {Array} The plaintext. + */ + decrypt: function (data) { return this._crypt(data, 1); }, + + /** + * The expanded S-box and inverse S-box tables. These will be computed + * on the client so that we don't have to send them down the wire. + * + * There are two tables, _tables[0] is for encryption and + * _tables[1] is for decryption. + * + * The first 4 sub-tables are the expanded S-box with MixColumns. The + * last (_tables[01][4]) is the S-box itself. + * + * @private + */ + _tables: [[[], [], [], [], []], [[], [], [], [], []]], + + /** + * Expand the S-box tables. + * + * @private + */ + _precompute: function () { + var encTable = this._tables[0], decTable = this._tables[1], + sbox = encTable[4], sboxInv = decTable[4], + i, x, xInv, d = [], th = [], x2, x4, x8, s, tEnc, tDec; + + // Compute double and third tables + for (i = 0; i < 256; i++) { + th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i; + } + + for (x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) { + // Compute sbox + s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4; + s = s >> 8 ^ s & 255 ^ 99; + sbox[x] = s; + sboxInv[s] = x; + + // Compute MixColumns + x8 = d[x4 = d[x2 = d[x]]]; + tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100; + tEnc = d[s] * 0x101 ^ s * 0x1010100; + + for (i = 0; i < 4; i++) { + encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8; + decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8; + } + } + + // Compactify. Considerable speedup on Firefox. + for (i = 0; i < 5; i++) { + encTable[i] = encTable[i].slice(0); + decTable[i] = decTable[i].slice(0); + } + }, + + /** + * Encryption and decryption core. + * @param {Array} input Four words to be encrypted or decrypted. + * @param dir The direction, 0 for encrypt and 1 for decrypt. + * @return {Array} The four encrypted or decrypted words. + * @private + */ + _crypt: function (input, dir) { + if (input.length !== 4) { + throw new sjcl.exception.invalid("invalid aes block size"); + } + + var key = this._key[dir], + // state variables a,b,c,d are loaded with pre-whitened data + a = input[0] ^ key[0], + b = input[dir ? 3 : 1] ^ key[1], + c = input[2] ^ key[2], + d = input[dir ? 1 : 3] ^ key[3], + a2, b2, c2, + + nInnerRounds = key.length / 4 - 2, + i, + kIndex = 4, + out = [0, 0, 0, 0], + table = this._tables[dir], + + // load up the tables + t0 = table[0], + t1 = table[1], + t2 = table[2], + t3 = table[3], + sbox = table[4]; + + // Inner rounds. Cribbed from OpenSSL. + for (i = 0; i < nInnerRounds; i++) { + a2 = t0[a >>> 24] ^ t1[b >> 16 & 255] ^ t2[c >> 8 & 255] ^ t3[d & 255] ^ key[kIndex]; + b2 = t0[b >>> 24] ^ t1[c >> 16 & 255] ^ t2[d >> 8 & 255] ^ t3[a & 255] ^ key[kIndex + 1]; + c2 = t0[c >>> 24] ^ t1[d >> 16 & 255] ^ t2[a >> 8 & 255] ^ t3[b & 255] ^ key[kIndex + 2]; + d = t0[d >>> 24] ^ t1[a >> 16 & 255] ^ t2[b >> 8 & 255] ^ t3[c & 255] ^ key[kIndex + 3]; + kIndex += 4; + a = a2; b = b2; c = c2; + } + + // Last round. + for (i = 0; i < 4; i++) { + out[dir ? 3 & -i : i] = + sbox[a >>> 24] << 24 ^ + sbox[b >> 16 & 255] << 16 ^ + sbox[c >> 8 & 255] << 8 ^ + sbox[d & 255] ^ + key[kIndex++]; + a2 = a; a = b; b = c; c = d; d = a2; + } + + return out; + } +}; + +/** @fileOverview HMAC implementation. + * + * @author Emily Stark + * @author Mike Hamburg + * @author Dan Boneh + */ + +/** HMAC with the specified hash function. + * @constructor + * @param {bitArray} key the key for HMAC. + * @param {Object} [Hash=sjcl.hash.sha1] The hash function to use. + */ +sjcl.misc.hmac = function (key, Hash) { + this._hash = Hash = Hash || sjcl.hash.sha1; + var exKey = [[], []], i, + bs = Hash.prototype.blockSize / 32; + this._baseHash = [new Hash(), new Hash()]; + + if (key.length > bs) { + key = Hash.hash(key); + } + + for (i = 0; i < bs; i++) { + exKey[0][i] = key[i] ^ 0x36363636; + exKey[1][i] = key[i] ^ 0x5C5C5C5C; + } + + this._baseHash[0].update(exKey[0]); + this._baseHash[1].update(exKey[1]); + this._resultHash = new Hash(this._baseHash[0]); +}; + +/** HMAC with the specified hash function. Also called encrypt since it's a prf. + * @param {bitArray|String} data The data to mac. + */ +sjcl.misc.hmac.prototype.encrypt = sjcl.misc.hmac.prototype.mac = function (data) { + if (!this._updated) { + this.update(data); + return this.digest(data); + } else { + throw new sjcl.exception.invalid("encrypt on already updated hmac called!"); + } +}; + +sjcl.misc.hmac.prototype.reset = function () { + this._resultHash = new this._hash(this._baseHash[0]); + this._updated = false; +}; + +sjcl.misc.hmac.prototype.update = function (data) { + this._updated = true; + this._resultHash.update(data); +}; + +sjcl.misc.hmac.prototype.digest = function () { + var w = this._resultHash.finalize(), result = new (this._hash)(this._baseHash[1]).update(w).finalize(); + + this.reset(); + + return result; +}; + +/** @fileOverview Password-based key-derivation function, version 2.0. + * + * @author Emily Stark + * @author Mike Hamburg + * @author Dan Boneh + */ + +/** Password-Based Key-Derivation Function, version 2.0. + * + * Generate keys from passwords using PBKDF2-HMAC-SHA1. + * + * This is the method specified by RSA's PKCS #5 standard. + * + * @param {bitArray|String} password The password. + * @param {bitArray|String} salt The salt. Should have lots of entropy. + * @param {Number} [count=1000] The number of iterations. Higher numbers make the function slower but more secure. + * @param {Number} [length] The length of the derived key. Defaults to the + output size of the hash function. + * @param {Object} [Prff=sjcl.misc.hmac] The pseudorandom function family. + * @return {bitArray} the derived key. + */ +sjcl.misc.pbkdf2 = function (password, salt, count, length, Prff) { + count = count || 10000; + + if (length < 0 || count < 0) { + throw new sjcl.exception.invalid("invalid params to pbkdf2"); + } + + if (typeof password === "string") { + password = sjcl.codec.utf8String.toBits(password); + } + + if (typeof salt === "string") { + salt = sjcl.codec.utf8String.toBits(salt); + } + + Prff = Prff || sjcl.misc.hmac; + + var prf = new Prff(password), + u, ui, i, j, k, out = [], b = sjcl.bitArray; + + for (k = 1; 32 * out.length < (length || 1); k++) { + u = ui = prf.encrypt(b.concat(salt, [k])); + + for (i = 1; i < count; i++) { + ui = prf.encrypt(ui); + for (j = 0; j < ui.length; j++) { + u[j] ^= ui[j]; + } + } + + out = out.concat(u); + } + + if (length) { out = b.clamp(out, length); } + + return out; +}; + +/** + * Random values + * @namespace + */ +sjcl.random = { + /** + * Generate cryptographically strong random words using native crypto module if it exists. + * + * In react-native or other non native crypto environment, user could define a crypto module from gloabl variable. + * + * If the crypto module doesn't exist, then using pure js implementation function. + * + * @param {Number} nbytes The number of bytes to generate. + * @return {bitArray} The random words. + */ + randomWords: function (nbytes) { + // function getCryptoModule() { + // try { + // return require("crypto"); + // } + // catch (e) { + // return null; + // } + // } + + // if (typeof window !== "undefined") { + // // Native crypto from window (Browser) + // if (window.crypto) { + // crypto = window.crypto; + // }else if(window.msCrypto) { + // crypto = window.msCrypto; + // } + // } else if (typeof self !== "undefined" && self.crypto) { + // // Native crypto from web worker (Browser) + // crypto = self.crypto; + // } else if (typeof module !== "undefined" && module.exports) { + // // Native crypto import from NodeJS + // crypto = getCryptoModule(); + // } else if (typeof global !== "undefined" && global.crypto) { + // // Native crypto from global variable + // crypto = global.crypto; + // }else{ + // crypto = getCryptoModule(); + // } + + // Get cryptographically strong random values depending on runtime environment + try { + if (crypto) { + if (crypto.getRandomValues) { + return sjcl.codec.bytes.toBits(crypto.getRandomValues(new Uint8Array(nbytes))); + } + if (crypto.randomBytes) { + return sjcl.codec.bytes.toBits(new Uint8Array(crypto.randomBytes(nbytes))); + } + } else { + return getRandomValues(nbytes); + } + } catch (e) { + return getRandomValues(nbytes); + } + }, + + /** + * Generate random words with pure js, cryptographically not as strong & safe as native implementation. + * @param {Number} nbytes The number of bytes to generate. + * @return {bitArray} The random words. + */ + getRandomValues: function (nbytes) { + var words = []; + + var r = function (m_w) { + var m_z = 0x3ade68b1; + var mask = 0xffffffff; + + return function () { + m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask; + m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask; + var result = ((m_z << 0x10) + m_w) & mask; + result /= 0x100000000; + result += 0.5; + return result * (Math.random() > .5 ? 1 : -1); + }; + }; + + for (var i = 0, rcache; i < nbytes; i += 4) { + var _r = r((rcache || Math.random()) * 0x100000000); + rcache = _r() * 0x3ade67b7; + words.push((_r() * 0x100000000) | 0); + } + + return words; + } +}; + +/** @fileOverview CTR mode implementation. + * + * Special thanks to Roy Nicholson for pointing out a bug in our + * implementation. + * + * @author Emily Stark + * @author Mike Hamburg + * @author Dan Boneh + */ + +/** Brian Gladman's CTR Mode. + * @constructor + * @param {Object} _prf The aes instance to generate key. + * @param {bitArray} _iv The iv for ctr mode, it must be 128 bits. + */ +/** + * Brian Gladman's CTR Mode. + * @namespace + */ +sjcl.mode.ctrGladman = function(prf, iv) { + this._prf = prf; + this._initIv = iv; + this._iv = iv; +}; + +sjcl.mode.ctrGladman.prototype.reset = function () { + this._iv = this._initIv; +}; + +/** Input some data to calculate. + * @param {bitArray} data the data to process, it must be intergral multiple of 128 bits unless it's the last. + */ +sjcl.mode.ctrGladman.prototype.update = function (data) { + return this.calculate(this._prf, data, this._iv); +}; + +sjcl.mode.ctrGladman.incWord = function (word) { + if (((word >> 24) & 0xff) === 0xff) { //overflow + var b1 = (word >> 16) & 0xff; + var b2 = (word >> 8) & 0xff; + var b3 = word & 0xff; + + if (b1 === 0xff) { // overflow b1 + b1 = 0; + if (b2 === 0xff) { + b2 = 0; + if (b3 === 0xff) { + b3 = 0; + } else { + ++b3; + } + } else { + ++b2; + } + } else { + ++b1; + } + + word = 0; + word += (b1 << 16); + word += (b2 << 8); + word += b3; + } else { + word += (0x01 << 24); + } + return word; +}; + +sjcl.mode.ctrGladman.incCounter = function (counter) { + if ((counter[0] = sjcl.mode.ctrGladman.incWord(counter[0])) === 0) { + // encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8 + counter[1] = sjcl.mode.ctrGladman.incWord(counter[1]); + } +}; + +sjcl.mode.ctrGladman.prototype.calculate = function (prf, data, iv) { + var l, bl, e, i; + if (!(l = data.length)) { + return []; + } + bl = sjcl.bitArray.bitLength(data); + for (i = 0; i < l; i += 4) { + sjcl.mode.ctrGladman.incCounter(iv); + e = prf.encrypt(iv); + data[i] ^= e[0]; + data[i + 1] ^= e[1]; + data[i + 2] ^= e[2]; + data[i + 3] ^= e[3]; + } + return sjcl.bitArray.clamp(data, bl); +}; + +module.exports = sjcl; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/stream/ConvertWorker.js b/ohos-jszip/library/src/main/core/jszip-master/lib/stream/ConvertWorker.js new file mode 100644 index 00000000..22d27b0b --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/stream/ConvertWorker.js @@ -0,0 +1,26 @@ +"use strict"; + +var GenericWorker = require("./GenericWorker"); +var utils = require("../utils"); + +/** + * A worker which convert chunks to a specified type. + * @constructor + * @param {String} destType the destination type. + */ +function ConvertWorker(destType) { + GenericWorker.call(this, "ConvertWorker to " + destType); + this.destType = destType; +} +utils.inherits(ConvertWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +ConvertWorker.prototype.processChunk = function (chunk) { + this.push({ + data : utils.transformTo(this.destType, chunk.data), + meta : chunk.meta + }); +}; +module.exports = ConvertWorker; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/stream/Crc32Probe.js b/ohos-jszip/library/src/main/core/jszip-master/lib/stream/Crc32Probe.js new file mode 100644 index 00000000..59c3da0b --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/stream/Crc32Probe.js @@ -0,0 +1,24 @@ +"use strict"; + +var GenericWorker = require("./GenericWorker"); +var crc32 = require("../crc32"); +var utils = require("../utils"); + +/** + * A worker which calculate the crc32 of the data flowing through. + * @constructor + */ +function Crc32Probe() { + GenericWorker.call(this, "Crc32Probe"); + this.withStreamInfo("crc32", 0); +} +utils.inherits(Crc32Probe, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +Crc32Probe.prototype.processChunk = function (chunk) { + this.streamInfo.crc32 = crc32(chunk.data, this.streamInfo.crc32 || 0); + this.push(chunk); +}; +module.exports = Crc32Probe; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/stream/DataLengthProbe.js b/ohos-jszip/library/src/main/core/jszip-master/lib/stream/DataLengthProbe.js new file mode 100644 index 00000000..12356926 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/stream/DataLengthProbe.js @@ -0,0 +1,29 @@ +"use strict"; + +var utils = require("../utils"); +var GenericWorker = require("./GenericWorker"); + +/** + * A worker which calculate the total length of the data flowing through. + * @constructor + * @param {String} propName the name used to expose the length + */ +function DataLengthProbe(propName) { + GenericWorker.call(this, "DataLengthProbe for " + propName); + this.propName = propName; + this.withStreamInfo(propName, 0); +} +utils.inherits(DataLengthProbe, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +DataLengthProbe.prototype.processChunk = function (chunk) { + if(chunk) { + var length = this.streamInfo[this.propName] || 0; + this.streamInfo[this.propName] = length + chunk.data.length; + } + GenericWorker.prototype.processChunk.call(this, chunk); +}; +module.exports = DataLengthProbe; + diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/stream/DataWorker.js b/ohos-jszip/library/src/main/core/jszip-master/lib/stream/DataWorker.js new file mode 100644 index 00000000..ffb99bdd --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/stream/DataWorker.js @@ -0,0 +1,116 @@ +"use strict"; + +var utils = require("../utils"); +var GenericWorker = require("./GenericWorker"); + +// the size of the generated chunks +// TODO expose this as a public variable +var DEFAULT_BLOCK_SIZE = 16 * 1024; + +/** + * A worker that reads a content and emits chunks. + * @constructor + * @param {Promise} dataP the promise of the data to split + */ +function DataWorker(dataP) { + GenericWorker.call(this, "DataWorker"); + var self = this; + this.dataIsReady = false; + this.index = 0; + this.max = 0; + this.data = null; + this.type = ""; + + this._tickScheduled = false; + + dataP.then(function (data) { + self.dataIsReady = true; + self.data = data; + self.max = data && data.length || 0; + self.type = utils.getTypeOf(data); + if(!self.isPaused) { + self._tickAndRepeat(); + } + }, function (e) { + self.error(e); + }); +} + +utils.inherits(DataWorker, GenericWorker); + +/** + * @see GenericWorker.cleanUp + */ +DataWorker.prototype.cleanUp = function () { + GenericWorker.prototype.cleanUp.call(this); + this.data = null; +}; + +/** + * @see GenericWorker.resume + */ +DataWorker.prototype.resume = function () { + if(!GenericWorker.prototype.resume.call(this)) { + return false; + } + + if (!this._tickScheduled && this.dataIsReady) { + this._tickScheduled = true; + utils.delay(this._tickAndRepeat, [], this); + } + return true; +}; + +/** + * Trigger a tick a schedule an other call to this function. + */ +DataWorker.prototype._tickAndRepeat = function() { + this._tickScheduled = false; + if(this.isPaused || this.isFinished) { + return; + } + this._tick(); + if(!this.isFinished) { + utils.delay(this._tickAndRepeat, [], this); + this._tickScheduled = true; + } +}; + +/** + * Read and push a chunk. + */ +DataWorker.prototype._tick = function() { + + if(this.isPaused || this.isFinished) { + return false; + } + + var size = DEFAULT_BLOCK_SIZE; + var data = null, nextIndex = Math.min(this.max, this.index + size); + if (this.index >= this.max) { + // EOF + return this.end(); + } else { + switch(this.type) { + case "string": + data = this.data.substring(this.index, nextIndex); + break; + case "uint8array": + data = this.data.subarray(this.index, nextIndex); + break; + case "array": + case "nodebuffer": + data = this.data.slice(this.index, nextIndex); + break; + } + this.index = nextIndex; + return this.push({ + data : data, + meta : { + percent : this.max ? this.index / this.max * 100 : 0 + } + }); + } +}; + +module.exports = DataWorker; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/stream/GenericWorker.js b/ohos-jszip/library/src/main/core/jszip-master/lib/stream/GenericWorker.js new file mode 100644 index 00000000..4b283101 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/stream/GenericWorker.js @@ -0,0 +1,263 @@ +"use strict"; + +/** + * A worker that does nothing but passing chunks to the next one. This is like + * a nodejs stream but with some differences. On the good side : + * - it works on IE 6-9 without any issue / polyfill + * - it weights less than the full dependencies bundled with browserify + * - it forwards errors (no need to declare an error handler EVERYWHERE) + * + * A chunk is an object with 2 attributes : `meta` and `data`. The former is an + * object containing anything (`percent` for example), see each worker for more + * details. The latter is the real data (String, Uint8Array, etc). + * + * @constructor + * @param {String} name the name of the stream (mainly used for debugging purposes) + */ +function GenericWorker(name) { + // the name of the worker + this.name = name || "default"; + // an object containing metadata about the workers chain + this.streamInfo = {}; + // an error which happened when the worker was paused + this.generatedError = null; + // an object containing metadata to be merged by this worker into the general metadata + this.extraStreamInfo = {}; + // true if the stream is paused (and should not do anything), false otherwise + this.isPaused = true; + // true if the stream is finished (and should not do anything), false otherwise + this.isFinished = false; + // true if the stream is locked to prevent further structure updates (pipe), false otherwise + this.isLocked = false; + // the event listeners + this._listeners = { + "data":[], + "end":[], + "error":[] + }; + // the previous worker, if any + this.previous = null; +} + +GenericWorker.prototype = { + /** + * Push a chunk to the next workers. + * @param {Object} chunk the chunk to push + */ + push : function (chunk) { + this.emit("data", chunk); + }, + /** + * End the stream. + * @return {Boolean} true if this call ended the worker, false otherwise. + */ + end : function () { + if (this.isFinished) { + return false; + } + + this.flush(); + try { + this.emit("end"); + this.cleanUp(); + this.isFinished = true; + } catch (e) { + this.emit("error", e); + } + return true; + }, + /** + * End the stream with an error. + * @param {Error} e the error which caused the premature end. + * @return {Boolean} true if this call ended the worker with an error, false otherwise. + */ + error : function (e) { + if (this.isFinished) { + return false; + } + + if(this.isPaused) { + this.generatedError = e; + } else { + this.isFinished = true; + + this.emit("error", e); + + // in the workers chain exploded in the middle of the chain, + // the error event will go downward but we also need to notify + // workers upward that there has been an error. + if(this.previous) { + this.previous.error(e); + } + + this.cleanUp(); + } + return true; + }, + /** + * Add a callback on an event. + * @param {String} name the name of the event (data, end, error) + * @param {Function} listener the function to call when the event is triggered + * @return {GenericWorker} the current object for chainability + */ + on : function (name, listener) { + this._listeners[name].push(listener); + return this; + }, + /** + * Clean any references when a worker is ending. + */ + cleanUp : function () { + this.streamInfo = this.generatedError = this.extraStreamInfo = null; + this._listeners = []; + }, + /** + * Trigger an event. This will call registered callback with the provided arg. + * @param {String} name the name of the event (data, end, error) + * @param {Object} arg the argument to call the callback with. + */ + emit : function (name, arg) { + if (this._listeners[name]) { + for(var i = 0; i < this._listeners[name].length; i++) { + this._listeners[name][i].call(this, arg); + } + } + }, + /** + * Chain a worker with an other. + * @param {Worker} next the worker receiving events from the current one. + * @return {worker} the next worker for chainability + */ + pipe : function (next) { + return next.registerPrevious(this); + }, + /** + * Same as `pipe` in the other direction. + * Using an API with `pipe(next)` is very easy. + * Implementing the API with the point of view of the next one registering + * a source is easier, see the ZipFileWorker. + * @param {Worker} previous the previous worker, sending events to this one + * @return {Worker} the current worker for chainability + */ + registerPrevious : function (previous) { + if (this.isLocked) { + throw new Error("The stream '" + this + "' has already been used."); + } + + // sharing the streamInfo... + this.streamInfo = previous.streamInfo; + // ... and adding our own bits + this.mergeStreamInfo(); + this.previous = previous; + var self = this; + previous.on("data", function (chunk) { + self.processChunk(chunk); + }); + previous.on("end", function () { + self.end(); + }); + previous.on("error", function (e) { + self.error(e); + }); + return this; + }, + /** + * Pause the stream so it doesn't send events anymore. + * @return {Boolean} true if this call paused the worker, false otherwise. + */ + pause : function () { + if(this.isPaused || this.isFinished) { + return false; + } + this.isPaused = true; + + if(this.previous) { + this.previous.pause(); + } + return true; + }, + /** + * Resume a paused stream. + * @return {Boolean} true if this call resumed the worker, false otherwise. + */ + resume : function () { + if(!this.isPaused || this.isFinished) { + return false; + } + this.isPaused = false; + + // if true, the worker tried to resume but failed + var withError = false; + if(this.generatedError) { + this.error(this.generatedError); + withError = true; + } + if(this.previous) { + this.previous.resume(); + } + + return !withError; + }, + /** + * Flush any remaining bytes as the stream is ending. + */ + flush : function () {}, + /** + * Process a chunk. This is usually the method overridden. + * @param {Object} chunk the chunk to process. + */ + processChunk : function(chunk) { + this.push(chunk); + }, + /** + * Add a key/value to be added in the workers chain streamInfo once activated. + * @param {String} key the key to use + * @param {Object} value the associated value + * @return {Worker} the current worker for chainability + */ + withStreamInfo : function (key, value) { + this.extraStreamInfo[key] = value; + this.mergeStreamInfo(); + return this; + }, + /** + * Merge this worker's streamInfo into the chain's streamInfo. + */ + mergeStreamInfo : function () { + for(var key in this.extraStreamInfo) { + if (!Object.prototype.hasOwnProperty.call(this.extraStreamInfo, key)) { + continue; + } + this.streamInfo[key] = this.extraStreamInfo[key]; + } + }, + + /** + * Lock the stream to prevent further updates on the workers chain. + * After calling this method, all calls to pipe will fail. + */ + lock: function () { + if (this.isLocked) { + throw new Error("The stream '" + this + "' has already been used."); + } + this.isLocked = true; + if (this.previous) { + this.previous.lock(); + } + }, + + /** + * + * Pretty print the workers chain. + */ + toString : function () { + var me = "Worker " + this.name; + if (this.previous) { + return this.previous + " -> " + me; + } else { + return me; + } + } +}; + +module.exports = GenericWorker; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/stream/StreamHelper.js b/ohos-jszip/library/src/main/core/jszip-master/lib/stream/StreamHelper.js new file mode 100644 index 00000000..64575132 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/stream/StreamHelper.js @@ -0,0 +1,214 @@ +"use strict"; + +var utils = require("../utils"); +var ConvertWorker = require("./ConvertWorker"); +var GenericWorker = require("./GenericWorker"); +var base64 = require("../base64"); +var support = require("../support"); +var external = require("../external"); + +var NodejsStreamOutputAdapter = null; +if (support.nodestream) { + try { + NodejsStreamOutputAdapter = require("../nodejs/NodejsStreamOutputAdapter"); + } catch(e) { + // ignore + } +} + +/** + * Apply the final transformation of the data. If the user wants a Blob for + * example, it's easier to work with an U8intArray and finally do the + * ArrayBuffer/Blob conversion. + * @param {String} type the name of the final type + * @param {String|Uint8Array|Buffer} content the content to transform + * @param {String} mimeType the mime type of the content, if applicable. + * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the content in the right format. + */ +function transformZipOutput(type, content, mimeType) { + switch(type) { + case "blob" : + return utils.newBlob(utils.transformTo("arraybuffer", content), mimeType); + case "base64" : + return base64.encode(content); + default : + return utils.transformTo(type, content); + } +} + +/** + * Concatenate an array of data of the given type. + * @param {String} type the type of the data in the given array. + * @param {Array} dataArray the array containing the data chunks to concatenate + * @return {String|Uint8Array|Buffer} the concatenated data + * @throws Error if the asked type is unsupported + */ +function concat (type, dataArray) { + var i, index = 0, res = null, totalLength = 0; + for(i = 0; i < dataArray.length; i++) { + totalLength += dataArray[i].length; + } + switch(type) { + case "string": + return dataArray.join(""); + case "array": + return Array.prototype.concat.apply([], dataArray); + case "uint8array": + res = new Uint8Array(totalLength); + for(i = 0; i < dataArray.length; i++) { + res.set(dataArray[i], index); + index += dataArray[i].length; + } + return res; + case "nodebuffer": + return Buffer.concat(dataArray); + default: + throw new Error("concat : unsupported type '" + type + "'"); + } +} + +/** + * Listen a StreamHelper, accumulate its content and concatenate it into a + * complete block. + * @param {StreamHelper} helper the helper to use. + * @param {Function} updateCallback a callback called on each update. Called + * with one arg : + * - the metadata linked to the update received. + * @return Promise the promise for the accumulation. + */ +function accumulate(helper, updateCallback) { + return new external.Promise(function (resolve, reject){ + var dataArray = []; + var chunkType = helper._internalType, + resultType = helper._outputType, + mimeType = helper._mimeType; + helper + .on("data", function (data, meta) { + dataArray.push(data); + if(updateCallback) { + updateCallback(meta); + } + }) + .on("error", function(err) { + dataArray = []; + reject(err); + }) + .on("end", function (){ + try { + var result = transformZipOutput(resultType, concat(chunkType, dataArray), mimeType); + resolve(result); + } catch (e) { + reject(e); + } + dataArray = []; + }) + .resume(); + }); +} + +/** + * An helper to easily use workers outside of JSZip. + * @constructor + * @param {Worker} worker the worker to wrap + * @param {String} outputType the type of data expected by the use + * @param {String} mimeType the mime type of the content, if applicable. + */ +function StreamHelper(worker, outputType, mimeType) { + var internalType = outputType; + switch(outputType) { + case "blob": + case "arraybuffer": + internalType = "uint8array"; + break; + case "base64": + internalType = "string"; + break; + } + + try { + // the type used internally + this._internalType = internalType; + // the type used to output results + this._outputType = outputType; + // the mime type + this._mimeType = mimeType; + utils.checkSupport(internalType); + this._worker = worker.pipe(new ConvertWorker(internalType)); + // the last workers can be rewired without issues but we need to + // prevent any updates on previous workers. + worker.lock(); + } catch(e) { + this._worker = new GenericWorker("error"); + this._worker.error(e); + } +} + +StreamHelper.prototype = { + /** + * Listen a StreamHelper, accumulate its content and concatenate it into a + * complete block. + * @param {Function} updateCb the update callback. + * @return Promise the promise for the accumulation. + */ + accumulate : function (updateCb) { + return accumulate(this, updateCb); + }, + /** + * Add a listener on an event triggered on a stream. + * @param {String} evt the name of the event + * @param {Function} fn the listener + * @return {StreamHelper} the current helper. + */ + on : function (evt, fn) { + var self = this; + + if(evt === "data") { + this._worker.on(evt, function (chunk) { + fn.call(self, chunk.data, chunk.meta); + }); + } else { + this._worker.on(evt, function () { + utils.delay(fn, arguments, self); + }); + } + return this; + }, + /** + * Resume the flow of chunks. + * @return {StreamHelper} the current helper. + */ + resume : function () { + utils.delay(this._worker.resume, [], this._worker); + return this; + }, + /** + * Pause the flow of chunks. + * @return {StreamHelper} the current helper. + */ + pause : function () { + this._worker.pause(); + return this; + }, + /** + * Return a nodejs stream for this helper. + * @param {Function} updateCb the update callback. + * @return {NodejsStreamOutputAdapter} the nodejs stream. + */ + toNodejsStream : function (updateCb) { + utils.checkSupport("nodestream"); + if (this._outputType !== "nodebuffer") { + // an object stream containing blob/arraybuffer/uint8array/string + // is strange and I don't know if it would be useful. + // I you find this comment and have a good usecase, please open a + // bug report ! + throw new Error(this._outputType + " is not supported by this method"); + } + + return new NodejsStreamOutputAdapter(this, { + objectMode : this._outputType !== "nodebuffer" + }, updateCb); + } +}; + + +module.exports = StreamHelper; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/support.js b/ohos-jszip/library/src/main/core/jszip-master/lib/support.js new file mode 100644 index 00000000..ef60feaa --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/support.js @@ -0,0 +1,38 @@ +"use strict"; + +exports.base64 = true; +exports.array = true; +exports.string = true; +exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; +exports.nodebuffer = typeof Buffer !== "undefined"; +// contains true if JSZip can read/generate Uint8Array, false otherwise. +exports.uint8array = typeof Uint8Array !== "undefined"; + +if (typeof ArrayBuffer === "undefined") { + exports.blob = false; +} +else { + var buffer = new ArrayBuffer(0); + try { + exports.blob = new Blob([buffer], { + type: "application/zip" + }).size === 0; + } + catch (e) { + try { + var Builder = self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder; + var builder = new Builder(); + builder.append(buffer); + exports.blob = builder.getBlob("application/zip").size === 0; + } + catch (e) { + exports.blob = false; + } + } +} + +try { + exports.nodestream = !!require("readable-stream").Readable; +} catch(e) { + exports.nodestream = false; +} diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/utf8.js b/ohos-jszip/library/src/main/core/jszip-master/lib/utf8.js new file mode 100644 index 00000000..18e8f829 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/utf8.js @@ -0,0 +1,275 @@ +"use strict"; + +var utils = require("./utils"); +var support = require("./support"); +var nodejsUtils = require("./nodejsUtils"); +var GenericWorker = require("./stream/GenericWorker"); + +/** + * The following functions come from pako, from pako/lib/utils/strings + * released under the MIT license, see pako https://github.com/nodeca/pako/ + */ + +// Table with utf8 lengths (calculated by first byte of sequence) +// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, +// because max possible codepoint is 0x10ffff +var _utf8len = new Array(256); +for (var i=0; i<256; i++) { + _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); +} +_utf8len[254]=_utf8len[254]=1; // Invalid sequence start + +// convert string to array (typed, when possible) +var string2buf = function (str) { + var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; + + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; + } + + // allocate buffer + if (support.uint8array) { + buf = new Uint8Array(buf_len); + } else { + buf = new Array(buf_len); + } + + // convert + for (i=0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xC0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xE0 | (c >>> 12); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | (c >>> 12 & 0x3f); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } + } + + return buf; +}; + +// Calculate max possible position in utf8 buffer, +// that will not break sequence. If that's not possible +// - (very small limits) return max size as is. +// +// buf[] - utf8 bytes array +// max - length limit (mandatory); +var utf8border = function(buf, max) { + var pos; + + max = max || buf.length; + if (max > buf.length) { max = buf.length; } + + // go back from last position, until start of sequence found + pos = max-1; + while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } + + // Fuckup - very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { return max; } + + // If we came to start of buffer - that means vuffer is too small, + // return max too. + if (pos === 0) { return max; } + + return (pos + _utf8len[buf[pos]] > max) ? pos : max; +}; + +// convert array to string +var buf2string = function (buf) { + var i, out, c, c_len; + var len = buf.length; + + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + var utf16buf = new Array(len*2); + + for (out=0, i=0; i 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; } + + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; + } + + // terminated by end of string? + if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } + + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); + } + } + + // shrinkBuf(utf16buf, out) + if (utf16buf.length !== out) { + if(utf16buf.subarray) { + utf16buf = utf16buf.subarray(0, out); + } else { + utf16buf.length = out; + } + } + + // return String.fromCharCode.apply(null, utf16buf); + return utils.applyFromCharCode(utf16buf); +}; + + +// That's all for the pako functions. + + +/** + * Transform a javascript string into an array (typed if possible) of bytes, + * UTF-8 encoded. + * @param {String} str the string to encode + * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string. + */ +exports.utf8encode = function utf8encode(str) { + if (support.nodebuffer) { + return nodejsUtils.newBufferFrom(str, "utf-8"); + } + + return string2buf(str); +}; + + +/** + * Transform a bytes array (or a representation) representing an UTF-8 encoded + * string into a javascript string. + * @param {Array|Uint8Array|Buffer} buf the data de decode + * @return {String} the decoded string. + */ +exports.utf8decode = function utf8decode(buf) { + if (support.nodebuffer) { + return utils.transformTo("nodebuffer", buf).toString("utf-8"); + } + + buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf); + + return buf2string(buf); +}; + +/** + * A worker to decode utf8 encoded binary chunks into string chunks. + * @constructor + */ +function Utf8DecodeWorker() { + GenericWorker.call(this, "utf-8 decode"); + // the last bytes if a chunk didn't end with a complete codepoint. + this.leftOver = null; +} +utils.inherits(Utf8DecodeWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +Utf8DecodeWorker.prototype.processChunk = function (chunk) { + + var data = utils.transformTo(support.uint8array ? "uint8array" : "array", chunk.data); + + // 1st step, re-use what's left of the previous chunk + if (this.leftOver && this.leftOver.length) { + if(support.uint8array) { + var previousData = data; + data = new Uint8Array(previousData.length + this.leftOver.length); + data.set(this.leftOver, 0); + data.set(previousData, this.leftOver.length); + } else { + data = this.leftOver.concat(data); + } + this.leftOver = null; + } + + var nextBoundary = utf8border(data); + var usableData = data; + if (nextBoundary !== data.length) { + if (support.uint8array) { + usableData = data.subarray(0, nextBoundary); + this.leftOver = data.subarray(nextBoundary, data.length); + } else { + usableData = data.slice(0, nextBoundary); + this.leftOver = data.slice(nextBoundary, data.length); + } + } + + this.push({ + data : exports.utf8decode(usableData), + meta : chunk.meta + }); +}; + +/** + * @see GenericWorker.flush + */ +Utf8DecodeWorker.prototype.flush = function () { + if(this.leftOver && this.leftOver.length) { + this.push({ + data : exports.utf8decode(this.leftOver), + meta : {} + }); + this.leftOver = null; + } +}; +exports.Utf8DecodeWorker = Utf8DecodeWorker; + +/** + * A worker to endcode string chunks into utf8 encoded binary chunks. + * @constructor + */ +function Utf8EncodeWorker() { + GenericWorker.call(this, "utf-8 encode"); +} +utils.inherits(Utf8EncodeWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +Utf8EncodeWorker.prototype.processChunk = function (chunk) { + this.push({ + data : exports.utf8encode(chunk.data), + meta : chunk.meta + }); +}; +exports.Utf8EncodeWorker = Utf8EncodeWorker; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/utils.js b/ohos-jszip/library/src/main/core/jszip-master/lib/utils.js new file mode 100644 index 00000000..fe585f40 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/utils.js @@ -0,0 +1,501 @@ +"use strict"; + +var support = require("./support"); +var base64 = require("./base64"); +var nodejsUtils = require("./nodejsUtils"); +var external = require("./external"); +require("setimmediate"); + + +/** + * Convert a string that pass as a "binary string": it should represent a byte + * array but may have > 255 char codes. Be sure to take only the first byte + * and returns the byte array. + * @param {String} str the string to transform. + * @return {Array|Uint8Array} the string in a binary format. + */ +function string2binary(str) { + var result = null; + if (support.uint8array) { + result = new Uint8Array(str.length); + } else { + result = new Array(str.length); + } + return stringToArrayLike(str, result); +} + +/** + * Create a new blob with the given content and the given type. + * @param {String|ArrayBuffer} part the content to put in the blob. DO NOT use + * an Uint8Array because the stock browser of android 4 won't accept it (it + * will be silently converted to a string, "[object Uint8Array]"). + * + * Use only ONE part to build the blob to avoid a memory leak in IE11 / Edge: + * when a large amount of Array is used to create the Blob, the amount of + * memory consumed is nearly 100 times the original data amount. + * + * @param {String} type the mime type of the blob. + * @return {Blob} the created blob. + */ +exports.newBlob = function(part, type) { + exports.checkSupport("blob"); + + try { + // Blob constructor + return new Blob([part], { + type: type + }); + } + catch (e) { + + try { + // deprecated, browser only, old way + var Builder = self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder; + var builder = new Builder(); + builder.append(part); + return builder.getBlob(type); + } + catch (e) { + + // well, fuck ?! + throw new Error("Bug : can't construct the Blob."); + } + } + + +}; +/** + * The identity function. + * @param {Object} input the input. + * @return {Object} the same input. + */ +function identity(input) { + return input; +} + +/** + * Fill in an array with a string. + * @param {String} str the string to use. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated). + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array. + */ +function stringToArrayLike(str, array) { + for (var i = 0; i < str.length; ++i) { + array[i] = str.charCodeAt(i) & 0xFF; + } + return array; +} + +/** + * An helper for the function arrayLikeToString. + * This contains static information and functions that + * can be optimized by the browser JIT compiler. + */ +var arrayToStringHelper = { + /** + * Transform an array of int into a string, chunk by chunk. + * See the performances notes on arrayLikeToString. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @param {String} type the type of the array. + * @param {Integer} chunk the chunk size. + * @return {String} the resulting string. + * @throws Error if the chunk is too big for the stack. + */ + stringifyByChunk: function(array, type, chunk) { + var result = [], k = 0, len = array.length; + // shortcut + if (len <= chunk) { + return String.fromCharCode.apply(null, array); + } + while (k < len) { + if (type === "array" || type === "nodebuffer") { + result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len)))); + } + else { + result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len)))); + } + k += chunk; + } + return result.join(""); + }, + /** + * Call String.fromCharCode on every item in the array. + * This is the naive implementation, which generate A LOT of intermediate string. + * This should be used when everything else fail. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @return {String} the result. + */ + stringifyByChar: function(array){ + var resultStr = ""; + for(var i = 0; i < array.length; i++) { + resultStr += String.fromCharCode(array[i]); + } + return resultStr; + }, + applyCanBeUsed : { + /** + * true if the browser accepts to use String.fromCharCode on Uint8Array + */ + uint8array : (function () { + try { + return support.uint8array && String.fromCharCode.apply(null, new Uint8Array(1)).length === 1; + } catch (e) { + return false; + } + })(), + /** + * true if the browser accepts to use String.fromCharCode on nodejs Buffer. + */ + nodebuffer : (function () { + try { + return support.nodebuffer && String.fromCharCode.apply(null, nodejsUtils.allocBuffer(1)).length === 1; + } catch (e) { + return false; + } + })() + } +}; + +/** + * Transform an array-like object to a string. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @return {String} the result. + */ +function arrayLikeToString(array) { + // Performances notes : + // -------------------- + // String.fromCharCode.apply(null, array) is the fastest, see + // see http://jsperf.com/converting-a-uint8array-to-a-string/2 + // but the stack is limited (and we can get huge arrays !). + // + // result += String.fromCharCode(array[i]); generate too many strings ! + // + // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2 + // TODO : we now have workers that split the work. Do we still need that ? + var chunk = 65536, + type = exports.getTypeOf(array), + canUseApply = true; + if (type === "uint8array") { + canUseApply = arrayToStringHelper.applyCanBeUsed.uint8array; + } else if (type === "nodebuffer") { + canUseApply = arrayToStringHelper.applyCanBeUsed.nodebuffer; + } + + if (canUseApply) { + while (chunk > 1) { + try { + return arrayToStringHelper.stringifyByChunk(array, type, chunk); + } catch (e) { + chunk = Math.floor(chunk / 2); + } + } + } + + // no apply or chunk error : slow and painful algorithm + // default browser on android 4.* + return arrayToStringHelper.stringifyByChar(array); +} + +exports.applyFromCharCode = arrayLikeToString; + + +/** + * Copy the data from an array-like to an other array-like. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated. + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array. + */ +function arrayLikeToArrayLike(arrayFrom, arrayTo) { + for (var i = 0; i < arrayFrom.length; i++) { + arrayTo[i] = arrayFrom[i]; + } + return arrayTo; +} + +// a matrix containing functions to transform everything into everything. +var transform = {}; + +// string to ? +transform["string"] = { + "string": identity, + "array": function(input) { + return stringToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return transform["string"]["uint8array"](input).buffer; + }, + "uint8array": function(input) { + return stringToArrayLike(input, new Uint8Array(input.length)); + }, + "nodebuffer": function(input) { + return stringToArrayLike(input, nodejsUtils.allocBuffer(input.length)); + } +}; + +// array to ? +transform["array"] = { + "string": arrayLikeToString, + "array": identity, + "arraybuffer": function(input) { + return (new Uint8Array(input)).buffer; + }, + "uint8array": function(input) { + return new Uint8Array(input); + }, + "nodebuffer": function(input) { + return nodejsUtils.newBufferFrom(input); + } +}; + +// arraybuffer to ? +transform["arraybuffer"] = { + "string": function(input) { + return arrayLikeToString(new Uint8Array(input)); + }, + "array": function(input) { + return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength)); + }, + "arraybuffer": identity, + "uint8array": function(input) { + return new Uint8Array(input); + }, + "nodebuffer": function(input) { + return nodejsUtils.newBufferFrom(new Uint8Array(input)); + } +}; + +// uint8array to ? +transform["uint8array"] = { + "string": arrayLikeToString, + "array": function(input) { + return arrayLikeToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return input.buffer; + }, + "uint8array": identity, + "nodebuffer": function(input) { + return nodejsUtils.newBufferFrom(input); + } +}; + +// nodebuffer to ? +transform["nodebuffer"] = { + "string": arrayLikeToString, + "array": function(input) { + return arrayLikeToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return transform["nodebuffer"]["uint8array"](input).buffer; + }, + "uint8array": function(input) { + return arrayLikeToArrayLike(input, new Uint8Array(input.length)); + }, + "nodebuffer": identity +}; + +/** + * Transform an input into any type. + * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer. + * If no output type is specified, the unmodified input will be returned. + * @param {String} outputType the output type. + * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert. + * @throws {Error} an Error if the browser doesn't support the requested output type. + */ +exports.transformTo = function(outputType, input) { + if (!input) { + // undefined, null, etc + // an empty string won't harm. + input = ""; + } + if (!outputType) { + return input; + } + exports.checkSupport(outputType); + var inputType = exports.getTypeOf(input); + var result = transform[inputType][outputType](input); + return result; +}; + +/** + * Resolve all relative path components, "." and "..", in a path. If these relative components + * traverse above the root then the resulting path will only contain the final path component. + * + * All empty components, e.g. "//", are removed. + * @param {string} path A path with / or \ separators + * @returns {string} The path with all relative path components resolved. + */ +exports.resolve = function(path) { + var parts = path.split("/"); + var result = []; + for (var index = 0; index < parts.length; index++) { + var part = parts[index]; + // Allow the first and last component to be empty for trailing slashes. + if (part === "." || (part === "" && index !== 0 && index !== parts.length - 1)) { + continue; + } else if (part === "..") { + result.pop(); + } else { + result.push(part); + } + } + return result.join("/"); +}; + +/** + * Return the type of the input. + * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. + * @param {Object} input the input to identify. + * @return {String} the (lowercase) type of the input. + */ +exports.getTypeOf = function(input) { + if (typeof input === "string") { + return "string"; + } + if (Object.prototype.toString.call(input) === "[object Array]") { + return "array"; + } + if (support.nodebuffer && nodejsUtils.isBuffer(input)) { + return "nodebuffer"; + } + if (support.uint8array && input instanceof Uint8Array) { + return "uint8array"; + } + if (support.arraybuffer && input instanceof ArrayBuffer) { + return "arraybuffer"; + } +}; + +/** + * Throw an exception if the type is not supported. + * @param {String} type the type to check. + * @throws {Error} an Error if the browser doesn't support the requested type. + */ +exports.checkSupport = function(type) { + var supported = support[type.toLowerCase()]; + if (!supported) { + throw new Error(type + " is not supported by this platform"); + } +}; + +exports.MAX_VALUE_16BITS = 65535; +exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 + +/** + * Prettify a string read as binary. + * @param {string} str the string to prettify. + * @return {string} a pretty string. + */ +exports.pretty = function(str) { + var res = "", + code, i; + for (i = 0; i < (str || "").length; i++) { + code = str.charCodeAt(i); + res += "\\x" + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); + } + return res; +}; + +/** + * Defer the call of a function. + * @param {Function} callback the function to call asynchronously. + * @param {Array} args the arguments to give to the callback. + */ +exports.delay = function(callback, args, self) { + setImmediate(function () { + callback.apply(self || null, args || []); + }); +}; + +/** + * Extends a prototype with an other, without calling a constructor with + * side effects. Inspired by nodejs' `utils.inherits` + * @param {Function} ctor the constructor to augment + * @param {Function} superCtor the parent constructor to use + */ +exports.inherits = function (ctor, superCtor) { + var Obj = function() {}; + Obj.prototype = superCtor.prototype; + ctor.prototype = new Obj(); +}; + +/** + * Merge the objects passed as parameters into a new one. + * @private + * @param {...Object} var_args All objects to merge. + * @return {Object} a new object with the data of the others. + */ +exports.extend = function() { + var result = {}, i, attr; + for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers + for (attr in arguments[i]) { + if (Object.prototype.hasOwnProperty.call(arguments[i], attr) && typeof result[attr] === "undefined") { + result[attr] = arguments[i][attr]; + } + } + } + return result; +}; + +/** + * Transform arbitrary content into a Promise. + * @param {String} name a name for the content being processed. + * @param {Object} inputData the content to process. + * @param {Boolean} isBinary true if the content is not an unicode string + * @param {Boolean} isOptimizedBinaryString true if the string content only has one byte per character. + * @param {Boolean} isBase64 true if the string content is encoded with base64. + * @return {Promise} a promise in a format usable by JSZip. + */ +exports.prepareContent = function(name, inputData, isBinary, isOptimizedBinaryString, isBase64) { + + // if inputData is already a promise, this flatten it. + var promise = external.Promise.resolve(inputData).then(function(data) { + + + var isBlob = support.blob && (data instanceof Blob || ["[object File]", "[object Blob]"].indexOf(Object.prototype.toString.call(data)) !== -1); + + if (isBlob && typeof FileReader !== "undefined") { + return new external.Promise(function (resolve, reject) { + var reader = new FileReader(); + + reader.onload = function(e) { + resolve(e.target.result); + }; + reader.onerror = function(e) { + reject(e.target.error); + }; + reader.readAsArrayBuffer(data); + }); + } else { + return data; + } + }); + + return promise.then(function(data) { + var dataType = exports.getTypeOf(data); + + if (!dataType) { + return external.Promise.reject( + new Error("Can't read the data of '" + name + "'. Is it " + + "in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?") + ); + } + // special case : it's way easier to work with Uint8Array than with ArrayBuffer + if (dataType === "arraybuffer") { + data = exports.transformTo("uint8array", data); + } else if (dataType === "string") { + if (isBase64) { + data = base64.decode(data); + } + else if (isBinary) { + // optimizedBinaryString === true means that the file has already been filtered with a 0xFF mask + if (isOptimizedBinaryString !== true) { + // this is a string, not in a base64 format. + // Be sure that this is a correct "binary string" + data = string2binary(data); + } + } + } + return data; + }); +}; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/zipEntries.js b/ohos-jszip/library/src/main/core/jszip-master/lib/zipEntries.js new file mode 100644 index 00000000..4fb7694c --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/zipEntries.js @@ -0,0 +1,263 @@ +"use strict"; +var readerFor = require("./reader/readerFor"); +var utils = require("./utils"); +var sig = require("./signature"); +var ZipEntry = require("./zipEntry"); +var support = require("./support"); +// class ZipEntries {{{ +/** + * All the entries in the zip file. + * @constructor + * @param {Object} loadOptions Options for loading the stream. + */ +function ZipEntries(loadOptions) { + this.files = []; + this.loadOptions = loadOptions; +} +ZipEntries.prototype = { + /** + * Check that the reader is on the specified signature. + * @param {string} expectedSignature the expected signature. + * @throws {Error} if it is an other signature. + */ + checkSignature: function(expectedSignature) { + if (!this.reader.readAndCheckSignature(expectedSignature)) { + this.reader.index -= 4; + var signature = this.reader.readString(4); + throw new Error("Corrupted zip or bug: unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")"); + } + }, + /** + * Check if the given signature is at the given index. + * @param {number} askedIndex the index to check. + * @param {string} expectedSignature the signature to expect. + * @return {boolean} true if the signature is here, false otherwise. + */ + isSignature: function(askedIndex, expectedSignature) { + var currentIndex = this.reader.index; + this.reader.setIndex(askedIndex); + var signature = this.reader.readString(4); + var result = signature === expectedSignature; + this.reader.setIndex(currentIndex); + return result; + }, + /** + * Read the end of the central directory. + */ + readBlockEndOfCentral: function() { + this.diskNumber = this.reader.readInt(2); + this.diskWithCentralDirStart = this.reader.readInt(2); + this.centralDirRecordsOnThisDisk = this.reader.readInt(2); + this.centralDirRecords = this.reader.readInt(2); + this.centralDirSize = this.reader.readInt(4); + this.centralDirOffset = this.reader.readInt(4); + + this.zipCommentLength = this.reader.readInt(2); + // warning : the encoding depends of the system locale + // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded. + // On a windows machine, this field is encoded with the localized windows code page. + var zipComment = this.reader.readData(this.zipCommentLength); + var decodeParamType = support.uint8array ? "uint8array" : "array"; + // To get consistent behavior with the generation part, we will assume that + // this is utf8 encoded unless specified otherwise. + var decodeContent = utils.transformTo(decodeParamType, zipComment); + this.zipComment = this.loadOptions.decodeFileName(decodeContent); + }, + /** + * Read the end of the Zip 64 central directory. + * Not merged with the method readEndOfCentral : + * The end of central can coexist with its Zip64 brother, + * I don't want to read the wrong number of bytes ! + */ + readBlockZip64EndOfCentral: function() { + this.zip64EndOfCentralSize = this.reader.readInt(8); + this.reader.skip(4); + // this.versionMadeBy = this.reader.readString(2); + // this.versionNeeded = this.reader.readInt(2); + this.diskNumber = this.reader.readInt(4); + this.diskWithCentralDirStart = this.reader.readInt(4); + this.centralDirRecordsOnThisDisk = this.reader.readInt(8); + this.centralDirRecords = this.reader.readInt(8); + this.centralDirSize = this.reader.readInt(8); + this.centralDirOffset = this.reader.readInt(8); + + this.zip64ExtensibleData = {}; + var extraDataSize = this.zip64EndOfCentralSize - 44, + index = 0, + extraFieldId, + extraFieldLength, + extraFieldValue; + while (index < extraDataSize) { + extraFieldId = this.reader.readInt(2); + extraFieldLength = this.reader.readInt(4); + extraFieldValue = this.reader.readData(extraFieldLength); + this.zip64ExtensibleData[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue + }; + } + }, + /** + * Read the end of the Zip 64 central directory locator. + */ + readBlockZip64EndOfCentralLocator: function() { + this.diskWithZip64CentralDirStart = this.reader.readInt(4); + this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); + this.disksCount = this.reader.readInt(4); + if (this.disksCount > 1) { + throw new Error("Multi-volumes zip are not supported"); + } + }, + /** + * Read the local files, based on the offset read in the central part. + */ + readLocalFiles: function() { + var i, file; + for (i = 0; i < this.files.length; i++) { + file = this.files[i]; + this.reader.setIndex(file.localHeaderOffset); + this.checkSignature(sig.LOCAL_FILE_HEADER); + file.readLocalPart(this.reader); + file.handleUTF8(); + file.processAttributes(); + file.readCompressed(this.reader); + } + }, + /** + * Read the central directory. + */ + readCentralDir: function() { + var file; + + this.reader.setIndex(this.centralDirOffset); + while (this.reader.readAndCheckSignature(sig.CENTRAL_FILE_HEADER)) { + file = new ZipEntry({ + zip64: this.zip64, + aes: {} + }, this.loadOptions); + file.readCentralPart(this.reader); + this.files.push(file); + } + + if (this.centralDirRecords !== this.files.length) { + if (this.centralDirRecords !== 0 && this.files.length === 0) { + // We expected some records but couldn't find ANY. + // This is really suspicious, as if something went wrong. + throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length); + } else { + // We found some records but not all. + // Something is wrong but we got something for the user: no error here. + // console.warn("expected", this.centralDirRecords, "records in central dir, got", this.files.length); + } + } + }, + /** + * Read the end of central directory. + */ + readEndOfCentral: function() { + var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END); + if (offset < 0) { + // Check if the content is a truncated zip or complete garbage. + // A "LOCAL_FILE_HEADER" is not required at the beginning (auto + // extractible zip for example) but it can give a good hint. + // If an ajax request was used without responseType, we will also + // get unreadable data. + var isGarbage = !this.isSignature(0, sig.LOCAL_FILE_HEADER); + + if (isGarbage) { + throw new Error("Can't find end of central directory : is this a zip file ? " + + "If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html"); + } else { + throw new Error("Corrupted zip: can't find end of central directory"); + } + + } + this.reader.setIndex(offset); + var endOfCentralDirOffset = offset; + this.checkSignature(sig.CENTRAL_DIRECTORY_END); + this.readBlockEndOfCentral(); + + + /* extract from the zip spec : + 4) If one of the fields in the end of central directory + record is too small to hold required data, the field + should be set to -1 (0xFFFF or 0xFFFFFFFF) and the + ZIP64 format record should be created. + 5) The end of central directory record and the + Zip64 end of central directory locator record must + reside on the same disk when splitting or spanning + an archive. + */ + if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) { + this.zip64 = true; + + /* + Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from + the zip file can fit into a 32bits integer. This cannot be solved : JavaScript represents + all numbers as 64-bit double precision IEEE 754 floating point numbers. + So, we have 53bits for integers and bitwise operations treat everything as 32bits. + see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators + and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 + */ + + // should look for a zip64 EOCD locator + offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); + if (offset < 0) { + throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator"); + } + this.reader.setIndex(offset); + this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); + this.readBlockZip64EndOfCentralLocator(); + + // now the zip64 EOCD record + if (!this.isSignature(this.relativeOffsetEndOfZip64CentralDir, sig.ZIP64_CENTRAL_DIRECTORY_END)) { + // console.warn("ZIP64 end of central directory not where expected."); + this.relativeOffsetEndOfZip64CentralDir = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); + if (this.relativeOffsetEndOfZip64CentralDir < 0) { + throw new Error("Corrupted zip: can't find the ZIP64 end of central directory"); + } + } + this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); + this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); + this.readBlockZip64EndOfCentral(); + } + + var expectedEndOfCentralDirOffset = this.centralDirOffset + this.centralDirSize; + if (this.zip64) { + expectedEndOfCentralDirOffset += 20; // end of central dir 64 locator + expectedEndOfCentralDirOffset += 12 /* should not include the leading 12 bytes */ + this.zip64EndOfCentralSize; + } + + var extraBytes = endOfCentralDirOffset - expectedEndOfCentralDirOffset; + + if (extraBytes > 0) { + // console.warn(extraBytes, "extra bytes at beginning or within zipfile"); + if (this.isSignature(endOfCentralDirOffset, sig.CENTRAL_FILE_HEADER)) { + // The offsets seem wrong, but we have something at the specified offset. + // So… we keep it. + } else { + // the offset is wrong, update the "zero" of the reader + // this happens if data has been prepended (crx files for example) + this.reader.zero = extraBytes; + } + } else if (extraBytes < 0) { + throw new Error("Corrupted zip: missing " + Math.abs(extraBytes) + " bytes."); + } + }, + prepareReader: function(data) { + this.reader = readerFor(data); + }, + /** + * Read a zip file and create ZipEntries. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file. + */ + load: function(data) { + this.prepareReader(data); + this.readEndOfCentral(); + this.readCentralDir(); + this.readLocalFiles(); + } +}; +// }}} end of ZipEntries +module.exports = ZipEntries; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/zipEntry.js b/ohos-jszip/library/src/main/core/jszip-master/lib/zipEntry.js new file mode 100644 index 00000000..b869eb10 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/zipEntry.js @@ -0,0 +1,329 @@ +"use strict"; +var readerFor = require("./reader/readerFor"); +var utils = require("./utils"); +var CompressedObject = require("./compressedObject"); +var crc32fn = require("./crc32"); +var utf8 = require("./utf8"); +var compressions = require("./compressions"); +var support = require("./support"); + +var MADE_BY_DOS = 0x00; +var MADE_BY_UNIX = 0x03; + +/** + * Find a compression registered in JSZip. + * @param {string} compressionMethod the method magic to find. + * @return {Object|null} the JSZip compression object, null if none found. + */ +var findCompression = function(compressionMethod) { + for (var method in compressions) { + if (!Object.prototype.hasOwnProperty.call(compressions, method)) { + continue; + } + if (compressions[method].magic === compressionMethod) { + return compressions[method]; + } + } + return null; +}; + +// class ZipEntry {{{ +/** + * An entry in the zip file. + * @constructor + * @param {Object} options Options of the current file. + * @param {Object} loadOptions Options for loading the stream. + */ +function ZipEntry(options, loadOptions) { + this.options = options; + this.loadOptions = loadOptions; +} +ZipEntry.prototype = { + /** + * say if the file is encrypted. + * @return {boolean} true if the file is encrypted, false otherwise. + */ + isEncrypted: function() { + // bit 1 is set + return (this.bitFlag & 0x0001) === 0x0001; + }, + /** + * say if the file has utf-8 filename/comment. + * @return {boolean} true if the filename/comment is in utf-8, false otherwise. + */ + useUTF8: function() { + // bit 11 is set + return (this.bitFlag & 0x0800) === 0x0800; + }, + /** + * Read the local part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readLocalPart: function(reader) { + var localExtraFieldsLength; + + // we already know everything from the central dir ! + // If the central dir data are false, we are doomed. + // On the bright side, the local part is scary : zip64, data descriptors, both, etc. + // The less data we get here, the more reliable this should be. + // Let's skip the whole header and dash to the data ! + reader.skip(22); + // in some zip created on windows, the filename stored in the central dir contains \ instead of /. + // Strangely, the filename here is OK. + // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes + // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... + // Search "unzip mismatching "local" filename continuing with "central" filename version" on + // the internet. + // + // I think I see the logic here : the central directory is used to display + // content and the local directory is used to extract the files. Mixing / and \ + // may be used to display \ to windows users and use / when extracting the files. + // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 + this.fileNameLength = reader.readInt(2); + localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir + // the fileName is stored as binary data, the handleUTF8 method will take care of the encoding. + this.fileName = reader.readData(this.fileNameLength); + reader.skip(localExtraFieldsLength); + + if (this.compressedSize === -1 || this.uncompressedSize === -1) { + throw new Error("Bug or corrupted zip : didn't get enough information from the central directory " + "(compressedSize === -1 || uncompressedSize === -1)"); + } + + }, + + /** + * Read the compressed file data of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readCompressed: function(reader) { + var compression = findCompression(this.compressionMethod); + if (compression === null) { // no compression found + throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + utils.transformTo("string", this.fileName) + ")"); + } + var compressContent = reader.readData(this.compressedSize); + var decryptOptions = { + password: null, + strength: null + }; + if (this.isEncrypted() && !this.dir) { + if (!this.options.aes.strength) { + throw new Error("Encrypted zip: unsupported encrypt method"); + } + decryptOptions.password = this.loadOptions.password; + decryptOptions.strength = this.options.aes.strength; + decryptOptions.version = this.options.aes.version; + } + this.decompressed = new CompressedObject(this.compressedSize, this.uncompressedSize, this.crc32, compression, compressContent, decryptOptions); + }, + + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readCentralPart: function(reader) { + this.versionMadeBy = reader.readInt(2); + reader.skip(2); + // this.versionNeeded = reader.readInt(2); + this.bitFlag = reader.readInt(2); + this.compressionMethod = reader.readString(2); + this.date = reader.readDate(); + this.crc32 = reader.readInt(4); + this.compressedSize = reader.readInt(4); + this.uncompressedSize = reader.readInt(4); + var fileNameLength = reader.readInt(2); + this.extraFieldsLength = reader.readInt(2); + this.fileCommentLength = reader.readInt(2); + this.diskNumberStart = reader.readInt(2); + this.internalFileAttributes = reader.readInt(2); + this.externalFileAttributes = reader.readInt(4); + this.localHeaderOffset = reader.readInt(4); + + // will be read in the local part, see the comments there + reader.skip(fileNameLength); + this.readExtraFields(reader); + this.parseZIP64ExtraField(reader); + this.parseAESExtraField(); + this.fileComment = reader.readData(this.fileCommentLength); + }, + + /** + * Parse the external file attributes and get the unix/dos permissions. + */ + processAttributes: function () { + this.unixPermissions = null; + this.dosPermissions = null; + var madeBy = this.versionMadeBy >> 8; + + // Check if we have the DOS directory flag set. + // We look for it in the DOS and UNIX permissions + // but some unknown platform could set it as a compatibility flag. + this.dir = this.externalFileAttributes & 0x0010 ? true : false; + + if(madeBy === MADE_BY_DOS) { + // first 6 bits (0 to 5) + this.dosPermissions = this.externalFileAttributes & 0x3F; + } + + if(madeBy === MADE_BY_UNIX) { + this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF; + // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8); + } + + // fail safe : if the name ends with a / it probably means a folder + if (!this.dir && this.fileNameStr.slice(-1) === "/") { + this.dir = true; + } + }, + + /** + * Parse the ZIP64 extra field and merge the info in the current ZipEntry. + * @param {DataReader} reader the reader to use. + */ + parseZIP64ExtraField: function() { + if (!this.extraFields[0x0001]) { + return; + } + + // should be something, preparing the extra reader + var extraReader = readerFor(this.extraFields[0x0001].value); + + // I really hope that these 64bits integer can fit in 32 bits integer, because js + // won't let us have more. + if (this.uncompressedSize === utils.MAX_VALUE_32BITS) { + this.uncompressedSize = extraReader.readInt(8); + } + if (this.compressedSize === utils.MAX_VALUE_32BITS) { + this.compressedSize = extraReader.readInt(8); + } + if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) { + this.localHeaderOffset = extraReader.readInt(8); + } + if (this.diskNumberStart === utils.MAX_VALUE_32BITS) { + this.diskNumberStart = extraReader.readInt(4); + } + }, + + /** + * Parse the AES extra field and add the info in the aes options. + */ + parseAESExtraField: function() { + if (!this.extraFields[0x9901]) { + return; + } + + // should be something, preparing the extra reader + var extraReader = readerFor(this.extraFields[0x9901].value); + + this.options.aes.version = extraReader.readInt(2); + extraReader.skip(2); + this.options.aes.strength = extraReader.readInt(1); + this.compressionMethod = this.options.aes.compressionMethod = extraReader.readString(2); + }, + + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readExtraFields: function(reader) { + var end = reader.index + this.extraFieldsLength, + extraFieldId, + extraFieldLength, + extraFieldValue; + + if (!this.extraFields) { + this.extraFields = {}; + } + + while (reader.index + 4 < end) { + extraFieldId = reader.readInt(2); + extraFieldLength = reader.readInt(2); + extraFieldValue = reader.readData(extraFieldLength); + + this.extraFields[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue + }; + } + + reader.setIndex(end); + }, + + /** + * Apply an UTF8 transformation if needed. + */ + handleUTF8: function() { + var decodeParamType = support.uint8array ? "uint8array" : "array"; + if (this.useUTF8()) { + this.fileNameStr = utf8.utf8decode(this.fileName); + this.fileCommentStr = utf8.utf8decode(this.fileComment); + } else { + var upath = this.findExtraFieldUnicodePath(); + if (upath !== null) { + this.fileNameStr = upath; + } else { + // ASCII text or unsupported code page + var fileNameByteArray = utils.transformTo(decodeParamType, this.fileName); + this.fileNameStr = this.loadOptions.decodeFileName(fileNameByteArray); + } + + var ucomment = this.findExtraFieldUnicodeComment(); + if (ucomment !== null) { + this.fileCommentStr = ucomment; + } else { + // ASCII text or unsupported code page + var commentByteArray = utils.transformTo(decodeParamType, this.fileComment); + this.fileCommentStr = this.loadOptions.decodeFileName(commentByteArray); + } + } + }, + + /** + * Find the unicode path declared in the extra field, if any. + * @return {String} the unicode path, null otherwise. + */ + findExtraFieldUnicodePath: function() { + var upathField = this.extraFields[0x7075]; + if (upathField) { + var extraReader = readerFor(upathField.value); + + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } + + // the crc of the filename changed, this field is out of date. + if (crc32fn(this.fileName) !== extraReader.readInt(4)) { + return null; + } + + return utf8.utf8decode(extraReader.readData(upathField.length - 5)); + } + return null; + }, + + /** + * Find the unicode comment declared in the extra field, if any. + * @return {String} the unicode comment, null otherwise. + */ + findExtraFieldUnicodeComment: function() { + var ucommentField = this.extraFields[0x6375]; + if (ucommentField) { + var extraReader = readerFor(ucommentField.value); + + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } + + // the crc of the comment changed, this field is out of date. + if (crc32fn(this.fileComment) !== extraReader.readInt(4)) { + return null; + } + + return utf8.utf8decode(extraReader.readData(ucommentField.length - 5)); + } + return null; + } +}; +module.exports = ZipEntry; diff --git a/ohos-jszip/library/src/main/core/jszip-master/lib/zipObject.js b/ohos-jszip/library/src/main/core/jszip-master/lib/zipObject.js new file mode 100644 index 00000000..db91ff71 --- /dev/null +++ b/ohos-jszip/library/src/main/core/jszip-master/lib/zipObject.js @@ -0,0 +1,153 @@ +"use strict"; + +var StreamHelper = require("./stream/StreamHelper"); +var DataWorker = require("./stream/DataWorker"); +var utf8 = require("./utf8"); +var CompressedObject = require("./compressedObject"); +var GenericWorker = require("./stream/GenericWorker"); + +/** + * A simple object representing a file in the zip file. + * @constructor + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data + * @param {Object} options the options of the file + */ +var ZipObject = function(name, data, options) { + this.name = name; + this.dir = options.dir; + this.date = options.date; + this.comment = options.comment; + this.unixPermissions = options.unixPermissions; + this.dosPermissions = options.dosPermissions; + + this._data = data; + this._dataBinary = options.binary; + // keep only the compression + this.options = { + compression : options.compression, + compressionOptions : options.compressionOptions + }; + if (options.password || options.encryptStrength) { + this.encryptOptions = { + password: options.password, + strength: options.encryptStrength + }; + } +}; + +ZipObject.prototype = { + /** + * Update the decrypt password for the compressed object. + * @param {String} password the decrypt password of the compressed object. + * @return this ZipObject object. + */ + password: function (password) { + if (this._data.decryptOptions.strength) { + this._data.decryptOptions.password = password; + } + return this; + }, + + /** + * Create an internal stream for the content of this object. + * @param {String} type the type of each chunk. + * @return StreamHelper the stream. + */ + internalStream: function (type) { + var result = null, outputType = "string"; + try { + if (!type) { + throw new Error("No output type specified."); + } + outputType = type.toLowerCase(); + var askUnicodeString = outputType === "string" || outputType === "text"; + if (outputType === "binarystring" || outputType === "text") { + outputType = "string"; + } + result = this._decompressWorker(); + + var isUnicodeString = !this._dataBinary; + + if (isUnicodeString && !askUnicodeString) { + result = result.pipe(new utf8.Utf8EncodeWorker()); + } + if (!isUnicodeString && askUnicodeString) { + result = result.pipe(new utf8.Utf8DecodeWorker()); + } + } catch (e) { + result = new GenericWorker("error"); + result.error(e); + } + + return new StreamHelper(result, outputType, ""); + }, + + /** + * Prepare the content in the asked type. + * @param {String} type the type of the result. + * @param {Function} onUpdate a function to call on each internal update. + * @return Promise the promise of the result. + */ + async: function (type, onUpdate) { + return this.internalStream(type).accumulate(onUpdate); + }, + + /** + * Prepare the content as a nodejs stream. + * @param {String} type the type of each chunk. + * @param {Function} onUpdate a function to call on each internal update. + * @return Stream the stream. + */ + nodeStream: function (type, onUpdate) { + return this.internalStream(type || "nodebuffer").toNodejsStream(onUpdate); + }, + + /** + * Return a worker for the compressed content. + * @private + * @param {Object} compression the compression object to use. + * @param {Object} compressionOptions the options to use when compressing. + * @return Worker the worker. + */ + _compressWorker: function (compression, compressionOptions, encryptOptions) { + if ( + this._data instanceof CompressedObject && + this._data.compression.magic === compression.magic && + this._data.decryptOptions.password === encryptOptions.password && + this._data.decryptOptions.strength === encryptOptions.strength + ) { + return this._data.getCompressedWorker(); + } else { + var result = this._decompressWorker(); + if(!this._dataBinary) { + result = result.pipe(new utf8.Utf8EncodeWorker()); + } + return CompressedObject.createWorkerFrom(result, compression, compressionOptions, encryptOptions); + } + }, + /** + * Return a worker for the decompressed content. + * @private + * @return Worker the worker. + */ + _decompressWorker : function () { + if (this._data instanceof CompressedObject) { + return this._data.getContentWorker(); + } else if (this._data instanceof GenericWorker) { + return this._data; + } else { + return new DataWorker(this._data); + } + } +}; + +var removedMethods = ["asText", "asBinary", "asNodeBuffer", "asUint8Array", "asArrayBuffer"]; +var removedFn = function () { + throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); +}; + +for(var i = 0; i < removedMethods.length; i++) { + ZipObject.prototype[removedMethods[i]] = removedFn; +} +module.exports = ZipObject; diff --git a/ohos-jszip/library/src/main/dist/dist.js b/ohos-jszip/library/src/main/dist/dist.js new file mode 100644 index 00000000..9bef7843 --- /dev/null +++ b/ohos-jszip/library/src/main/dist/dist.js @@ -0,0 +1,15349 @@ +import require$$0 from '@ohos/node-polyfill/src/main/dist/stream'; +import require$$2 from '@ohos/node-polyfill/src/main/dist/events'; +import require$$0$1 from '@ohos/node-polyfill/src/main/dist/buffer'; +import require$$1 from '@ohos/node-polyfill/src/main/dist/util'; +import require$$11 from '@ohos/node-polyfill/src/main/dist/string_decoder'; +import require$$0$2 from '@ohos/node-polyfill/src/main/dist/crypto'; + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +var utf8$5 = {}; + +var utils$s = {}; + +var support$4 = {}; + +var readable = {exports: {}}; + +var processNextickArgs = {exports: {}}; + +var hasRequiredProcessNextickArgs; + +function requireProcessNextickArgs () { + if (hasRequiredProcessNextickArgs) return processNextickArgs.exports; + hasRequiredProcessNextickArgs = 1; + + if (typeof process === 'undefined' || + !process.version || + process.version.indexOf('v0.') === 0 || + process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { + processNextickArgs.exports = { nextTick: nextTick }; + } else { + processNextickArgs.exports = process; + } + + function nextTick(fn, arg1, arg2, arg3) { + if (typeof fn !== 'function') { + throw new TypeError('"callback" argument must be a function'); + } + var len = arguments.length; + var args, i; + switch (len) { + case 0: + case 1: + return process.nextTick(fn); + case 2: + return process.nextTick(function afterTickOne() { + fn.call(null, arg1); + }); + case 3: + return process.nextTick(function afterTickTwo() { + fn.call(null, arg1, arg2); + }); + case 4: + return process.nextTick(function afterTickThree() { + fn.call(null, arg1, arg2, arg3); + }); + default: + args = new Array(len - 1); + i = 0; + while (i < args.length) { + args[i++] = arguments[i]; + } + return process.nextTick(function afterTick() { + fn.apply(null, args); + }); + } + } + return processNextickArgs.exports; +} + +var isarray; +var hasRequiredIsarray; + +function requireIsarray () { + if (hasRequiredIsarray) return isarray; + hasRequiredIsarray = 1; + var toString = {}.toString; + + isarray = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; + }; + return isarray; +} + +var stream; +var hasRequiredStream; + +function requireStream () { + if (hasRequiredStream) return stream; + hasRequiredStream = 1; + stream = require$$0; + return stream; +} + +var safeBuffer = {exports: {}}; + +/* eslint-disable node/no-deprecated-api */ + +var hasRequiredSafeBuffer; + +function requireSafeBuffer () { + if (hasRequiredSafeBuffer) return safeBuffer.exports; + hasRequiredSafeBuffer = 1; + (function (module, exports) { + var buffer = require$$0$1; + var Buffer = buffer.Buffer; + + // alternative to using Object.keys for old browsers + function copyProps (src, dst) { + for (var key in src) { + dst[key] = src[key]; + } + } + if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { + module.exports = buffer; + } else { + // Copy properties from require('buffer') + copyProps(buffer, exports); + exports.Buffer = SafeBuffer; + } + + function SafeBuffer (arg, encodingOrOffset, length) { + return Buffer(arg, encodingOrOffset, length) + } + + // Copy static methods from Buffer + copyProps(Buffer, SafeBuffer); + + SafeBuffer.from = function (arg, encodingOrOffset, length) { + if (typeof arg === 'number') { + throw new TypeError('Argument must not be a number') + } + return Buffer(arg, encodingOrOffset, length) + }; + + SafeBuffer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + var buf = Buffer(size); + if (fill !== undefined) { + if (typeof encoding === 'string') { + buf.fill(fill, encoding); + } else { + buf.fill(fill); + } + } else { + buf.fill(0); + } + return buf + }; + + SafeBuffer.allocUnsafe = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return Buffer(size) + }; + + SafeBuffer.allocUnsafeSlow = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return buffer.SlowBuffer(size) + }; + } (safeBuffer, safeBuffer.exports)); + return safeBuffer.exports; +} + +var util = {}; + +var hasRequiredUtil; + +function requireUtil () { + if (hasRequiredUtil) return util; + hasRequiredUtil = 1; + // Copyright Joyent, Inc. and other Node contributors. + // + // Permission is hereby granted, free of charge, to any person obtaining a + // copy of this software and associated documentation files (the + // "Software"), to deal in the Software without restriction, including + // without limitation the rights to use, copy, modify, merge, publish, + // distribute, sublicense, and/or sell copies of the Software, and to permit + // persons to whom the Software is furnished to do so, subject to the + // following conditions: + // + // The above copyright notice and this permission notice shall be included + // in all copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + // NOTE: These type checking functions intentionally don't use `instanceof` + // because it is fragile and can be easily faked with `Object.create()`. + + function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return objectToString(arg) === '[object Array]'; + } + util.isArray = isArray; + + function isBoolean(arg) { + return typeof arg === 'boolean'; + } + util.isBoolean = isBoolean; + + function isNull(arg) { + return arg === null; + } + util.isNull = isNull; + + function isNullOrUndefined(arg) { + return arg == null; + } + util.isNullOrUndefined = isNullOrUndefined; + + function isNumber(arg) { + return typeof arg === 'number'; + } + util.isNumber = isNumber; + + function isString(arg) { + return typeof arg === 'string'; + } + util.isString = isString; + + function isSymbol(arg) { + return typeof arg === 'symbol'; + } + util.isSymbol = isSymbol; + + function isUndefined(arg) { + return arg === void 0; + } + util.isUndefined = isUndefined; + + function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; + } + util.isRegExp = isRegExp; + + function isObject(arg) { + return typeof arg === 'object' && arg !== null; + } + util.isObject = isObject; + + function isDate(d) { + return objectToString(d) === '[object Date]'; + } + util.isDate = isDate; + + function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); + } + util.isError = isError; + + function isFunction(arg) { + return typeof arg === 'function'; + } + util.isFunction = isFunction; + + function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; + } + util.isPrimitive = isPrimitive; + + util.isBuffer = require$$0$1.Buffer.isBuffer; + + function objectToString(o) { + return Object.prototype.toString.call(o); + } + return util; +} + +var inherits = {exports: {}}; + +var inherits_browser = {exports: {}}; + +var hasRequiredInherits_browser; + +function requireInherits_browser () { + if (hasRequiredInherits_browser) return inherits_browser.exports; + hasRequiredInherits_browser = 1; + if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + inherits_browser.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + } + }; + } else { + // old school shim for old browsers + inherits_browser.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor; + var TempCtor = function () {}; + TempCtor.prototype = superCtor.prototype; + ctor.prototype = new TempCtor(); + ctor.prototype.constructor = ctor; + } + }; + } + return inherits_browser.exports; +} + +var hasRequiredInherits; + +function requireInherits () { + if (hasRequiredInherits) return inherits.exports; + hasRequiredInherits = 1; + try { + var util = require('util'); + /* istanbul ignore next */ + if (typeof util.inherits !== 'function') throw ''; + inherits.exports = util.inherits; + } catch (e) { + /* istanbul ignore next */ + inherits.exports = requireInherits_browser(); + } + return inherits.exports; +} + +var BufferList = {exports: {}}; + +var hasRequiredBufferList; + +function requireBufferList () { + if (hasRequiredBufferList) return BufferList.exports; + hasRequiredBufferList = 1; + (function (module) { + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + var Buffer = requireSafeBuffer().Buffer; + var util = require$$1; + + function copyBuffer(src, target, offset) { + src.copy(target, offset); + } + + module.exports = function () { + function BufferList() { + _classCallCheck(this, BufferList); + + this.head = null; + this.tail = null; + this.length = 0; + } + + BufferList.prototype.push = function push(v) { + var entry = { data: v, next: null }; + if (this.length > 0) this.tail.next = entry;else this.head = entry; + this.tail = entry; + ++this.length; + }; + + BufferList.prototype.unshift = function unshift(v) { + var entry = { data: v, next: this.head }; + if (this.length === 0) this.tail = entry; + this.head = entry; + ++this.length; + }; + + BufferList.prototype.shift = function shift() { + if (this.length === 0) return; + var ret = this.head.data; + if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; + --this.length; + return ret; + }; + + BufferList.prototype.clear = function clear() { + this.head = this.tail = null; + this.length = 0; + }; + + BufferList.prototype.join = function join(s) { + if (this.length === 0) return ''; + var p = this.head; + var ret = '' + p.data; + while (p = p.next) { + ret += s + p.data; + }return ret; + }; + + BufferList.prototype.concat = function concat(n) { + if (this.length === 0) return Buffer.alloc(0); + var ret = Buffer.allocUnsafe(n >>> 0); + var p = this.head; + var i = 0; + while (p) { + copyBuffer(p.data, ret, i); + i += p.data.length; + p = p.next; + } + return ret; + }; + + return BufferList; + }(); + + if (util && util.inspect && util.inspect.custom) { + module.exports.prototype[util.inspect.custom] = function () { + var obj = util.inspect({ length: this.length }); + return this.constructor.name + ' ' + obj; + }; + } + } (BufferList)); + return BufferList.exports; +} + +var destroy_1; +var hasRequiredDestroy; + +function requireDestroy () { + if (hasRequiredDestroy) return destroy_1; + hasRequiredDestroy = 1; + + /**/ + + var pna = requireProcessNextickArgs(); + /**/ + + // undocumented cb() API, needed for core, not for public API + function destroy(err, cb) { + var _this = this; + + var readableDestroyed = this._readableState && this._readableState.destroyed; + var writableDestroyed = this._writableState && this._writableState.destroyed; + + if (readableDestroyed || writableDestroyed) { + if (cb) { + cb(err); + } else if (err) { + if (!this._writableState) { + pna.nextTick(emitErrorNT, this, err); + } else if (!this._writableState.errorEmitted) { + this._writableState.errorEmitted = true; + pna.nextTick(emitErrorNT, this, err); + } + } + + return this; + } + + // we set destroyed to true before firing error callbacks in order + // to make it re-entrance safe in case destroy() is called within callbacks + + if (this._readableState) { + this._readableState.destroyed = true; + } + + // if this is a duplex stream mark the writable part as destroyed as well + if (this._writableState) { + this._writableState.destroyed = true; + } + + this._destroy(err || null, function (err) { + if (!cb && err) { + if (!_this._writableState) { + pna.nextTick(emitErrorNT, _this, err); + } else if (!_this._writableState.errorEmitted) { + _this._writableState.errorEmitted = true; + pna.nextTick(emitErrorNT, _this, err); + } + } else if (cb) { + cb(err); + } + }); + + return this; + } + + function undestroy() { + if (this._readableState) { + this._readableState.destroyed = false; + this._readableState.reading = false; + this._readableState.ended = false; + this._readableState.endEmitted = false; + } + + if (this._writableState) { + this._writableState.destroyed = false; + this._writableState.ended = false; + this._writableState.ending = false; + this._writableState.finalCalled = false; + this._writableState.prefinished = false; + this._writableState.finished = false; + this._writableState.errorEmitted = false; + } + } + + function emitErrorNT(self, err) { + self.emit('error', err); + } + + destroy_1 = { + destroy: destroy, + undestroy: undestroy + }; + return destroy_1; +} + +var node; +var hasRequiredNode; + +function requireNode () { + if (hasRequiredNode) return node; + hasRequiredNode = 1; + /** + * For Node.js, simply re-export the core `util.deprecate` function. + */ + + node = require$$1.deprecate; + return node; +} + +var _stream_writable; +var hasRequired_stream_writable; + +function require_stream_writable () { + if (hasRequired_stream_writable) return _stream_writable; + hasRequired_stream_writable = 1; + + /**/ + + var pna = requireProcessNextickArgs(); + /**/ + + _stream_writable = Writable; + + // It seems a linked list but it is not + // there will be only 2 of these for each stream + function CorkedRequest(state) { + var _this = this; + + this.next = null; + this.entry = null; + this.finish = function () { + onCorkedFinish(_this, state); + }; + } + /* */ + + /**/ + var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick; + /**/ + + /**/ + var Duplex; + /**/ + + Writable.WritableState = WritableState; + + /**/ + var util = Object.create(requireUtil()); + util.inherits = requireInherits(); + /**/ + + /**/ + var internalUtil = { + deprecate: requireNode() + }; + /**/ + + /**/ + var Stream = requireStream(); + /**/ + + /**/ + + var Buffer = requireSafeBuffer().Buffer; + var OurUint8Array = (typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {}; + function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); + } + function _isUint8Array(obj) { + return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; + } + + /**/ + + var destroyImpl = requireDestroy(); + + util.inherits(Writable, Stream); + + function nop() {} + + function WritableState(options, stream) { + Duplex = Duplex || require_stream_duplex(); + + options = options || {}; + + // Duplex streams are both readable and writable, but share + // the same options object. + // However, some cases require setting options to different + // values for the readable and the writable sides of the duplex stream. + // These options can be provided separately as readableXXX and writableXXX. + var isDuplex = stream instanceof Duplex; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var writableHwm = options.writableHighWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + + if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm;else this.highWaterMark = defaultHwm; + + // cast to ints. + this.highWaterMark = Math.floor(this.highWaterMark); + + // if _final has been called + this.finalCalled = false; + + // drain event flag. + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // has it been destroyed + this.destroyed = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function (er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.bufferedRequest = null; + this.lastBufferedRequest = null; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; + + // count buffered requests + this.bufferedRequestCount = 0; + + // allocate the first CorkedRequest, there is always + // one allocated and free to use, and we maintain at most two + this.corkedRequestsFree = new CorkedRequest(this); + } + + WritableState.prototype.getBuffer = function getBuffer() { + var current = this.bufferedRequest; + var out = []; + while (current) { + out.push(current); + current = current.next; + } + return out; + }; + + (function () { + try { + Object.defineProperty(WritableState.prototype, 'buffer', { + get: internalUtil.deprecate(function () { + return this.getBuffer(); + }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') + }); + } catch (_) {} + })(); + + // Test _writableState for inheritance to account for Duplex streams, + // whose prototype chain only points to Readable. + var realHasInstance; + if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { + realHasInstance = Function.prototype[Symbol.hasInstance]; + Object.defineProperty(Writable, Symbol.hasInstance, { + value: function (object) { + if (realHasInstance.call(this, object)) return true; + if (this !== Writable) return false; + + return object && object._writableState instanceof WritableState; + } + }); + } else { + realHasInstance = function (object) { + return object instanceof this; + }; + } + + function Writable(options) { + Duplex = Duplex || require_stream_duplex(); + + // Writable ctor is applied to Duplexes, too. + // `realHasInstance` is necessary because using plain `instanceof` + // would return false, as no `_writableState` property is attached. + + // Trying to use the custom `instanceof` for Writable here will also break the + // Node.js LazyTransform implementation, which has a non-trivial getter for + // `_writableState` that would lead to infinite recursion. + if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) { + return new Writable(options); + } + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + if (options) { + if (typeof options.write === 'function') this._write = options.write; + + if (typeof options.writev === 'function') this._writev = options.writev; + + if (typeof options.destroy === 'function') this._destroy = options.destroy; + + if (typeof options.final === 'function') this._final = options.final; + } + + Stream.call(this); + } + + // Otherwise people can pipe Writable streams, which is just wrong. + Writable.prototype.pipe = function () { + this.emit('error', new Error('Cannot pipe, not readable')); + }; + + function writeAfterEnd(stream, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + pna.nextTick(cb, er); + } + + // Checks that a user-supplied chunk is valid, especially for the particular + // mode the stream is in. Currently this means that `null` is never accepted + // and undefined/non-string values are only allowed in object mode. + function validChunk(stream, state, chunk, cb) { + var valid = true; + var er = false; + + if (chunk === null) { + er = new TypeError('May not write null values to stream'); + } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + if (er) { + stream.emit('error', er); + pna.nextTick(cb, er); + valid = false; + } + return valid; + } + + Writable.prototype.write = function (chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + var isBuf = !state.objectMode && _isUint8Array(chunk); + + if (isBuf && !Buffer.isBuffer(chunk)) { + chunk = _uint8ArrayToBuffer(chunk); + } + + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; + + if (typeof cb !== 'function') cb = nop; + + if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); + } + + return ret; + }; + + Writable.prototype.cork = function () { + var state = this._writableState; + + state.corked++; + }; + + Writable.prototype.uncork = function () { + var state = this._writableState; + + if (state.corked) { + state.corked--; + + if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); + } + }; + + Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { + // node::ParseEncoding() requires lower case. + if (typeof encoding === 'string') encoding = encoding.toLowerCase(); + if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); + this._writableState.defaultEncoding = encoding; + return this; + }; + + function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { + chunk = Buffer.from(chunk, encoding); + } + return chunk; + } + + Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function () { + return this._writableState.highWaterMark; + } + }); + + // if we're already writing something, then just put this + // in the queue, and wait our turn. Otherwise, call _write + // If we return false, then we need a drain event, so set that flag. + function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { + if (!isBuf) { + var newChunk = decodeChunk(state, chunk, encoding); + if (chunk !== newChunk) { + isBuf = true; + encoding = 'buffer'; + chunk = newChunk; + } + } + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) state.needDrain = true; + + if (state.writing || state.corked) { + var last = state.lastBufferedRequest; + state.lastBufferedRequest = { + chunk: chunk, + encoding: encoding, + isBuf: isBuf, + callback: cb, + next: null + }; + if (last) { + last.next = state.lastBufferedRequest; + } else { + state.bufferedRequest = state.lastBufferedRequest; + } + state.bufferedRequestCount += 1; + } else { + doWrite(stream, state, false, len, chunk, encoding, cb); + } + + return ret; + } + + function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); + state.sync = false; + } + + function onwriteError(stream, state, sync, er, cb) { + --state.pendingcb; + + if (sync) { + // defer the callback if we are being called synchronously + // to avoid piling up things on the stack + pna.nextTick(cb, er); + // this can emit finish, and it will always happen + // after error + pna.nextTick(finishMaybe, stream, state); + stream._writableState.errorEmitted = true; + stream.emit('error', er); + } else { + // the caller expect this to happen before if + // it is async + cb(er); + stream._writableState.errorEmitted = true; + stream.emit('error', er); + // this can emit finish, but finish must + // always follow error + finishMaybe(stream, state); + } + } + + function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; + } + + function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + + onwriteStateUpdate(state); + + if (er) onwriteError(stream, state, sync, er, cb);else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(state); + + if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { + clearBuffer(stream, state); + } + + if (sync) { + /**/ + asyncWrite(afterWrite, stream, state, finished, cb); + /**/ + } else { + afterWrite(stream, state, finished, cb); + } + } + } + + function afterWrite(stream, state, finished, cb) { + if (!finished) onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); + } + + // Must force callback to be called on nextTick, so that we don't + // emit 'drain' before the write() consumer gets the 'false' return + // value, and has a chance to attach a 'drain' listener. + function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } + } + + // if there's something in the buffer waiting, then process it + function clearBuffer(stream, state) { + state.bufferProcessing = true; + var entry = state.bufferedRequest; + + if (stream._writev && entry && entry.next) { + // Fast case, write everything using _writev() + var l = state.bufferedRequestCount; + var buffer = new Array(l); + var holder = state.corkedRequestsFree; + holder.entry = entry; + + var count = 0; + var allBuffers = true; + while (entry) { + buffer[count] = entry; + if (!entry.isBuf) allBuffers = false; + entry = entry.next; + count += 1; + } + buffer.allBuffers = allBuffers; + + doWrite(stream, state, true, state.length, buffer, '', holder.finish); + + // doWrite is almost always async, defer these to save a bit of time + // as the hot path ends with doWrite + state.pendingcb++; + state.lastBufferedRequest = null; + if (holder.next) { + state.corkedRequestsFree = holder.next; + holder.next = null; + } else { + state.corkedRequestsFree = new CorkedRequest(state); + } + state.bufferedRequestCount = 0; + } else { + // Slow case, write chunks one-by-one + while (entry) { + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, false, len, chunk, encoding, cb); + entry = entry.next; + state.bufferedRequestCount--; + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + break; + } + } + + if (entry === null) state.lastBufferedRequest = null; + } + + state.bufferedRequest = entry; + state.bufferProcessing = false; + } + + Writable.prototype._write = function (chunk, encoding, cb) { + cb(new Error('_write() is not implemented')); + }; + + Writable.prototype._writev = null; + + Writable.prototype.end = function (chunk, encoding, cb) { + var state = this._writableState; + + if (typeof chunk === 'function') { + cb = chunk; + chunk = null; + encoding = null; + } else if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); + + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } + + // ignore unnecessary end() calls. + if (!state.ending) endWritable(this, state, cb); + }; + + function needFinish(state) { + return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; + } + function callFinal(stream, state) { + stream._final(function (err) { + state.pendingcb--; + if (err) { + stream.emit('error', err); + } + state.prefinished = true; + stream.emit('prefinish'); + finishMaybe(stream, state); + }); + } + function prefinish(stream, state) { + if (!state.prefinished && !state.finalCalled) { + if (typeof stream._final === 'function') { + state.pendingcb++; + state.finalCalled = true; + pna.nextTick(callFinal, stream, state); + } else { + state.prefinished = true; + stream.emit('prefinish'); + } + } + } + + function finishMaybe(stream, state) { + var need = needFinish(state); + if (need) { + prefinish(stream, state); + if (state.pendingcb === 0) { + state.finished = true; + stream.emit('finish'); + } + } + return need; + } + + function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) pna.nextTick(cb);else stream.once('finish', cb); + } + state.ended = true; + stream.writable = false; + } + + function onCorkedFinish(corkReq, state, err) { + var entry = corkReq.entry; + corkReq.entry = null; + while (entry) { + var cb = entry.callback; + state.pendingcb--; + cb(err); + entry = entry.next; + } + + // reuse the free corkReq. + state.corkedRequestsFree.next = corkReq; + } + + Object.defineProperty(Writable.prototype, 'destroyed', { + get: function () { + if (this._writableState === undefined) { + return false; + } + return this._writableState.destroyed; + }, + set: function (value) { + // we ignore the value if the stream + // has not been initialized yet + if (!this._writableState) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._writableState.destroyed = value; + } + }); + + Writable.prototype.destroy = destroyImpl.destroy; + Writable.prototype._undestroy = destroyImpl.undestroy; + Writable.prototype._destroy = function (err, cb) { + this.end(); + cb(err); + }; + return _stream_writable; +} + +var _stream_duplex; +var hasRequired_stream_duplex; + +function require_stream_duplex () { + if (hasRequired_stream_duplex) return _stream_duplex; + hasRequired_stream_duplex = 1; + + /**/ + + var pna = requireProcessNextickArgs(); + /**/ + + /**/ + var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + keys.push(key); + }return keys; + }; + /**/ + + _stream_duplex = Duplex; + + /**/ + var util = Object.create(requireUtil()); + util.inherits = requireInherits(); + /**/ + + var Readable = require_stream_readable(); + var Writable = require_stream_writable(); + + util.inherits(Duplex, Readable); + + { + // avoid scope creep, the keys array can then be collected + var keys = objectKeys(Writable.prototype); + for (var v = 0; v < keys.length; v++) { + var method = keys[v]; + if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; + } + } + + function Duplex(options) { + if (!(this instanceof Duplex)) return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) this.readable = false; + + if (options && options.writable === false) this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; + + this.once('end', onend); + } + + Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function () { + return this._writableState.highWaterMark; + } + }); + + // the no-half-open enforcer + function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) return; + + // no more data can be written. + // But allow more writes to happen in this tick. + pna.nextTick(onEndNT, this); + } + + function onEndNT(self) { + self.end(); + } + + Object.defineProperty(Duplex.prototype, 'destroyed', { + get: function () { + if (this._readableState === undefined || this._writableState === undefined) { + return false; + } + return this._readableState.destroyed && this._writableState.destroyed; + }, + set: function (value) { + // we ignore the value if the stream + // has not been initialized yet + if (this._readableState === undefined || this._writableState === undefined) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._readableState.destroyed = value; + this._writableState.destroyed = value; + } + }); + + Duplex.prototype._destroy = function (err, cb) { + this.push(null); + this.end(); + + pna.nextTick(cb, err); + }; + return _stream_duplex; +} + +var _stream_readable; +var hasRequired_stream_readable; + +function require_stream_readable () { + if (hasRequired_stream_readable) return _stream_readable; + hasRequired_stream_readable = 1; + + /**/ + + var pna = requireProcessNextickArgs(); + /**/ + + _stream_readable = Readable; + + /**/ + var isArray = requireIsarray(); + /**/ + + /**/ + var Duplex; + /**/ + + Readable.ReadableState = ReadableState; + + /**/ + require$$2.EventEmitter; + + var EElistenerCount = function (emitter, type) { + return emitter.listeners(type).length; + }; + /**/ + + /**/ + var Stream = requireStream(); + /**/ + + /**/ + + var Buffer = requireSafeBuffer().Buffer; + var OurUint8Array = (typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {}; + function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); + } + function _isUint8Array(obj) { + return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; + } + + /**/ + + /**/ + var util = Object.create(requireUtil()); + util.inherits = requireInherits(); + /**/ + + /**/ + var debugUtil = require$$1; + var debug = void 0; + if (debugUtil && debugUtil.debuglog) { + debug = debugUtil.debuglog('stream'); + } else { + debug = function () {}; + } + /**/ + + var BufferList = requireBufferList(); + var destroyImpl = requireDestroy(); + var StringDecoder; + + util.inherits(Readable, Stream); + + var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; + + function prependListener(emitter, event, fn) { + // Sadly this is not cacheable as some libraries bundle their own + // event emitter implementation with them. + if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn); + + // This is a hack to make sure that our error handler is attached before any + // userland ones. NEVER DO THIS. This is here only because this code needs + // to continue to work with older versions of Node.js that do not include + // the prependListener() method. The goal is to eventually remove this hack. + if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; + } + + function ReadableState(options, stream) { + Duplex = Duplex || require_stream_duplex(); + + options = options || {}; + + // Duplex streams are both readable and writable, but share + // the same options object. + // However, some cases require setting options to different + // values for the readable and the writable sides of the duplex stream. + // These options can be provided separately as readableXXX and writableXXX. + var isDuplex = stream instanceof Duplex; + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var readableHwm = options.readableHighWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + + if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (readableHwm || readableHwm === 0)) this.highWaterMark = readableHwm;else this.highWaterMark = defaultHwm; + + // cast to ints. + this.highWaterMark = Math.floor(this.highWaterMark); + + // A linked list is used to store data chunks instead of an array because the + // linked list can remove elements from the beginning faster than + // array.shift() + this.buffer = new BufferList(); + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the event 'readable'/'data' is emitted + // immediately, or on a later tick. We set this to true at first, because + // any actions that shouldn't happen until "later" should generally also + // not happen before the first read call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + this.resumeScheduled = false; + + // has it been destroyed + this.destroyed = false; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) StringDecoder = require$$11.StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } + } + + function Readable(options) { + Duplex = Duplex || require_stream_duplex(); + + if (!(this instanceof Readable)) return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + if (options) { + if (typeof options.read === 'function') this._read = options.read; + + if (typeof options.destroy === 'function') this._destroy = options.destroy; + } + + Stream.call(this); + } + + Object.defineProperty(Readable.prototype, 'destroyed', { + get: function () { + if (this._readableState === undefined) { + return false; + } + return this._readableState.destroyed; + }, + set: function (value) { + // we ignore the value if the stream + // has not been initialized yet + if (!this._readableState) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._readableState.destroyed = value; + } + }); + + Readable.prototype.destroy = destroyImpl.destroy; + Readable.prototype._undestroy = destroyImpl.undestroy; + Readable.prototype._destroy = function (err, cb) { + this.push(null); + cb(err); + }; + + // Manually shove something into the read() buffer. + // This returns true if the highWaterMark has not been hit yet, + // similar to how Writable.write() returns true if you should + // write() some more. + Readable.prototype.push = function (chunk, encoding) { + var state = this._readableState; + var skipChunkCheck; + + if (!state.objectMode) { + if (typeof chunk === 'string') { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = Buffer.from(chunk, encoding); + encoding = ''; + } + skipChunkCheck = true; + } + } else { + skipChunkCheck = true; + } + + return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); + }; + + // Unshift should *always* be something directly out of read() + Readable.prototype.unshift = function (chunk) { + return readableAddChunk(this, chunk, null, true, false); + }; + + function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { + var state = stream._readableState; + if (chunk === null) { + state.reading = false; + onEofChunk(stream, state); + } else { + var er; + if (!skipChunkCheck) er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { + chunk = _uint8ArrayToBuffer(chunk); + } + + if (addToFront) { + if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true); + } else if (state.ended) { + stream.emit('error', new Error('stream.push() after EOF')); + } else { + state.reading = false; + if (state.decoder && !encoding) { + chunk = state.decoder.write(chunk); + if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); + } else { + addChunk(stream, state, chunk, false); + } + } + } else if (!addToFront) { + state.reading = false; + } + } + + return needMoreData(state); + } + + function addChunk(stream, state, chunk, addToFront) { + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); + + if (state.needReadable) emitReadable(stream); + } + maybeReadMore(stream, state); + } + + function chunkInvalid(state, chunk) { + var er; + if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; + } + + // if it's past the high water mark, we can push in some more. + // Also, if we have no data yet, we can stand some + // more bytes. This is to work around cases where hwm=0, + // such as the repl. Also, if the push() triggered a + // readable event, and the user called read(largeNumber) such that + // needReadable was set, then we ought to push more, so that another + // 'readable' event will be triggered. + function needMoreData(state) { + return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); + } + + Readable.prototype.isPaused = function () { + return this._readableState.flowing === false; + }; + + // backwards compatibility. + Readable.prototype.setEncoding = function (enc) { + if (!StringDecoder) StringDecoder = require$$11.StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; + }; + + // Don't raise the hwm > 8MB + var MAX_HWM = 0x800000; + function computeNewHighWaterMark(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 to prevent increasing hwm excessively in + // tiny amounts + n--; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + n++; + } + return n; + } + + // This function is designed to be inlinable, so please take care when making + // changes to the function body. + function howMuchToRead(n, state) { + if (n <= 0 || state.length === 0 && state.ended) return 0; + if (state.objectMode) return 1; + if (n !== n) { + // Only flow one buffer at a time + if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; + } + // If we're asking for more than the current hwm, then raise the hwm. + if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); + if (n <= state.length) return n; + // Don't have enough + if (!state.ended) { + state.needReadable = true; + return 0; + } + return state.length; + } + + // you can override either this method, or the async _read(n) below. + Readable.prototype.read = function (n) { + debug('read', n); + n = parseInt(n, 10); + var state = this._readableState; + var nOrig = n; + + if (n !== 0) state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) endReadable(this); + return null; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } else if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (!state.reading) n = howMuchToRead(nOrig, state); + } + + var ret; + if (n > 0) ret = fromList(n, state);else ret = null; + + if (ret === null) { + state.needReadable = true; + n = 0; + } else { + state.length -= n; + } + + if (state.length === 0) { + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (!state.ended) state.needReadable = true; + + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended) endReadable(this); + } + + if (ret !== null) this.emit('data', ret); + + return ret; + }; + + function onEofChunk(stream, state) { + if (state.ended) return; + if (state.decoder) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); + } + + // Don't emit readable right away in sync mode, because this can trigger + // another read() call => stack overflow. This way, it might trigger + // a nextTick recursion warning, but that's not so bad. + function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) pna.nextTick(emitReadable_, stream);else emitReadable_(stream); + } + } + + function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); + } + + // at this point, the user has presumably seen the 'readable' event, + // and called read() to consume some data. that may have triggered + // in turn another _read(n) call, in which case reading = true if + // it's in progress. + // However, if we're not ended, or reading, and the length < hwm, + // then go ahead and try to read some more preemptively. + function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + pna.nextTick(maybeReadMore_, stream, state); + } + } + + function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break;else len = state.length; + } + state.readingMore = false; + } + + // abstract method. to be overridden in specific implementation classes. + // call cb(er, data) where data is <= n in length. + // for virtual (non-string, non-buffer) streams, "length" is somewhat + // arbitrary, and perhaps not very meaningful. + Readable.prototype._read = function (n) { + this.emit('error', new Error('_read() is not implemented')); + }; + + Readable.prototype.pipe = function (dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; + + var endFn = doEnd ? onend : unpipe; + if (state.endEmitted) pna.nextTick(endFn);else src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable, unpipeInfo) { + debug('onunpipe'); + if (readable === src) { + if (unpipeInfo && unpipeInfo.hasUnpiped === false) { + unpipeInfo.hasUnpiped = true; + cleanup(); + } + } + } + + function onend() { + debug('onend'); + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + + var cleanedUp = false; + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', unpipe); + src.removeListener('data', ondata); + + cleanedUp = true; + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); + } + + // If the user pushes more data while we're writing to dest then we'll end up + // in ondata again. However, we only want to increase awaitDrain once because + // dest will only emit one 'drain' event for the multiple writes. + // => Introduce a guard on increasing awaitDrain. + var increasedAwaitDrain = false; + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + increasedAwaitDrain = false; + var ret = dest.write(chunk); + if (false === ret && !increasedAwaitDrain) { + // If the user unpiped during `dest.write()`, it is possible + // to get stuck in a permanently paused state if that write + // also returned false. + // => Check whether `dest` is still a piping destination. + if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { + debug('false write response, pause', state.awaitDrain); + state.awaitDrain++; + increasedAwaitDrain = true; + } + src.pause(); + } + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); + } + + // Make sure our error handler is attached before userland ones. + prependListener(dest, 'error', onerror); + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + return dest; + }; + + function pipeOnDrain(src) { + return function () { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) state.awaitDrain--; + if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; + } + + Readable.prototype.unpipe = function (dest) { + var state = this._readableState; + var unpipeInfo = { hasUnpiped: false }; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) return this; + + if (!dest) dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) dest.emit('unpipe', this, unpipeInfo); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var i = 0; i < len; i++) { + dests[i].emit('unpipe', this, { hasUnpiped: false }); + }return this; + } + + // try to find the right one. + var index = indexOf(state.pipes, dest); + if (index === -1) return this; + + state.pipes.splice(index, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) state.pipes = state.pipes[0]; + + dest.emit('unpipe', this, unpipeInfo); + + return this; + }; + + // set up data events if they are asked for + // Ensure readable listeners eventually get something + Readable.prototype.on = function (ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + if (ev === 'data') { + // Start flowing on next tick if stream isn't explicitly paused + if (this._readableState.flowing !== false) this.resume(); + } else if (ev === 'readable') { + var state = this._readableState; + if (!state.endEmitted && !state.readableListening) { + state.readableListening = state.needReadable = true; + state.emittedReadable = false; + if (!state.reading) { + pna.nextTick(nReadingNextTick, this); + } else if (state.length) { + emitReadable(this); + } + } + } + + return res; + }; + Readable.prototype.addListener = Readable.prototype.on; + + function nReadingNextTick(self) { + debug('readable nexttick read 0'); + self.read(0); + } + + // pause() and resume() are remnants of the legacy readable stream API + // If the user uses them, then switch into old mode. + Readable.prototype.resume = function () { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + resume(this, state); + } + return this; + }; + + function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + pna.nextTick(resume_, stream, state); + } + } + + function resume_(stream, state) { + if (!state.reading) { + debug('resume read 0'); + stream.read(0); + } + + state.resumeScheduled = false; + state.awaitDrain = 0; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) stream.read(0); + } + + Readable.prototype.pause = function () { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + return this; + }; + + function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + while (state.flowing && stream.read() !== null) {} + } + + // wrap an old-style stream as the async data source. + // This is *not* part of the readable stream interface. + // It is an ugly unfortunate mess of history. + Readable.prototype.wrap = function (stream) { + var _this = this; + + var state = this._readableState; + var paused = false; + + stream.on('end', function () { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) _this.push(chunk); + } + + _this.push(null); + }); + + stream.on('data', function (chunk) { + debug('wrapped data'); + if (state.decoder) chunk = state.decoder.write(chunk); + + // don't skip over falsy values in objectMode + if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; + + var ret = _this.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (this[i] === undefined && typeof stream[i] === 'function') { + this[i] = function (method) { + return function () { + return stream[method].apply(stream, arguments); + }; + }(i); + } + } + + // proxy certain important events. + for (var n = 0; n < kProxyEvents.length; n++) { + stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n])); + } + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + this._read = function (n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + + return this; + }; + + Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function () { + return this._readableState.highWaterMark; + } + }); + + // exposed for testing purposes only. + Readable._fromList = fromList; + + // Pluck off n bytes from an array of buffers. + // Length is the combined lengths of all the buffers in the list. + // This function is designed to be inlinable, so please take care when making + // changes to the function body. + function fromList(n, state) { + // nothing buffered + if (state.length === 0) return null; + + var ret; + if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { + // read it all, truncate the list + if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); + state.buffer.clear(); + } else { + // read part of list + ret = fromListPartial(n, state.buffer, state.decoder); + } + + return ret; + } + + // Extracts only enough buffered data to satisfy the amount requested. + // This function is designed to be inlinable, so please take care when making + // changes to the function body. + function fromListPartial(n, list, hasStrings) { + var ret; + if (n < list.head.data.length) { + // slice is the same for buffers and strings + ret = list.head.data.slice(0, n); + list.head.data = list.head.data.slice(n); + } else if (n === list.head.data.length) { + // first chunk is a perfect match + ret = list.shift(); + } else { + // result spans more than one buffer + ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); + } + return ret; + } + + // Copies a specified amount of characters from the list of buffered data + // chunks. + // This function is designed to be inlinable, so please take care when making + // changes to the function body. + function copyFromBufferString(n, list) { + var p = list.head; + var c = 1; + var ret = p.data; + n -= ret.length; + while (p = p.next) { + var str = p.data; + var nb = n > str.length ? str.length : n; + if (nb === str.length) ret += str;else ret += str.slice(0, n); + n -= nb; + if (n === 0) { + if (nb === str.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = str.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; + } + + // Copies a specified amount of bytes from the list of buffered data chunks. + // This function is designed to be inlinable, so please take care when making + // changes to the function body. + function copyFromBuffer(n, list) { + var ret = Buffer.allocUnsafe(n); + var p = list.head; + var c = 1; + p.data.copy(ret); + n -= p.data.length; + while (p = p.next) { + var buf = p.data; + var nb = n > buf.length ? buf.length : n; + buf.copy(ret, ret.length - n, 0, nb); + n -= nb; + if (n === 0) { + if (nb === buf.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = buf.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; + } + + function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); + + if (!state.endEmitted) { + state.ended = true; + pna.nextTick(endReadableNT, state, stream); + } + } + + function endReadableNT(state, stream) { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } + } + + function indexOf(xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; + } + return _stream_readable; +} + +var _stream_transform; +var hasRequired_stream_transform; + +function require_stream_transform () { + if (hasRequired_stream_transform) return _stream_transform; + hasRequired_stream_transform = 1; + + _stream_transform = Transform; + + var Duplex = require_stream_duplex(); + + /**/ + var util = Object.create(requireUtil()); + util.inherits = requireInherits(); + /**/ + + util.inherits(Transform, Duplex); + + function afterTransform(er, data) { + var ts = this._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) { + return this.emit('error', new Error('write callback called multiple times')); + } + + ts.writechunk = null; + ts.writecb = null; + + if (data != null) // single equals check for both `null` and `undefined` + this.push(data); + + cb(er); + + var rs = this._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + this._read(rs.highWaterMark); + } + } + + function Transform(options) { + if (!(this instanceof Transform)) return new Transform(options); + + Duplex.call(this, options); + + this._transformState = { + afterTransform: afterTransform.bind(this), + needTransform: false, + transforming: false, + writecb: null, + writechunk: null, + writeencoding: null + }; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + if (options) { + if (typeof options.transform === 'function') this._transform = options.transform; + + if (typeof options.flush === 'function') this._flush = options.flush; + } + + // When the writable side finishes, then flush out anything remaining. + this.on('prefinish', prefinish); + } + + function prefinish() { + var _this = this; + + if (typeof this._flush === 'function') { + this._flush(function (er, data) { + done(_this, er, data); + }); + } else { + done(this, null, null); + } + } + + Transform.prototype.push = function (chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); + }; + + // This is the part where you do stuff! + // override this function in implementation classes. + // 'chunk' is an input chunk. + // + // Call `push(newChunk)` to pass along transformed output + // to the readable side. You may call 'push' zero or more times. + // + // Call `cb(err)` when you are done with this chunk. If you pass + // an error, then that'll put the hurt on the whole operation. If you + // never call cb(), then you'll never get another chunk. + Transform.prototype._transform = function (chunk, encoding, cb) { + throw new Error('_transform() is not implemented'); + }; + + Transform.prototype._write = function (chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); + } + }; + + // Doesn't matter what the args are here. + // _transform does all the work. + // That we got here means that the readable side wants more data. + Transform.prototype._read = function (n) { + var ts = this._transformState; + + if (ts.writechunk !== null && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } + }; + + Transform.prototype._destroy = function (err, cb) { + var _this2 = this; + + Duplex.prototype._destroy.call(this, err, function (err2) { + cb(err2); + _this2.emit('close'); + }); + }; + + function done(stream, er, data) { + if (er) return stream.emit('error', er); + + if (data != null) // single equals check for both `null` and `undefined` + stream.push(data); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + if (stream._writableState.length) throw new Error('Calling transform done when ws.length != 0'); + + if (stream._transformState.transforming) throw new Error('Calling transform done when still transforming'); + + return stream.push(null); + } + return _stream_transform; +} + +var _stream_passthrough; +var hasRequired_stream_passthrough; + +function require_stream_passthrough () { + if (hasRequired_stream_passthrough) return _stream_passthrough; + hasRequired_stream_passthrough = 1; + + _stream_passthrough = PassThrough; + + var Transform = require_stream_transform(); + + /**/ + var util = Object.create(requireUtil()); + util.inherits = requireInherits(); + /**/ + + util.inherits(PassThrough, Transform); + + function PassThrough(options) { + if (!(this instanceof PassThrough)) return new PassThrough(options); + + Transform.call(this, options); + } + + PassThrough.prototype._transform = function (chunk, encoding, cb) { + cb(null, chunk); + }; + return _stream_passthrough; +} + +var hasRequiredReadable; + +function requireReadable () { + if (hasRequiredReadable) return readable.exports; + hasRequiredReadable = 1; + (function (module, exports) { + var Stream = require$$0; + if (process.env.READABLE_STREAM === 'disable' && Stream) { + module.exports = Stream; + exports = module.exports = Stream.Readable; + exports.Readable = Stream.Readable; + exports.Writable = Stream.Writable; + exports.Duplex = Stream.Duplex; + exports.Transform = Stream.Transform; + exports.PassThrough = Stream.PassThrough; + exports.Stream = Stream; + } else { + exports = module.exports = require_stream_readable(); + exports.Stream = Stream || exports; + exports.Readable = exports; + exports.Writable = require_stream_writable(); + exports.Duplex = require_stream_duplex(); + exports.Transform = require_stream_transform(); + exports.PassThrough = require_stream_passthrough(); + } + } (readable, readable.exports)); + return readable.exports; +} + +var nodestream; +var blob; + +support$4.base64 = true; +support$4.array = true; +support$4.string = true; +support$4.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; +support$4.nodebuffer = typeof Buffer !== "undefined"; +// contains true if JSZip can read/generate Uint8Array, false otherwise. +support$4.uint8array = typeof Uint8Array !== "undefined"; + +if (typeof ArrayBuffer === "undefined") { + blob = support$4.blob = false; +} +else { + var buffer = new ArrayBuffer(0); + try { + blob = support$4.blob = new Blob([buffer], { + type: "application/zip" + }).size === 0; + } + catch (e) { + try { + var Builder = self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder; + var builder = new Builder(); + builder.append(buffer); + blob = support$4.blob = builder.getBlob("application/zip").size === 0; + } + catch (e) { + blob = support$4.blob = false; + } + } +} + +try { + nodestream = support$4.nodestream = !!requireReadable().Readable; +} catch(e) { + nodestream = support$4.nodestream = false; +} + +var base64$1 = {}; + +var hasRequiredBase64; + +function requireBase64 () { + if (hasRequiredBase64) return base64$1; + hasRequiredBase64 = 1; + var utils = requireUtils(); + var support = support$4; + // private property + var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + + + // public method for encoding + base64$1.encode = function(input) { + var output = []; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0, len = input.length, remainingBytes = len; + + var isArray = utils.getTypeOf(input) !== "string"; + while (i < input.length) { + remainingBytes = len - i; + + if (!isArray) { + chr1 = input.charCodeAt(i++); + chr2 = i < len ? input.charCodeAt(i++) : 0; + chr3 = i < len ? input.charCodeAt(i++) : 0; + } else { + chr1 = input[i++]; + chr2 = i < len ? input[i++] : 0; + chr3 = i < len ? input[i++] : 0; + } + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = remainingBytes > 1 ? (((chr2 & 15) << 2) | (chr3 >> 6)) : 64; + enc4 = remainingBytes > 2 ? (chr3 & 63) : 64; + + output.push(_keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4)); + + } + + return output.join(""); + }; + + // public method for decoding + base64$1.decode = function(input) { + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0, resultIndex = 0; + + var dataUrlPrefix = "data:"; + + if (input.substr(0, dataUrlPrefix.length) === dataUrlPrefix) { + // This is a common error: people give a data url + // (data:image/png;base64,iVBOR...) with a {base64: true} and + // wonders why things don't work. + // We can detect that the string input looks like a data url but we + // *can't* be sure it is one: removing everything up to the comma would + // be too dangerous. + throw new Error("Invalid base64 input, it looks like a data url."); + } + + input = input.replace(/[^A-Za-z0-9+/=]/g, ""); + + var totalLength = input.length * 3 / 4; + if(input.charAt(input.length - 1) === _keyStr.charAt(64)) { + totalLength--; + } + if(input.charAt(input.length - 2) === _keyStr.charAt(64)) { + totalLength--; + } + if (totalLength % 1 !== 0) { + // totalLength is not an integer, the length does not match a valid + // base64 content. That can happen if: + // - the input is not a base64 content + // - the input is *almost* a base64 content, with a extra chars at the + // beginning or at the end + // - the input uses a base64 variant (base64url for example) + throw new Error("Invalid base64 input, bad content length."); + } + var output; + if (support.uint8array) { + output = new Uint8Array(totalLength|0); + } else { + output = new Array(totalLength|0); + } + + while (i < input.length) { + + enc1 = _keyStr.indexOf(input.charAt(i++)); + enc2 = _keyStr.indexOf(input.charAt(i++)); + enc3 = _keyStr.indexOf(input.charAt(i++)); + enc4 = _keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output[resultIndex++] = chr1; + + if (enc3 !== 64) { + output[resultIndex++] = chr2; + } + if (enc4 !== 64) { + output[resultIndex++] = chr3; + } + + } + + return output; + }; + return base64$1; +} + +var nodejsUtils$2 = { + /** + * True if this is running in Nodejs, will be undefined in a browser. + * In a browser, browserify won't include this file and the whole module + * will be resolved an empty object. + */ + isNode : typeof Buffer !== "undefined", + /** + * Create a new nodejs Buffer from an existing content. + * @param {Object} data the data to pass to the constructor. + * @param {String} encoding the encoding to use. + * @return {Buffer} a new Buffer. + */ + newBufferFrom: function(data, encoding) { + if (Buffer.from && Buffer.from !== Uint8Array.from) { + return Buffer.from(data, encoding); + } else { + if (typeof data === "number") { + // Safeguard for old Node.js versions. On newer versions, + // Buffer.from(number) / Buffer(number, encoding) already throw. + throw new Error("The \"data\" argument must not be a number"); + } + return new Buffer(data, encoding); + } + }, + /** + * Create a new nodejs Buffer with the specified size. + * @param {Integer} size the size of the buffer. + * @return {Buffer} a new Buffer. + */ + allocBuffer: function (size) { + if (Buffer.alloc) { + return Buffer.alloc(size); + } else { + var buf = new Buffer(size); + buf.fill(0); + return buf; + } + }, + /** + * Find out if an object is a Buffer. + * @param {Object} b the object to test. + * @return {Boolean} true if the object is a Buffer, false otherwise. + */ + isBuffer : function(b){ + return Buffer.isBuffer(b); + }, + + isStream : function (obj) { + return obj && + typeof obj.on === "function" && + typeof obj.pause === "function" && + typeof obj.resume === "function"; + } +}; + +var lib$2; +var hasRequiredLib$1; + +function requireLib$1 () { + if (hasRequiredLib$1) return lib$2; + hasRequiredLib$1 = 1; + var Mutation = commonjsGlobal.MutationObserver || commonjsGlobal.WebKitMutationObserver; + + var scheduleDrain; + + if (process.browser) { + if (Mutation) { + var called = 0; + var observer = new Mutation(nextTick); + var element = commonjsGlobal.document.createTextNode(''); + observer.observe(element, { + characterData: true + }); + scheduleDrain = function () { + element.data = (called = ++called % 2); + }; + } else if (!commonjsGlobal.setImmediate && typeof commonjsGlobal.MessageChannel !== 'undefined') { + var channel = new commonjsGlobal.MessageChannel(); + channel.port1.onmessage = nextTick; + scheduleDrain = function () { + channel.port2.postMessage(0); + }; + } else if ('document' in commonjsGlobal && 'onreadystatechange' in commonjsGlobal.document.createElement('script')) { + scheduleDrain = function () { + + // Create a