postdoc 0.2.0.beta4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/postdoc/postdoc_view_helper.rb +15 -0
- data/lib/postdoc.rb +34 -14
- metadata +20 -373
- data/lib/pdf.js +0 -27
- data/node_modules/agent-base/History.md +0 -113
- data/node_modules/agent-base/README.md +0 -145
- data/node_modules/agent-base/index.js +0 -160
- data/node_modules/agent-base/package.json +0 -35
- data/node_modules/agent-base/patch-core.js +0 -37
- data/node_modules/agent-base/test/ssl-cert-snakeoil.key +0 -15
- data/node_modules/agent-base/test/ssl-cert-snakeoil.pem +0 -12
- data/node_modules/agent-base/test/test.js +0 -673
- data/node_modules/async-limiter/LICENSE +0 -8
- data/node_modules/async-limiter/coverage/coverage.json +0 -1
- data/node_modules/async-limiter/coverage/lcov-report/async-throttle/index.html +0 -73
- data/node_modules/async-limiter/coverage/lcov-report/async-throttle/index.js.html +0 -246
- data/node_modules/async-limiter/coverage/lcov-report/base.css +0 -182
- data/node_modules/async-limiter/coverage/lcov-report/index.html +0 -73
- data/node_modules/async-limiter/coverage/lcov-report/prettify.css +0 -1
- data/node_modules/async-limiter/coverage/lcov-report/prettify.js +0 -1
- data/node_modules/async-limiter/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- data/node_modules/async-limiter/coverage/lcov-report/sorter.js +0 -156
- data/node_modules/async-limiter/coverage/lcov.info +0 -74
- data/node_modules/async-limiter/index.js +0 -67
- data/node_modules/async-limiter/package.json +0 -35
- data/node_modules/async-limiter/readme.md +0 -132
- data/node_modules/balanced-match/LICENSE.md +0 -21
- data/node_modules/balanced-match/README.md +0 -91
- data/node_modules/balanced-match/index.js +0 -59
- data/node_modules/balanced-match/package.json +0 -49
- data/node_modules/brace-expansion/LICENSE +0 -21
- data/node_modules/brace-expansion/README.md +0 -129
- data/node_modules/brace-expansion/index.js +0 -201
- data/node_modules/brace-expansion/package.json +0 -47
- data/node_modules/buffer-from/index.js +0 -69
- data/node_modules/buffer-from/package.json +0 -16
- data/node_modules/buffer-from/readme.md +0 -69
- data/node_modules/buffer-from/test.js +0 -12
- data/node_modules/concat-map/LICENSE +0 -18
- data/node_modules/concat-map/README.markdown +0 -62
- data/node_modules/concat-map/example/map.js +0 -6
- data/node_modules/concat-map/index.js +0 -13
- data/node_modules/concat-map/package.json +0 -43
- data/node_modules/concat-map/test/map.js +0 -39
- data/node_modules/concat-stream/LICENSE +0 -24
- data/node_modules/concat-stream/index.js +0 -144
- data/node_modules/concat-stream/package.json +0 -55
- data/node_modules/concat-stream/readme.md +0 -102
- data/node_modules/core-util-is/LICENSE +0 -19
- data/node_modules/core-util-is/README.md +0 -3
- data/node_modules/core-util-is/float.patch +0 -604
- data/node_modules/core-util-is/lib/util.js +0 -107
- data/node_modules/core-util-is/package.json +0 -32
- data/node_modules/core-util-is/test.js +0 -68
- data/node_modules/debug/CHANGELOG.md +0 -395
- data/node_modules/debug/LICENSE +0 -19
- data/node_modules/debug/Makefile +0 -58
- data/node_modules/debug/README.md +0 -368
- data/node_modules/debug/karma.conf.js +0 -70
- data/node_modules/debug/node.js +0 -1
- data/node_modules/debug/package.json +0 -43
- data/node_modules/debug/src/browser.js +0 -195
- data/node_modules/debug/src/debug.js +0 -225
- data/node_modules/debug/src/index.js +0 -10
- data/node_modules/debug/src/node.js +0 -186
- data/node_modules/es6-promise/CHANGELOG.md +0 -151
- data/node_modules/es6-promise/LICENSE +0 -19
- data/node_modules/es6-promise/README.md +0 -97
- data/node_modules/es6-promise/auto.js +0 -4
- data/node_modules/es6-promise/dist/es6-promise.auto.js +0 -1181
- data/node_modules/es6-promise/dist/es6-promise.auto.map +0 -1
- data/node_modules/es6-promise/dist/es6-promise.auto.min.js +0 -1
- data/node_modules/es6-promise/dist/es6-promise.auto.min.map +0 -1
- data/node_modules/es6-promise/dist/es6-promise.js +0 -1179
- data/node_modules/es6-promise/dist/es6-promise.map +0 -1
- data/node_modules/es6-promise/dist/es6-promise.min.js +0 -1
- data/node_modules/es6-promise/dist/es6-promise.min.map +0 -1
- data/node_modules/es6-promise/es6-promise.d.ts +0 -81
- data/node_modules/es6-promise/lib/es6-promise/-internal.js +0 -266
- data/node_modules/es6-promise/lib/es6-promise/asap.js +0 -119
- data/node_modules/es6-promise/lib/es6-promise/enumerator.js +0 -113
- data/node_modules/es6-promise/lib/es6-promise/polyfill.js +0 -35
- data/node_modules/es6-promise/lib/es6-promise/promise/all.js +0 -52
- data/node_modules/es6-promise/lib/es6-promise/promise/race.js +0 -84
- data/node_modules/es6-promise/lib/es6-promise/promise/reject.js +0 -46
- data/node_modules/es6-promise/lib/es6-promise/promise/resolve.js +0 -48
- data/node_modules/es6-promise/lib/es6-promise/promise.js +0 -427
- data/node_modules/es6-promise/lib/es6-promise/then.js +0 -32
- data/node_modules/es6-promise/lib/es6-promise/utils.js +0 -21
- data/node_modules/es6-promise/lib/es6-promise.auto.js +0 -3
- data/node_modules/es6-promise/lib/es6-promise.js +0 -7
- data/node_modules/es6-promise/package.json +0 -75
- data/node_modules/es6-promisify/README.md +0 -89
- data/node_modules/es6-promisify/dist/promise.js +0 -73
- data/node_modules/es6-promisify/dist/promisify.js +0 -85
- data/node_modules/es6-promisify/package.json +0 -41
- data/node_modules/extract-zip/CONTRIBUTING.md +0 -1
- data/node_modules/extract-zip/LICENSE +0 -23
- data/node_modules/extract-zip/cli.js +0 -20
- data/node_modules/extract-zip/index.js +0 -205
- data/node_modules/extract-zip/node_modules/debug/CHANGELOG.md +0 -362
- data/node_modules/extract-zip/node_modules/debug/LICENSE +0 -19
- data/node_modules/extract-zip/node_modules/debug/Makefile +0 -50
- data/node_modules/extract-zip/node_modules/debug/README.md +0 -312
- data/node_modules/extract-zip/node_modules/debug/component.json +0 -19
- data/node_modules/extract-zip/node_modules/debug/karma.conf.js +0 -70
- data/node_modules/extract-zip/node_modules/debug/node.js +0 -1
- data/node_modules/extract-zip/node_modules/debug/package.json +0 -49
- data/node_modules/extract-zip/node_modules/debug/src/browser.js +0 -185
- data/node_modules/extract-zip/node_modules/debug/src/debug.js +0 -202
- data/node_modules/extract-zip/node_modules/debug/src/index.js +0 -10
- data/node_modules/extract-zip/node_modules/debug/src/inspector-log.js +0 -15
- data/node_modules/extract-zip/node_modules/debug/src/node.js +0 -248
- data/node_modules/extract-zip/package.json +0 -35
- data/node_modules/extract-zip/readme.md +0 -49
- data/node_modules/fd-slicer/CHANGELOG.md +0 -49
- data/node_modules/fd-slicer/LICENSE +0 -21
- data/node_modules/fd-slicer/README.md +0 -189
- data/node_modules/fd-slicer/index.js +0 -277
- data/node_modules/fd-slicer/package.json +0 -36
- data/node_modules/fd-slicer/test/test.js +0 -350
- data/node_modules/fs.realpath/LICENSE +0 -43
- data/node_modules/fs.realpath/README.md +0 -33
- data/node_modules/fs.realpath/index.js +0 -66
- data/node_modules/fs.realpath/old.js +0 -303
- data/node_modules/fs.realpath/package.json +0 -26
- data/node_modules/glob/LICENSE +0 -15
- data/node_modules/glob/README.md +0 -368
- data/node_modules/glob/changelog.md +0 -67
- data/node_modules/glob/common.js +0 -240
- data/node_modules/glob/glob.js +0 -790
- data/node_modules/glob/package.json +0 -43
- data/node_modules/glob/sync.js +0 -486
- data/node_modules/https-proxy-agent/History.md +0 -124
- data/node_modules/https-proxy-agent/README.md +0 -137
- data/node_modules/https-proxy-agent/index.js +0 -229
- data/node_modules/https-proxy-agent/package.json +0 -35
- data/node_modules/https-proxy-agent/test/ssl-cert-snakeoil.key +0 -15
- data/node_modules/https-proxy-agent/test/ssl-cert-snakeoil.pem +0 -12
- data/node_modules/https-proxy-agent/test/test.js +0 -342
- data/node_modules/inflight/LICENSE +0 -15
- data/node_modules/inflight/README.md +0 -37
- data/node_modules/inflight/inflight.js +0 -54
- data/node_modules/inflight/package.json +0 -29
- data/node_modules/inherits/LICENSE +0 -16
- data/node_modules/inherits/README.md +0 -42
- data/node_modules/inherits/inherits.js +0 -7
- data/node_modules/inherits/inherits_browser.js +0 -23
- data/node_modules/inherits/package.json +0 -29
- data/node_modules/isarray/Makefile +0 -6
- data/node_modules/isarray/README.md +0 -60
- data/node_modules/isarray/component.json +0 -19
- data/node_modules/isarray/index.js +0 -5
- data/node_modules/isarray/package.json +0 -45
- data/node_modules/isarray/test.js +0 -20
- data/node_modules/mime/CHANGELOG.md +0 -225
- data/node_modules/mime/CONTRIBUTING.md +0 -5
- data/node_modules/mime/LICENSE +0 -21
- data/node_modules/mime/Mime.js +0 -89
- data/node_modules/mime/README.md +0 -188
- data/node_modules/mime/cli.js +0 -10
- data/node_modules/mime/index.js +0 -4
- data/node_modules/mime/lite.js +0 -4
- data/node_modules/mime/package.json +0 -43
- data/node_modules/mime/src/README_js.md +0 -179
- data/node_modules/mime/src/build.js +0 -71
- data/node_modules/mime/src/test.js +0 -257
- data/node_modules/mime/types/other.json +0 -1
- data/node_modules/mime/types/standard.json +0 -1
- data/node_modules/minimatch/LICENSE +0 -15
- data/node_modules/minimatch/README.md +0 -209
- data/node_modules/minimatch/minimatch.js +0 -923
- data/node_modules/minimatch/package.json +0 -30
- data/node_modules/minimist/LICENSE +0 -18
- data/node_modules/minimist/example/parse.js +0 -2
- data/node_modules/minimist/index.js +0 -187
- data/node_modules/minimist/package.json +0 -40
- data/node_modules/minimist/readme.markdown +0 -73
- data/node_modules/minimist/test/dash.js +0 -24
- data/node_modules/minimist/test/default_bool.js +0 -20
- data/node_modules/minimist/test/dotted.js +0 -16
- data/node_modules/minimist/test/long.js +0 -31
- data/node_modules/minimist/test/parse.js +0 -318
- data/node_modules/minimist/test/parse_modified.js +0 -9
- data/node_modules/minimist/test/short.js +0 -67
- data/node_modules/minimist/test/whitespace.js +0 -8
- data/node_modules/mkdirp/LICENSE +0 -21
- data/node_modules/mkdirp/bin/cmd.js +0 -33
- data/node_modules/mkdirp/bin/usage.txt +0 -12
- data/node_modules/mkdirp/examples/pow.js +0 -6
- data/node_modules/mkdirp/index.js +0 -98
- data/node_modules/mkdirp/package.json +0 -27
- data/node_modules/mkdirp/readme.markdown +0 -100
- data/node_modules/mkdirp/test/chmod.js +0 -41
- data/node_modules/mkdirp/test/clobber.js +0 -38
- data/node_modules/mkdirp/test/mkdirp.js +0 -28
- data/node_modules/mkdirp/test/opts_fs.js +0 -29
- data/node_modules/mkdirp/test/opts_fs_sync.js +0 -27
- data/node_modules/mkdirp/test/perm.js +0 -32
- data/node_modules/mkdirp/test/perm_sync.js +0 -36
- data/node_modules/mkdirp/test/race.js +0 -37
- data/node_modules/mkdirp/test/rel.js +0 -32
- data/node_modules/mkdirp/test/return.js +0 -25
- data/node_modules/mkdirp/test/return_sync.js +0 -24
- data/node_modules/mkdirp/test/root.js +0 -19
- data/node_modules/mkdirp/test/sync.js +0 -32
- data/node_modules/mkdirp/test/umask.js +0 -28
- data/node_modules/mkdirp/test/umask_sync.js +0 -32
- data/node_modules/ms/index.js +0 -152
- data/node_modules/ms/license.md +0 -21
- data/node_modules/ms/package.json +0 -37
- data/node_modules/ms/readme.md +0 -51
- data/node_modules/once/LICENSE +0 -15
- data/node_modules/once/README.md +0 -79
- data/node_modules/once/once.js +0 -42
- data/node_modules/once/package.json +0 -33
- data/node_modules/path-is-absolute/index.js +0 -20
- data/node_modules/path-is-absolute/license +0 -21
- data/node_modules/path-is-absolute/package.json +0 -43
- data/node_modules/path-is-absolute/readme.md +0 -59
- data/node_modules/pend/LICENSE +0 -23
- data/node_modules/pend/README.md +0 -41
- data/node_modules/pend/index.js +0 -55
- data/node_modules/pend/package.json +0 -18
- data/node_modules/pend/test.js +0 -137
- data/node_modules/process-nextick-args/index.js +0 -44
- data/node_modules/process-nextick-args/license.md +0 -19
- data/node_modules/process-nextick-args/package.json +0 -25
- data/node_modules/process-nextick-args/readme.md +0 -18
- data/node_modules/progress/CHANGELOG.md +0 -115
- data/node_modules/progress/LICENSE +0 -22
- data/node_modules/progress/Makefile +0 -8
- data/node_modules/progress/README.md +0 -146
- data/node_modules/progress/index.js +0 -1
- data/node_modules/progress/lib/node-progress.js +0 -231
- data/node_modules/progress/package.json +0 -25
- data/node_modules/proxy-from-env/README.md +0 -131
- data/node_modules/proxy-from-env/index.js +0 -103
- data/node_modules/proxy-from-env/package.json +0 -35
- data/node_modules/proxy-from-env/test.js +0 -393
- data/node_modules/puppeteer/CONTRIBUTING.md +0 -206
- data/node_modules/puppeteer/DeviceDescriptors.js +0 -704
- data/node_modules/puppeteer/LICENSE +0 -202
- data/node_modules/puppeteer/README.md +0 -306
- data/node_modules/puppeteer/index.js +0 -28
- data/node_modules/puppeteer/install.js +0 -122
- data/node_modules/puppeteer/lib/Browser.js +0 -186
- data/node_modules/puppeteer/lib/BrowserFetcher.js +0 -279
- data/node_modules/puppeteer/lib/Connection.js +0 -246
- data/node_modules/puppeteer/lib/Coverage.js +0 -301
- data/node_modules/puppeteer/lib/Dialog.js +0 -84
- data/node_modules/puppeteer/lib/ElementHandle.js +0 -328
- data/node_modules/puppeteer/lib/EmulationManager.js +0 -89
- data/node_modules/puppeteer/lib/ExecutionContext.js +0 -232
- data/node_modules/puppeteer/lib/FrameManager.js +0 -997
- data/node_modules/puppeteer/lib/Input.js +0 -309
- data/node_modules/puppeteer/lib/Launcher.js +0 -310
- data/node_modules/puppeteer/lib/Multimap.js +0 -95
- data/node_modules/puppeteer/lib/NavigatorWatcher.js +0 -137
- data/node_modules/puppeteer/lib/NetworkManager.js +0 -796
- data/node_modules/puppeteer/lib/Page.js +0 -1098
- data/node_modules/puppeteer/lib/Pipe.js +0 -69
- data/node_modules/puppeteer/lib/Puppeteer.js +0 -60
- data/node_modules/puppeteer/lib/Target.js +0 -88
- data/node_modules/puppeteer/lib/TaskQueue.js +0 -17
- data/node_modules/puppeteer/lib/Tracing.js +0 -99
- data/node_modules/puppeteer/lib/USKeyboardLayout.js +0 -281
- data/node_modules/puppeteer/lib/helper.js +0 -248
- data/node_modules/puppeteer/node6/lib/Browser.js +0 -394
- data/node_modules/puppeteer/node6/lib/BrowserFetcher.js +0 -357
- data/node_modules/puppeteer/node6/lib/Connection.js +0 -350
- data/node_modules/puppeteer/node6/lib/Coverage.js +0 -561
- data/node_modules/puppeteer/node6/lib/Dialog.js +0 -136
- data/node_modules/puppeteer/node6/lib/ElementHandle.js +0 -796
- data/node_modules/puppeteer/node6/lib/EmulationManager.js +0 -115
- data/node_modules/puppeteer/node6/lib/ExecutionContext.js +0 -414
- data/node_modules/puppeteer/node6/lib/FrameManager.js +0 -1621
- data/node_modules/puppeteer/node6/lib/Input.js +0 -569
- data/node_modules/puppeteer/node6/lib/Launcher.js +0 -362
- data/node_modules/puppeteer/node6/lib/Multimap.js +0 -95
- data/node_modules/puppeteer/node6/lib/NavigatorWatcher.js +0 -163
- data/node_modules/puppeteer/node6/lib/NetworkManager.js +0 -1108
- data/node_modules/puppeteer/node6/lib/Page.js +0 -2242
- data/node_modules/puppeteer/node6/lib/Pipe.js +0 -69
- data/node_modules/puppeteer/node6/lib/Puppeteer.js +0 -60
- data/node_modules/puppeteer/node6/lib/Target.js +0 -114
- data/node_modules/puppeteer/node6/lib/TaskQueue.js +0 -17
- data/node_modules/puppeteer/node6/lib/Tracing.js +0 -177
- data/node_modules/puppeteer/node6/lib/USKeyboardLayout.js +0 -281
- data/node_modules/puppeteer/node6/lib/helper.js +0 -274
- data/node_modules/puppeteer/package.json +0 -61
- data/node_modules/readable-stream/CONTRIBUTING.md +0 -38
- data/node_modules/readable-stream/GOVERNANCE.md +0 -136
- data/node_modules/readable-stream/LICENSE +0 -47
- data/node_modules/readable-stream/README.md +0 -58
- data/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +0 -60
- data/node_modules/readable-stream/duplex-browser.js +0 -1
- data/node_modules/readable-stream/duplex.js +0 -1
- data/node_modules/readable-stream/lib/_stream_duplex.js +0 -131
- data/node_modules/readable-stream/lib/_stream_passthrough.js +0 -47
- data/node_modules/readable-stream/lib/_stream_readable.js +0 -1019
- data/node_modules/readable-stream/lib/_stream_transform.js +0 -214
- data/node_modules/readable-stream/lib/_stream_writable.js +0 -687
- data/node_modules/readable-stream/lib/internal/streams/BufferList.js +0 -79
- data/node_modules/readable-stream/lib/internal/streams/destroy.js +0 -74
- data/node_modules/readable-stream/lib/internal/streams/stream-browser.js +0 -1
- data/node_modules/readable-stream/lib/internal/streams/stream.js +0 -1
- data/node_modules/readable-stream/package.json +0 -52
- data/node_modules/readable-stream/passthrough.js +0 -1
- data/node_modules/readable-stream/readable-browser.js +0 -7
- data/node_modules/readable-stream/readable.js +0 -19
- data/node_modules/readable-stream/transform.js +0 -1
- data/node_modules/readable-stream/writable-browser.js +0 -1
- data/node_modules/readable-stream/writable.js +0 -8
- data/node_modules/rimraf/LICENSE +0 -15
- data/node_modules/rimraf/README.md +0 -101
- data/node_modules/rimraf/bin.js +0 -50
- data/node_modules/rimraf/package.json +0 -26
- data/node_modules/rimraf/rimraf.js +0 -364
- data/node_modules/safe-buffer/LICENSE +0 -21
- data/node_modules/safe-buffer/README.md +0 -584
- data/node_modules/safe-buffer/index.d.ts +0 -187
- data/node_modules/safe-buffer/index.js +0 -62
- data/node_modules/safe-buffer/package.json +0 -37
- data/node_modules/string_decoder/LICENSE +0 -48
- data/node_modules/string_decoder/README.md +0 -47
- data/node_modules/string_decoder/lib/string_decoder.js +0 -296
- data/node_modules/string_decoder/package.json +0 -31
- data/node_modules/typedarray/LICENSE +0 -35
- data/node_modules/typedarray/example/tarray.js +0 -4
- data/node_modules/typedarray/index.js +0 -630
- data/node_modules/typedarray/package.json +0 -55
- data/node_modules/typedarray/readme.markdown +0 -61
- data/node_modules/typedarray/test/server/undef_globals.js +0 -19
- data/node_modules/typedarray/test/tarray.js +0 -10
- data/node_modules/ultron/LICENSE +0 -22
- data/node_modules/ultron/README.md +0 -113
- data/node_modules/ultron/index.js +0 -136
- data/node_modules/ultron/package.json +0 -41
- data/node_modules/util-deprecate/History.md +0 -16
- data/node_modules/util-deprecate/LICENSE +0 -24
- data/node_modules/util-deprecate/README.md +0 -53
- data/node_modules/util-deprecate/browser.js +0 -67
- data/node_modules/util-deprecate/node.js +0 -6
- data/node_modules/util-deprecate/package.json +0 -27
- data/node_modules/wrappy/LICENSE +0 -15
- data/node_modules/wrappy/README.md +0 -36
- data/node_modules/wrappy/package.json +0 -29
- data/node_modules/wrappy/wrappy.js +0 -33
- data/node_modules/ws/LICENSE +0 -21
- data/node_modules/ws/README.md +0 -341
- data/node_modules/ws/index.js +0 -15
- data/node_modules/ws/lib/BufferUtil.js +0 -71
- data/node_modules/ws/lib/Constants.js +0 -10
- data/node_modules/ws/lib/ErrorCodes.js +0 -28
- data/node_modules/ws/lib/EventTarget.js +0 -151
- data/node_modules/ws/lib/Extensions.js +0 -203
- data/node_modules/ws/lib/PerMessageDeflate.js +0 -507
- data/node_modules/ws/lib/Receiver.js +0 -553
- data/node_modules/ws/lib/Sender.js +0 -412
- data/node_modules/ws/lib/Validation.js +0 -17
- data/node_modules/ws/lib/WebSocket.js +0 -717
- data/node_modules/ws/lib/WebSocketServer.js +0 -326
- data/node_modules/ws/package.json +0 -46
- data/node_modules/yauzl/LICENSE +0 -21
- data/node_modules/yauzl/README.md +0 -467
- data/node_modules/yauzl/index.js +0 -626
- data/node_modules/yauzl/package.json +0 -36
- data/package.json +0 -5
- data/yarn.lock +0 -240
@@ -1,467 +0,0 @@
|
|
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.
|