postdoc 0.1.2 → 0.2.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/pdf.js +27 -0
- data/lib/postdoc.rb +3 -7
- data/node_modules/agent-base/History.md +113 -0
- data/node_modules/agent-base/README.md +145 -0
- data/node_modules/agent-base/index.js +160 -0
- data/node_modules/agent-base/package.json +35 -0
- data/node_modules/agent-base/patch-core.js +37 -0
- data/node_modules/agent-base/test/ssl-cert-snakeoil.key +15 -0
- data/node_modules/agent-base/test/ssl-cert-snakeoil.pem +12 -0
- data/node_modules/agent-base/test/test.js +673 -0
- data/node_modules/async-limiter/LICENSE +8 -0
- data/node_modules/async-limiter/coverage/coverage.json +1 -0
- data/node_modules/async-limiter/coverage/lcov-report/async-throttle/index.html +73 -0
- data/node_modules/async-limiter/coverage/lcov-report/async-throttle/index.js.html +246 -0
- data/node_modules/async-limiter/coverage/lcov-report/base.css +182 -0
- data/node_modules/async-limiter/coverage/lcov-report/index.html +73 -0
- data/node_modules/async-limiter/coverage/lcov-report/prettify.css +1 -0
- data/node_modules/async-limiter/coverage/lcov-report/prettify.js +1 -0
- data/node_modules/async-limiter/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- data/node_modules/async-limiter/coverage/lcov-report/sorter.js +156 -0
- data/node_modules/async-limiter/coverage/lcov.info +74 -0
- data/node_modules/async-limiter/index.js +67 -0
- data/node_modules/async-limiter/package.json +35 -0
- data/node_modules/async-limiter/readme.md +132 -0
- data/node_modules/balanced-match/LICENSE.md +21 -0
- data/node_modules/balanced-match/README.md +91 -0
- data/node_modules/balanced-match/index.js +59 -0
- data/node_modules/balanced-match/package.json +49 -0
- data/node_modules/brace-expansion/LICENSE +21 -0
- data/node_modules/brace-expansion/README.md +129 -0
- data/node_modules/brace-expansion/index.js +201 -0
- data/node_modules/brace-expansion/package.json +47 -0
- data/node_modules/buffer-from/index.js +69 -0
- data/node_modules/buffer-from/package.json +16 -0
- data/node_modules/buffer-from/readme.md +69 -0
- data/node_modules/buffer-from/test.js +12 -0
- data/node_modules/concat-map/LICENSE +18 -0
- data/node_modules/concat-map/README.markdown +62 -0
- data/node_modules/concat-map/example/map.js +6 -0
- data/node_modules/concat-map/index.js +13 -0
- data/node_modules/concat-map/package.json +43 -0
- data/node_modules/concat-map/test/map.js +39 -0
- data/node_modules/concat-stream/LICENSE +24 -0
- data/node_modules/concat-stream/index.js +144 -0
- data/node_modules/concat-stream/package.json +55 -0
- data/node_modules/concat-stream/readme.md +102 -0
- data/node_modules/core-util-is/LICENSE +19 -0
- data/node_modules/core-util-is/README.md +3 -0
- data/node_modules/core-util-is/float.patch +604 -0
- data/node_modules/core-util-is/lib/util.js +107 -0
- data/node_modules/core-util-is/package.json +32 -0
- data/node_modules/core-util-is/test.js +68 -0
- data/node_modules/debug/CHANGELOG.md +395 -0
- data/node_modules/debug/LICENSE +19 -0
- data/node_modules/debug/Makefile +58 -0
- data/node_modules/debug/README.md +368 -0
- data/node_modules/debug/karma.conf.js +70 -0
- data/node_modules/debug/node.js +1 -0
- data/node_modules/debug/package.json +43 -0
- data/node_modules/debug/src/browser.js +195 -0
- data/node_modules/debug/src/debug.js +225 -0
- data/node_modules/debug/src/index.js +10 -0
- data/node_modules/debug/src/node.js +186 -0
- data/node_modules/es6-promise/CHANGELOG.md +151 -0
- data/node_modules/es6-promise/LICENSE +19 -0
- data/node_modules/es6-promise/README.md +97 -0
- data/node_modules/es6-promise/auto.js +4 -0
- data/node_modules/es6-promise/dist/es6-promise.auto.js +1181 -0
- data/node_modules/es6-promise/dist/es6-promise.auto.map +1 -0
- data/node_modules/es6-promise/dist/es6-promise.auto.min.js +1 -0
- data/node_modules/es6-promise/dist/es6-promise.auto.min.map +1 -0
- data/node_modules/es6-promise/dist/es6-promise.js +1179 -0
- data/node_modules/es6-promise/dist/es6-promise.map +1 -0
- data/node_modules/es6-promise/dist/es6-promise.min.js +1 -0
- data/node_modules/es6-promise/dist/es6-promise.min.map +1 -0
- data/node_modules/es6-promise/es6-promise.d.ts +81 -0
- data/node_modules/es6-promise/lib/es6-promise/-internal.js +266 -0
- data/node_modules/es6-promise/lib/es6-promise/asap.js +119 -0
- data/node_modules/es6-promise/lib/es6-promise/enumerator.js +113 -0
- data/node_modules/es6-promise/lib/es6-promise/polyfill.js +35 -0
- data/node_modules/es6-promise/lib/es6-promise/promise/all.js +52 -0
- data/node_modules/es6-promise/lib/es6-promise/promise/race.js +84 -0
- data/node_modules/es6-promise/lib/es6-promise/promise/reject.js +46 -0
- data/node_modules/es6-promise/lib/es6-promise/promise/resolve.js +48 -0
- data/node_modules/es6-promise/lib/es6-promise/promise.js +427 -0
- data/node_modules/es6-promise/lib/es6-promise/then.js +32 -0
- data/node_modules/es6-promise/lib/es6-promise/utils.js +21 -0
- data/node_modules/es6-promise/lib/es6-promise.auto.js +3 -0
- data/node_modules/es6-promise/lib/es6-promise.js +7 -0
- data/node_modules/es6-promise/package.json +75 -0
- data/node_modules/es6-promisify/README.md +89 -0
- data/node_modules/es6-promisify/dist/promise.js +73 -0
- data/node_modules/es6-promisify/dist/promisify.js +85 -0
- data/node_modules/es6-promisify/package.json +41 -0
- data/node_modules/extract-zip/CONTRIBUTING.md +1 -0
- data/node_modules/extract-zip/LICENSE +23 -0
- data/node_modules/extract-zip/cli.js +20 -0
- data/node_modules/extract-zip/index.js +205 -0
- data/node_modules/extract-zip/node_modules/debug/CHANGELOG.md +362 -0
- data/node_modules/extract-zip/node_modules/debug/LICENSE +19 -0
- data/node_modules/extract-zip/node_modules/debug/Makefile +50 -0
- data/node_modules/extract-zip/node_modules/debug/README.md +312 -0
- data/node_modules/extract-zip/node_modules/debug/component.json +19 -0
- data/node_modules/extract-zip/node_modules/debug/karma.conf.js +70 -0
- data/node_modules/extract-zip/node_modules/debug/node.js +1 -0
- data/node_modules/extract-zip/node_modules/debug/package.json +49 -0
- data/node_modules/extract-zip/node_modules/debug/src/browser.js +185 -0
- data/node_modules/extract-zip/node_modules/debug/src/debug.js +202 -0
- data/node_modules/extract-zip/node_modules/debug/src/index.js +10 -0
- data/node_modules/extract-zip/node_modules/debug/src/inspector-log.js +15 -0
- data/node_modules/extract-zip/node_modules/debug/src/node.js +248 -0
- data/node_modules/extract-zip/package.json +35 -0
- data/node_modules/extract-zip/readme.md +49 -0
- data/node_modules/fd-slicer/CHANGELOG.md +49 -0
- data/node_modules/fd-slicer/LICENSE +21 -0
- data/node_modules/fd-slicer/README.md +189 -0
- data/node_modules/fd-slicer/index.js +277 -0
- data/node_modules/fd-slicer/package.json +36 -0
- data/node_modules/fd-slicer/test/test.js +350 -0
- data/node_modules/fs.realpath/LICENSE +43 -0
- data/node_modules/fs.realpath/README.md +33 -0
- data/node_modules/fs.realpath/index.js +66 -0
- data/node_modules/fs.realpath/old.js +303 -0
- data/node_modules/fs.realpath/package.json +26 -0
- data/node_modules/glob/LICENSE +15 -0
- data/node_modules/glob/README.md +368 -0
- data/node_modules/glob/changelog.md +67 -0
- data/node_modules/glob/common.js +240 -0
- data/node_modules/glob/glob.js +790 -0
- data/node_modules/glob/package.json +43 -0
- data/node_modules/glob/sync.js +486 -0
- data/node_modules/https-proxy-agent/History.md +124 -0
- data/node_modules/https-proxy-agent/README.md +137 -0
- data/node_modules/https-proxy-agent/index.js +229 -0
- data/node_modules/https-proxy-agent/package.json +35 -0
- data/node_modules/https-proxy-agent/test/ssl-cert-snakeoil.key +15 -0
- data/node_modules/https-proxy-agent/test/ssl-cert-snakeoil.pem +12 -0
- data/node_modules/https-proxy-agent/test/test.js +342 -0
- data/node_modules/inflight/LICENSE +15 -0
- data/node_modules/inflight/README.md +37 -0
- data/node_modules/inflight/inflight.js +54 -0
- data/node_modules/inflight/package.json +29 -0
- data/node_modules/inherits/LICENSE +16 -0
- data/node_modules/inherits/README.md +42 -0
- data/node_modules/inherits/inherits.js +7 -0
- data/node_modules/inherits/inherits_browser.js +23 -0
- data/node_modules/inherits/package.json +29 -0
- data/node_modules/isarray/Makefile +6 -0
- data/node_modules/isarray/README.md +60 -0
- data/node_modules/isarray/component.json +19 -0
- data/node_modules/isarray/index.js +5 -0
- data/node_modules/isarray/package.json +45 -0
- data/node_modules/isarray/test.js +20 -0
- data/node_modules/mime/CHANGELOG.md +225 -0
- data/node_modules/mime/CONTRIBUTING.md +5 -0
- data/node_modules/mime/LICENSE +21 -0
- data/node_modules/mime/Mime.js +89 -0
- data/node_modules/mime/README.md +188 -0
- data/node_modules/mime/cli.js +10 -0
- data/node_modules/mime/index.js +4 -0
- data/node_modules/mime/lite.js +4 -0
- data/node_modules/mime/package.json +43 -0
- data/node_modules/mime/src/README_js.md +179 -0
- data/node_modules/mime/src/build.js +71 -0
- data/node_modules/mime/src/test.js +257 -0
- data/node_modules/mime/types/other.json +1 -0
- data/node_modules/mime/types/standard.json +1 -0
- data/node_modules/minimatch/LICENSE +15 -0
- data/node_modules/minimatch/README.md +209 -0
- data/node_modules/minimatch/minimatch.js +923 -0
- data/node_modules/minimatch/package.json +30 -0
- data/node_modules/minimist/LICENSE +18 -0
- data/node_modules/minimist/example/parse.js +2 -0
- data/node_modules/minimist/index.js +187 -0
- data/node_modules/minimist/package.json +40 -0
- data/node_modules/minimist/readme.markdown +73 -0
- data/node_modules/minimist/test/dash.js +24 -0
- data/node_modules/minimist/test/default_bool.js +20 -0
- data/node_modules/minimist/test/dotted.js +16 -0
- data/node_modules/minimist/test/long.js +31 -0
- data/node_modules/minimist/test/parse.js +318 -0
- data/node_modules/minimist/test/parse_modified.js +9 -0
- data/node_modules/minimist/test/short.js +67 -0
- data/node_modules/minimist/test/whitespace.js +8 -0
- data/node_modules/mkdirp/LICENSE +21 -0
- data/node_modules/mkdirp/bin/cmd.js +33 -0
- data/node_modules/mkdirp/bin/usage.txt +12 -0
- data/node_modules/mkdirp/examples/pow.js +6 -0
- data/node_modules/mkdirp/index.js +98 -0
- data/node_modules/mkdirp/package.json +27 -0
- data/node_modules/mkdirp/readme.markdown +100 -0
- data/node_modules/mkdirp/test/chmod.js +41 -0
- data/node_modules/mkdirp/test/clobber.js +38 -0
- data/node_modules/mkdirp/test/mkdirp.js +28 -0
- data/node_modules/mkdirp/test/opts_fs.js +29 -0
- data/node_modules/mkdirp/test/opts_fs_sync.js +27 -0
- data/node_modules/mkdirp/test/perm.js +32 -0
- data/node_modules/mkdirp/test/perm_sync.js +36 -0
- data/node_modules/mkdirp/test/race.js +37 -0
- data/node_modules/mkdirp/test/rel.js +32 -0
- data/node_modules/mkdirp/test/return.js +25 -0
- data/node_modules/mkdirp/test/return_sync.js +24 -0
- data/node_modules/mkdirp/test/root.js +19 -0
- data/node_modules/mkdirp/test/sync.js +32 -0
- data/node_modules/mkdirp/test/umask.js +28 -0
- data/node_modules/mkdirp/test/umask_sync.js +32 -0
- data/node_modules/ms/index.js +152 -0
- data/node_modules/ms/license.md +21 -0
- data/node_modules/ms/package.json +37 -0
- data/node_modules/ms/readme.md +51 -0
- data/node_modules/once/LICENSE +15 -0
- data/node_modules/once/README.md +79 -0
- data/node_modules/once/once.js +42 -0
- data/node_modules/once/package.json +33 -0
- data/node_modules/path-is-absolute/index.js +20 -0
- data/node_modules/path-is-absolute/license +21 -0
- data/node_modules/path-is-absolute/package.json +43 -0
- data/node_modules/path-is-absolute/readme.md +59 -0
- data/node_modules/pend/LICENSE +23 -0
- data/node_modules/pend/README.md +41 -0
- data/node_modules/pend/index.js +55 -0
- data/node_modules/pend/package.json +18 -0
- data/node_modules/pend/test.js +137 -0
- data/node_modules/process-nextick-args/index.js +44 -0
- data/node_modules/process-nextick-args/license.md +19 -0
- data/node_modules/process-nextick-args/package.json +25 -0
- data/node_modules/process-nextick-args/readme.md +18 -0
- data/node_modules/progress/CHANGELOG.md +115 -0
- data/node_modules/progress/LICENSE +22 -0
- data/node_modules/progress/Makefile +8 -0
- data/node_modules/progress/README.md +146 -0
- data/node_modules/progress/index.js +1 -0
- data/node_modules/progress/lib/node-progress.js +231 -0
- data/node_modules/progress/package.json +25 -0
- data/node_modules/proxy-from-env/README.md +131 -0
- data/node_modules/proxy-from-env/index.js +103 -0
- data/node_modules/proxy-from-env/package.json +35 -0
- data/node_modules/proxy-from-env/test.js +393 -0
- data/node_modules/puppeteer/CONTRIBUTING.md +206 -0
- data/node_modules/puppeteer/DeviceDescriptors.js +704 -0
- data/node_modules/puppeteer/LICENSE +202 -0
- data/node_modules/puppeteer/README.md +306 -0
- data/node_modules/puppeteer/index.js +28 -0
- data/node_modules/puppeteer/install.js +122 -0
- data/node_modules/puppeteer/lib/Browser.js +186 -0
- data/node_modules/puppeteer/lib/BrowserFetcher.js +279 -0
- data/node_modules/puppeteer/lib/Connection.js +246 -0
- data/node_modules/puppeteer/lib/Coverage.js +301 -0
- data/node_modules/puppeteer/lib/Dialog.js +84 -0
- data/node_modules/puppeteer/lib/ElementHandle.js +328 -0
- data/node_modules/puppeteer/lib/EmulationManager.js +89 -0
- data/node_modules/puppeteer/lib/ExecutionContext.js +232 -0
- data/node_modules/puppeteer/lib/FrameManager.js +997 -0
- data/node_modules/puppeteer/lib/Input.js +309 -0
- data/node_modules/puppeteer/lib/Launcher.js +310 -0
- data/node_modules/puppeteer/lib/Multimap.js +95 -0
- data/node_modules/puppeteer/lib/NavigatorWatcher.js +137 -0
- data/node_modules/puppeteer/lib/NetworkManager.js +796 -0
- data/node_modules/puppeteer/lib/Page.js +1098 -0
- data/node_modules/puppeteer/lib/Pipe.js +69 -0
- data/node_modules/puppeteer/lib/Puppeteer.js +60 -0
- data/node_modules/puppeteer/lib/Target.js +88 -0
- data/node_modules/puppeteer/lib/TaskQueue.js +17 -0
- data/node_modules/puppeteer/lib/Tracing.js +99 -0
- data/node_modules/puppeteer/lib/USKeyboardLayout.js +281 -0
- data/node_modules/puppeteer/lib/helper.js +248 -0
- data/node_modules/puppeteer/node6/lib/Browser.js +394 -0
- data/node_modules/puppeteer/node6/lib/BrowserFetcher.js +357 -0
- data/node_modules/puppeteer/node6/lib/Connection.js +350 -0
- data/node_modules/puppeteer/node6/lib/Coverage.js +561 -0
- data/node_modules/puppeteer/node6/lib/Dialog.js +136 -0
- data/node_modules/puppeteer/node6/lib/ElementHandle.js +796 -0
- data/node_modules/puppeteer/node6/lib/EmulationManager.js +115 -0
- data/node_modules/puppeteer/node6/lib/ExecutionContext.js +414 -0
- data/node_modules/puppeteer/node6/lib/FrameManager.js +1621 -0
- data/node_modules/puppeteer/node6/lib/Input.js +569 -0
- data/node_modules/puppeteer/node6/lib/Launcher.js +362 -0
- data/node_modules/puppeteer/node6/lib/Multimap.js +95 -0
- data/node_modules/puppeteer/node6/lib/NavigatorWatcher.js +163 -0
- data/node_modules/puppeteer/node6/lib/NetworkManager.js +1108 -0
- data/node_modules/puppeteer/node6/lib/Page.js +2242 -0
- data/node_modules/puppeteer/node6/lib/Pipe.js +69 -0
- data/node_modules/puppeteer/node6/lib/Puppeteer.js +60 -0
- data/node_modules/puppeteer/node6/lib/Target.js +114 -0
- data/node_modules/puppeteer/node6/lib/TaskQueue.js +17 -0
- data/node_modules/puppeteer/node6/lib/Tracing.js +177 -0
- data/node_modules/puppeteer/node6/lib/USKeyboardLayout.js +281 -0
- data/node_modules/puppeteer/node6/lib/helper.js +274 -0
- data/node_modules/puppeteer/package.json +61 -0
- data/node_modules/readable-stream/CONTRIBUTING.md +38 -0
- data/node_modules/readable-stream/GOVERNANCE.md +136 -0
- data/node_modules/readable-stream/LICENSE +47 -0
- data/node_modules/readable-stream/README.md +58 -0
- data/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +60 -0
- data/node_modules/readable-stream/duplex-browser.js +1 -0
- data/node_modules/readable-stream/duplex.js +1 -0
- data/node_modules/readable-stream/lib/_stream_duplex.js +131 -0
- data/node_modules/readable-stream/lib/_stream_passthrough.js +47 -0
- data/node_modules/readable-stream/lib/_stream_readable.js +1019 -0
- data/node_modules/readable-stream/lib/_stream_transform.js +214 -0
- data/node_modules/readable-stream/lib/_stream_writable.js +687 -0
- data/node_modules/readable-stream/lib/internal/streams/BufferList.js +79 -0
- data/node_modules/readable-stream/lib/internal/streams/destroy.js +74 -0
- data/node_modules/readable-stream/lib/internal/streams/stream-browser.js +1 -0
- data/node_modules/readable-stream/lib/internal/streams/stream.js +1 -0
- data/node_modules/readable-stream/package.json +52 -0
- data/node_modules/readable-stream/passthrough.js +1 -0
- data/node_modules/readable-stream/readable-browser.js +7 -0
- data/node_modules/readable-stream/readable.js +19 -0
- data/node_modules/readable-stream/transform.js +1 -0
- data/node_modules/readable-stream/writable-browser.js +1 -0
- data/node_modules/readable-stream/writable.js +8 -0
- data/node_modules/rimraf/LICENSE +15 -0
- data/node_modules/rimraf/README.md +101 -0
- data/node_modules/rimraf/bin.js +50 -0
- data/node_modules/rimraf/package.json +26 -0
- data/node_modules/rimraf/rimraf.js +364 -0
- data/node_modules/safe-buffer/LICENSE +21 -0
- data/node_modules/safe-buffer/README.md +584 -0
- data/node_modules/safe-buffer/index.d.ts +187 -0
- data/node_modules/safe-buffer/index.js +62 -0
- data/node_modules/safe-buffer/package.json +37 -0
- data/node_modules/string_decoder/LICENSE +48 -0
- data/node_modules/string_decoder/README.md +47 -0
- data/node_modules/string_decoder/lib/string_decoder.js +296 -0
- data/node_modules/string_decoder/package.json +31 -0
- data/node_modules/typedarray/LICENSE +35 -0
- data/node_modules/typedarray/example/tarray.js +4 -0
- data/node_modules/typedarray/index.js +630 -0
- data/node_modules/typedarray/package.json +55 -0
- data/node_modules/typedarray/readme.markdown +61 -0
- data/node_modules/typedarray/test/server/undef_globals.js +19 -0
- data/node_modules/typedarray/test/tarray.js +10 -0
- data/node_modules/ultron/LICENSE +22 -0
- data/node_modules/ultron/README.md +113 -0
- data/node_modules/ultron/index.js +136 -0
- data/node_modules/ultron/package.json +41 -0
- data/node_modules/util-deprecate/History.md +16 -0
- data/node_modules/util-deprecate/LICENSE +24 -0
- data/node_modules/util-deprecate/README.md +53 -0
- data/node_modules/util-deprecate/browser.js +67 -0
- data/node_modules/util-deprecate/node.js +6 -0
- data/node_modules/util-deprecate/package.json +27 -0
- data/node_modules/wrappy/LICENSE +15 -0
- data/node_modules/wrappy/README.md +36 -0
- data/node_modules/wrappy/package.json +29 -0
- data/node_modules/wrappy/wrappy.js +33 -0
- data/node_modules/ws/LICENSE +21 -0
- data/node_modules/ws/README.md +341 -0
- data/node_modules/ws/index.js +15 -0
- data/node_modules/ws/lib/BufferUtil.js +71 -0
- data/node_modules/ws/lib/Constants.js +10 -0
- data/node_modules/ws/lib/ErrorCodes.js +28 -0
- data/node_modules/ws/lib/EventTarget.js +151 -0
- data/node_modules/ws/lib/Extensions.js +203 -0
- data/node_modules/ws/lib/PerMessageDeflate.js +507 -0
- data/node_modules/ws/lib/Receiver.js +553 -0
- data/node_modules/ws/lib/Sender.js +412 -0
- data/node_modules/ws/lib/Validation.js +17 -0
- data/node_modules/ws/lib/WebSocket.js +717 -0
- data/node_modules/ws/lib/WebSocketServer.js +326 -0
- data/node_modules/ws/package.json +46 -0
- data/node_modules/yauzl/LICENSE +21 -0
- data/node_modules/yauzl/README.md +467 -0
- data/node_modules/yauzl/index.js +626 -0
- data/node_modules/yauzl/package.json +36 -0
- data/package.json +5 -0
- data/yarn.lock +240 -0
- metadata +372 -7
- data/app/assets/stylesheets/default.css +0 -4
- data/lib/postdoc/postdoc_view_helper.rb +0 -22
@@ -0,0 +1,467 @@
|
|
1
|
+
# yauzl
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/thejoshwolfe/yauzl.svg?branch=master)](https://travis-ci.org/thejoshwolfe/yauzl)
|
4
|
+
[![Coverage Status](https://img.shields.io/coveralls/thejoshwolfe/yauzl.svg)](https://coveralls.io/r/thejoshwolfe/yauzl)
|
5
|
+
|
6
|
+
yet another unzip library for node. For zipping, see
|
7
|
+
[yazl](https://github.com/thejoshwolfe/yazl).
|
8
|
+
|
9
|
+
Design principles:
|
10
|
+
|
11
|
+
* Follow the spec.
|
12
|
+
Don't scan for local file headers.
|
13
|
+
Read the central directory for file metadata.
|
14
|
+
(see [No Streaming Unzip API](#no-streaming-unzip-api)).
|
15
|
+
* Don't block the JavaScript thread.
|
16
|
+
Use and provide async APIs.
|
17
|
+
* Keep memory usage under control.
|
18
|
+
Don't attempt to buffer entire files in RAM at once.
|
19
|
+
* Never crash (if used properly).
|
20
|
+
Don't let malformed zip files bring down client applications who are trying to catch errors.
|
21
|
+
* Catch unsafe filenames entries.
|
22
|
+
A zip file entry throws an error if its file name starts with `"/"` or `/[A-Za-z]:\//`
|
23
|
+
or if it contains `".."` path segments or `"\\"` (per the spec).
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
```js
|
28
|
+
var yauzl = require("yauzl");
|
29
|
+
var fs = require("fs");
|
30
|
+
var path = require("path");
|
31
|
+
var mkdirp = require("mkdirp"); // or similar
|
32
|
+
|
33
|
+
yauzl.open("path/to/file.zip", {lazyEntries: true}, function(err, zipfile) {
|
34
|
+
if (err) throw err;
|
35
|
+
zipfile.readEntry();
|
36
|
+
zipfile.on("entry", function(entry) {
|
37
|
+
if (/\/$/.test(entry.fileName)) {
|
38
|
+
// directory file names end with '/'
|
39
|
+
mkdirp(entry.fileName, function(err) {
|
40
|
+
if (err) throw err;
|
41
|
+
zipfile.readEntry();
|
42
|
+
});
|
43
|
+
} else {
|
44
|
+
// file entry
|
45
|
+
zipfile.openReadStream(entry, function(err, readStream) {
|
46
|
+
if (err) throw err;
|
47
|
+
// ensure parent directory exists
|
48
|
+
mkdirp(path.dirname(entry.fileName), function(err) {
|
49
|
+
if (err) throw err;
|
50
|
+
readStream.pipe(fs.createWriteStream(entry.fileName));
|
51
|
+
readStream.on("end", function() {
|
52
|
+
zipfile.readEntry();
|
53
|
+
});
|
54
|
+
});
|
55
|
+
});
|
56
|
+
}
|
57
|
+
});
|
58
|
+
});
|
59
|
+
```
|
60
|
+
|
61
|
+
## API
|
62
|
+
|
63
|
+
The default for every optional `callback` parameter is:
|
64
|
+
|
65
|
+
```js
|
66
|
+
function defaultCallback(err) {
|
67
|
+
if (err) throw err;
|
68
|
+
}
|
69
|
+
```
|
70
|
+
|
71
|
+
### open(path, [options], [callback])
|
72
|
+
|
73
|
+
Calls `fs.open(path, "r")` and gives the `fd`, `options`, and `callback` to `fromFd()` below.
|
74
|
+
|
75
|
+
`options` may be omitted or `null`. The defaults are `{autoClose: true, lazyEntries: false}`.
|
76
|
+
|
77
|
+
`autoClose` is effectively equivalent to:
|
78
|
+
|
79
|
+
```js
|
80
|
+
zipfile.once("end", function() {
|
81
|
+
zipfile.close();
|
82
|
+
});
|
83
|
+
```
|
84
|
+
|
85
|
+
`lazyEntries` indicates that entries should be read only when `readEntry()` is called.
|
86
|
+
If `lazyEntries` is `false`, `entry` events will be emitted as fast as possible to allow `pipe()`ing
|
87
|
+
file data from all entries in parallel.
|
88
|
+
This is not recommended, as it can lead to out of control memory usage for zip files with many entries.
|
89
|
+
See [issue #22](https://github.com/thejoshwolfe/yauzl/issues/22).
|
90
|
+
If `lazyEntries` is `true`, an `entry` or `end` event will be emitted in response to each call to `readEntry()`.
|
91
|
+
This allows processing of one entry at a time, and will keep memory usage under control for zip files with many entries.
|
92
|
+
|
93
|
+
### fromFd(fd, [options], [callback])
|
94
|
+
|
95
|
+
Reads from the fd, which is presumed to be an open .zip file.
|
96
|
+
Note that random access is required by the zip file specification,
|
97
|
+
so the fd cannot be an open socket or any other fd that does not support random access.
|
98
|
+
|
99
|
+
The `callback` is given the arguments `(err, zipfile)`.
|
100
|
+
An `err` is provided if the End of Central Directory Record Signature cannot be found in the file,
|
101
|
+
which indicates that the fd is not a zip file.
|
102
|
+
`zipfile` is an instance of `ZipFile`.
|
103
|
+
|
104
|
+
`options` may be omitted or `null`. The defaults are `{autoClose: false, lazyEntries: false}`.
|
105
|
+
See `open()` for the meaning of the options.
|
106
|
+
|
107
|
+
### fromBuffer(buffer, [options], [callback])
|
108
|
+
|
109
|
+
Like `fromFd()`, but reads from a RAM buffer instead of an open file.
|
110
|
+
`buffer` is a `Buffer`.
|
111
|
+
`callback` is effectively passed directly to `fromFd()`.
|
112
|
+
|
113
|
+
If a `ZipFile` is acquired from this method,
|
114
|
+
it will never emit the `close` event,
|
115
|
+
and calling `close()` is not necessary.
|
116
|
+
|
117
|
+
`options` may be omitted or `null`. The defaults are `{lazyEntries: false}`.
|
118
|
+
See `open()` for the meaning of the options.
|
119
|
+
The `autoClose` option is ignored for this method.
|
120
|
+
|
121
|
+
### fromRandomAccessReader(reader, totalSize, [options], [callback])
|
122
|
+
|
123
|
+
This method of creating a zip file allows clients to implement their own back-end file system.
|
124
|
+
For example, a client might translate read calls into network requests.
|
125
|
+
|
126
|
+
The `reader` parameter must be of a type that is a subclass of
|
127
|
+
[RandomAccessReader](#class-randomaccessreader) that implements the required methods.
|
128
|
+
The `totalSize` is a Number and indicates the total file size of the zip file.
|
129
|
+
|
130
|
+
`options` may be omitted or `null`. The defaults are `{autoClose: true, lazyEntries: false}`.
|
131
|
+
See `open()` for the meaning of the options.
|
132
|
+
|
133
|
+
### dosDateTimeToDate(date, time)
|
134
|
+
|
135
|
+
Converts MS-DOS `date` and `time` data into a JavaScript `Date` object.
|
136
|
+
Each parameter is a `Number` treated as an unsigned 16-bit integer.
|
137
|
+
Note that this format does not support timezones,
|
138
|
+
so the returned object will use the local timezone.
|
139
|
+
|
140
|
+
### Class: ZipFile
|
141
|
+
|
142
|
+
The constructor for the class is not part of the public API.
|
143
|
+
Use `open()`, `fromFd()`, `fromBuffer()`, or `fromRandomAccessReader()` instead.
|
144
|
+
|
145
|
+
#### Event: "entry"
|
146
|
+
|
147
|
+
Callback gets `(entry)`, which is an `Entry`.
|
148
|
+
See `open()` and `readEntry()` for when this event is emitted.
|
149
|
+
|
150
|
+
#### Event: "end"
|
151
|
+
|
152
|
+
Emitted after the last `entry` event has been emitted.
|
153
|
+
See `open()` and `readEntry()` for more info on when this event is emitted.
|
154
|
+
|
155
|
+
#### Event: "close"
|
156
|
+
|
157
|
+
Emitted after the fd is actually closed.
|
158
|
+
This is after calling `close()` (or after the `end` event when `autoClose` is `true`),
|
159
|
+
and after all stream pipelines created from `openReadStream()` have finished reading data from the fd.
|
160
|
+
|
161
|
+
If this `ZipFile` was acquired from `fromRandomAccessReader()`,
|
162
|
+
the "fd" in the previous paragraph refers to the `RandomAccessReader` implemented by the client.
|
163
|
+
|
164
|
+
If this `ZipFile` was acquired from `fromBuffer()`, this event is never emitted.
|
165
|
+
|
166
|
+
#### Event: "error"
|
167
|
+
|
168
|
+
Emitted in the case of errors with reading the zip file.
|
169
|
+
(Note that other errors can be emitted from the streams created from `openReadStream()` as well.)
|
170
|
+
After this event has been emitted, no further `entry`, `end`, or `error` events will be emitted,
|
171
|
+
but the `close` event may still be emitted.
|
172
|
+
|
173
|
+
#### readEntry()
|
174
|
+
|
175
|
+
Causes this `ZipFile` to emit an `entry` or `end` event (or an `error` event).
|
176
|
+
This method must only be called when this `ZipFile` was created with the `lazyEntries` option set to `true` (see `open()`).
|
177
|
+
When this `ZipFile` was created with the `lazyEntries` option set to `true`,
|
178
|
+
`entry` and `end` events are only ever emitted in response to this method call.
|
179
|
+
|
180
|
+
The event that is emitted in response to this method will not be emitted until after this method has returned,
|
181
|
+
so it is safe to call this method before attaching event listeners.
|
182
|
+
|
183
|
+
After calling this method, calling this method again before the response event has been emitted will cause undefined behavior.
|
184
|
+
Calling this method after the `end` event has been emitted will cause undefined behavior.
|
185
|
+
Calling this method after calling `close()` will cause undefined behavior.
|
186
|
+
|
187
|
+
#### openReadStream(entry, callback)
|
188
|
+
|
189
|
+
`entry` must be an `Entry` object from this `ZipFile`.
|
190
|
+
`callback` gets `(err, readStream)`, where `readStream` is a `Readable Stream`.
|
191
|
+
If the entry is compressed (with a supported compression method),
|
192
|
+
the read stream provides the decompressed data.
|
193
|
+
If this zipfile is already closed (see `close()`), the `callback` will receive an `err`.
|
194
|
+
|
195
|
+
It's possible for the `readStream` it to emit errors for several reasons.
|
196
|
+
For example, if zlib cannot decompress the data, the zlib error will be emitted from the `readStream`.
|
197
|
+
Two more error cases are if the decompressed data has too many or too few actual bytes
|
198
|
+
compared to the reported byte count from the entry's `uncompressedSize` field.
|
199
|
+
yauzl notices this false information and emits an error from the `readStream`
|
200
|
+
after some number of bytes have already been piped through the stream.
|
201
|
+
|
202
|
+
Because of this check, clients can always trust the `uncompressedSize` field in `Entry` objects.
|
203
|
+
Guarding against [zip bomb](http://en.wikipedia.org/wiki/Zip_bomb) attacks can be accomplished by
|
204
|
+
doing some heuristic checks on the size metadata and then watching out for the above errors.
|
205
|
+
Such heuristics are outside the scope of this library,
|
206
|
+
but enforcing the `uncompressedSize` is implemented here as a security feature.
|
207
|
+
|
208
|
+
It is possible to destroy the `readStream` before it has piped all of its data.
|
209
|
+
To do this, call `readStream.destroy()`.
|
210
|
+
You must `unpipe()` the `readStream` from any destination before calling `readStream.destroy()`.
|
211
|
+
If this zipfile was created using `fromRandomAccessReader()`, the `RandomAccessReader` implementation
|
212
|
+
must provide readable streams that implement a `.destroy()` method (see `randomAccessReader._readStreamForRange()`)
|
213
|
+
in order for calls to `readStream.destroy()` to work in this context.
|
214
|
+
|
215
|
+
#### close()
|
216
|
+
|
217
|
+
Causes all future calls to `openReadStream()` to fail,
|
218
|
+
and closes the fd after all streams created by `openReadStream()` have emitted their `end` events.
|
219
|
+
|
220
|
+
If the `autoClose` option is set to `true` (see `open()`),
|
221
|
+
this function will be called automatically effectively in response to this object's `end` event.
|
222
|
+
|
223
|
+
If the `lazyEntries` option is set to `false` (see `open()`) and this object's `end` event has not been emitted yet,
|
224
|
+
this function causes undefined behavior.
|
225
|
+
If the `lazyEntries` option is set to `true`,
|
226
|
+
you can call this function instead of calling `readEntry()` to abort reading the entries of a zipfile.
|
227
|
+
|
228
|
+
It is safe to call this function multiple times; after the first call, successive calls have no effect.
|
229
|
+
This includes situations where the `autoClose` option effectively calls this function for you.
|
230
|
+
|
231
|
+
#### isOpen
|
232
|
+
|
233
|
+
`Boolean`. `true` until `close()` is called; then it's `false`.
|
234
|
+
|
235
|
+
#### entryCount
|
236
|
+
|
237
|
+
`Number`. Total number of central directory records.
|
238
|
+
|
239
|
+
#### comment
|
240
|
+
|
241
|
+
`String`. Always decoded with `CP437` per the spec.
|
242
|
+
|
243
|
+
### Class: Entry
|
244
|
+
|
245
|
+
Objects of this class represent Central Directory Records.
|
246
|
+
Refer to the zipfile specification for more details about these fields.
|
247
|
+
|
248
|
+
These fields are of type `Number`:
|
249
|
+
|
250
|
+
* `versionMadeBy`
|
251
|
+
* `versionNeededToExtract`
|
252
|
+
* `generalPurposeBitFlag`
|
253
|
+
* `compressionMethod`
|
254
|
+
* `lastModFileTime` (MS-DOS format, see `getLastModDateTime`)
|
255
|
+
* `lastModFileDate` (MS-DOS format, see `getLastModDateTime`)
|
256
|
+
* `crc32`
|
257
|
+
* `compressedSize`
|
258
|
+
* `uncompressedSize`
|
259
|
+
* `fileNameLength` (bytes)
|
260
|
+
* `extraFieldLength` (bytes)
|
261
|
+
* `fileCommentLength` (bytes)
|
262
|
+
* `internalFileAttributes`
|
263
|
+
* `externalFileAttributes`
|
264
|
+
* `relativeOffsetOfLocalHeader`
|
265
|
+
|
266
|
+
#### fileName
|
267
|
+
|
268
|
+
`String`.
|
269
|
+
Following the spec, the bytes for the file name are decoded with
|
270
|
+
`UTF-8` if `generalPurposeBitFlag & 0x800`, otherwise with `CP437`.
|
271
|
+
|
272
|
+
If `fileName` would contain unsafe characters, such as an absolute path or
|
273
|
+
a relative directory, yauzl emits an error instead of an entry.
|
274
|
+
|
275
|
+
#### extraFields
|
276
|
+
|
277
|
+
`Array` with each entry in the form `{id: id, data: data}`,
|
278
|
+
where `id` is a `Number` and `data` is a `Buffer`.
|
279
|
+
This library looks for and reads the ZIP64 Extended Information Extra Field (0x0001)
|
280
|
+
in order to support ZIP64 format zip files.
|
281
|
+
None of the other fields are considered significant by this library.
|
282
|
+
|
283
|
+
#### comment
|
284
|
+
|
285
|
+
`String` decoded with the same charset as used for `fileName`.
|
286
|
+
|
287
|
+
#### getLastModDate()
|
288
|
+
|
289
|
+
Effectively implemented as:
|
290
|
+
|
291
|
+
```js
|
292
|
+
return dosDateTimeToDate(this.lastModFileDate, this.lastModFileTime);
|
293
|
+
```
|
294
|
+
|
295
|
+
### Class: RandomAccessReader
|
296
|
+
|
297
|
+
This class is meant to be subclassed by clients and instantiated for the `fromRandomAccessReader()` function.
|
298
|
+
|
299
|
+
An example implementation can be found in `test/test.js`.
|
300
|
+
|
301
|
+
#### randomAccessReader._readStreamForRange(start, end)
|
302
|
+
|
303
|
+
Subclasses *must* implement this method.
|
304
|
+
|
305
|
+
`start` and `end` are Numbers and indicate byte offsets from the start of the file.
|
306
|
+
`end` is exclusive, so `_readStreamForRange(0x1000, 0x2000)` would indicate to read `0x1000` bytes.
|
307
|
+
`end - start` will always be at least `1`.
|
308
|
+
|
309
|
+
This method should return a readable stream which will be `pipe()`ed into another stream.
|
310
|
+
It is expected that the readable stream will provide data in several chunks if necessary.
|
311
|
+
If the readable stream provides too many or too few bytes, an error will be emitted.
|
312
|
+
Any errors emitted on the readable stream will be handled and re-emitted on the client-visible stream
|
313
|
+
(returned from `zipfile.openReadStream()`) or provided as the `err` argument to the appropriate callback
|
314
|
+
(for example, for `fromRandomAccessReader()`).
|
315
|
+
|
316
|
+
The returned stream *must* implement a method `.destroy()`
|
317
|
+
if you call `readStream.destroy()` on streams you get from `openReadStream()`.
|
318
|
+
If you never call `readStream.destroy()`, then streams returned from this method do not need to implement a method `.destroy()`.
|
319
|
+
`.destroy()` should abort any streaming that is in progress and clean up any associated resources.
|
320
|
+
`.destroy()` will only be called after the stream has been `unpipe()`d from its destination.
|
321
|
+
|
322
|
+
Note that the stream returned from this method might not be the same object that is provided by `openReadStream()`.
|
323
|
+
The stream returned from this method might be `pipe()`d through one or more filter streams (for example, a zlib inflate stream).
|
324
|
+
|
325
|
+
#### randomAccessReader.read(buffer, offset, length, position, callback)
|
326
|
+
|
327
|
+
Subclasses may implement this method.
|
328
|
+
The default implementation uses `createReadStream()` to fill the `buffer`.
|
329
|
+
|
330
|
+
This method should behave like `fs.read()`.
|
331
|
+
|
332
|
+
#### randomAccessReader.close(callback)
|
333
|
+
|
334
|
+
Subclasses may implement this method.
|
335
|
+
The default implementation is effectively `setImmediate(callback);`.
|
336
|
+
|
337
|
+
`callback` takes parameters `(err)`.
|
338
|
+
|
339
|
+
This method is called once the all streams returned from `_readStreamForRange()` have ended,
|
340
|
+
and no more `_readStreamForRange()` or `read()` requests will be issued to this object.
|
341
|
+
|
342
|
+
## How to Avoid Crashing
|
343
|
+
|
344
|
+
When a malformed zipfile is encountered, the default behavior is to crash (throw an exception).
|
345
|
+
If you want to handle errors more gracefully than this,
|
346
|
+
be sure to do the following:
|
347
|
+
|
348
|
+
* Provide `callback` parameters where they are allowed, and check the `err` parameter.
|
349
|
+
* Attach a listener for the `error` event on any `ZipFile` object you get from `open()`, `fromFd()`, `fromBuffer()`, or `fromRandomAccessReader()`.
|
350
|
+
* Attach a listener for the `error` event on any stream you get from `openReadStream()`.
|
351
|
+
|
352
|
+
## Limitations
|
353
|
+
|
354
|
+
### No Streaming Unzip API
|
355
|
+
|
356
|
+
Due to the design of the .zip file format, it's impossible to interpret a .zip file from start to finish
|
357
|
+
(such as from a readable stream) without sacrificing correctness.
|
358
|
+
The Central Directory, which is the authority on the contents of the .zip file, is at the end of a .zip file, not the beginning.
|
359
|
+
A streaming API would need to either buffer the entire .zip file to get to the Central Directory before interpreting anything
|
360
|
+
(defeating the purpose of a streaming interface), or rely on the Local File Headers which are interspersed through the .zip file.
|
361
|
+
However, the Local File Headers are explicitly denounced in the spec as being unreliable copies of the Central Directory,
|
362
|
+
so trusting them would be a violation of the spec.
|
363
|
+
|
364
|
+
Any library that offers a streaming unzip API must make one of the above two compromises,
|
365
|
+
which makes the library either dishonest or nonconformant (usually the latter).
|
366
|
+
This library insists on correctness and adherence to the spec, and so does not offer a streaming API.
|
367
|
+
|
368
|
+
### Limitted ZIP64 Support
|
369
|
+
|
370
|
+
For ZIP64, only zip files smaller than `8PiB` are supported,
|
371
|
+
not the full `16EiB` range that a 64-bit integer should be able to index.
|
372
|
+
This is due to the JavaScript Number type being an IEEE 754 double precision float.
|
373
|
+
|
374
|
+
The Node.js `fs` module probably has this same limitation.
|
375
|
+
|
376
|
+
### ZIP64 Extensible Data Sector Is Ignored
|
377
|
+
|
378
|
+
The spec does not allow zip file creators to put arbitrary data here,
|
379
|
+
but rather reserves its use for PKWARE and mentions something about Z390.
|
380
|
+
This doesn't seem useful to expose in this library, so it is ignored.
|
381
|
+
|
382
|
+
### No Multi-Disk Archive Support
|
383
|
+
|
384
|
+
This library does not support multi-disk zip files.
|
385
|
+
The multi-disk fields in the zipfile spec were intended for a zip file to span multiple floppy disks,
|
386
|
+
which probably never happens now.
|
387
|
+
If the "number of this disk" field in the End of Central Directory Record is not `0`,
|
388
|
+
the `open()`, `fromFd()`, `fromBuffer()`, or `fromRandomAccessReader()` `callback` will receive an `err`.
|
389
|
+
By extension the following zip file fields are ignored by this library and not provided to clients:
|
390
|
+
|
391
|
+
* Disk where central directory starts
|
392
|
+
* Number of central directory records on this disk
|
393
|
+
* Disk number where file starts
|
394
|
+
|
395
|
+
### No Encryption Support
|
396
|
+
|
397
|
+
Currently, the presence of encryption is not even checked,
|
398
|
+
and encrypted zip files will cause undefined behavior.
|
399
|
+
|
400
|
+
### Local File Headers Are Ignored
|
401
|
+
|
402
|
+
Many unzip libraries mistakenly read the Local File Header data in zip files.
|
403
|
+
This data is officially defined to be redundant with the Central Directory information,
|
404
|
+
and is not to be trusted.
|
405
|
+
Aside from checking the signature, yauzl ignores the content of the Local File Header.
|
406
|
+
|
407
|
+
### No CRC-32 Checking
|
408
|
+
|
409
|
+
This library provides the `crc32` field of `Entry` objects read from the Central Directory.
|
410
|
+
However, this field is not used for anything in this library.
|
411
|
+
|
412
|
+
### versionNeededToExtract Is Ignored
|
413
|
+
|
414
|
+
The field `versionNeededToExtract` is ignored,
|
415
|
+
because this library doesn't support the complete zip file spec at any version,
|
416
|
+
|
417
|
+
### No Support For Obscure Compression Methods
|
418
|
+
|
419
|
+
Regarding the `compressionMethod` field of `Entry` objects,
|
420
|
+
only method `0` (stored with no compression)
|
421
|
+
and method `8` (deflated) are supported.
|
422
|
+
Any of the other 15 official methods will cause the `openReadStream()` `callback` to receive an `err`.
|
423
|
+
|
424
|
+
### Data Descriptors Are Ignored
|
425
|
+
|
426
|
+
There may or may not be Data Descriptor sections in a zip file.
|
427
|
+
This library provides no support for finding or interpreting them.
|
428
|
+
|
429
|
+
### Archive Extra Data Record Is Ignored
|
430
|
+
|
431
|
+
There may or may not be an Archive Extra Data Record section in a zip file.
|
432
|
+
This library provides no support for finding or interpreting it.
|
433
|
+
|
434
|
+
### No Language Encoding Flag Support
|
435
|
+
|
436
|
+
Zip files officially support charset encodings other than CP437 and UTF-8,
|
437
|
+
but the zip file spec does not specify how it works.
|
438
|
+
This library makes no attempt to interpret the Language Encoding Flag.
|
439
|
+
|
440
|
+
## Change History
|
441
|
+
|
442
|
+
* 2.4.1
|
443
|
+
* Fix error handling.
|
444
|
+
* 2.4.0
|
445
|
+
* Add ZIP64 support. [issue #6](https://github.com/thejoshwolfe/yazl/issues/6)
|
446
|
+
* Add `lazyEntries` option. [issue #22](https://github.com/thejoshwolfe/yazl/issues/22)
|
447
|
+
* Add `readStream.destroy()` method. [issue #26](https://github.com/thejoshwolfe/yazl/issues/26)
|
448
|
+
* Add `fromRandomAccessReader()`. [issue #14](https://github.com/thejoshwolfe/yazl/issues/14)
|
449
|
+
* Add `examples/unzip.js`.
|
450
|
+
* 2.3.1
|
451
|
+
* Documentation updates.
|
452
|
+
* 2.3.0
|
453
|
+
* Check that `uncompressedSize` is correct, or else emit an error. [issue #13](https://github.com/thejoshwolfe/yazl/issues/13)
|
454
|
+
* 2.2.1
|
455
|
+
* Update dependencies.
|
456
|
+
* 2.2.0
|
457
|
+
* Update dependencies.
|
458
|
+
* 2.1.0
|
459
|
+
* Remove dependency on `iconv`.
|
460
|
+
* 2.0.3
|
461
|
+
* Fix crash when trying to read a 0-byte file.
|
462
|
+
* 2.0.2
|
463
|
+
* Fix event behavior after errors.
|
464
|
+
* 2.0.1
|
465
|
+
* Fix bug with using `iconv`.
|
466
|
+
* 2.0.0
|
467
|
+
* Initial release.
|