npm: Upgrade to 1.2.24
authorisaacs <i@izs.me>
Thu, 30 May 2013 17:19:45 +0000 (10:19 -0700)
committerisaacs <i@izs.me>
Thu, 30 May 2013 17:19:45 +0000 (10:19 -0700)
280 files changed:
deps/npm/doc/cli/config.md
deps/npm/doc/cli/developers.md
deps/npm/doc/cli/shrinkwrap.md
deps/npm/html/api/bin.html
deps/npm/html/api/bugs.html
deps/npm/html/api/commands.html
deps/npm/html/api/config.html
deps/npm/html/api/deprecate.html
deps/npm/html/api/docs.html
deps/npm/html/api/edit.html
deps/npm/html/api/explore.html
deps/npm/html/api/help-search.html
deps/npm/html/api/init.html
deps/npm/html/api/install.html
deps/npm/html/api/link.html
deps/npm/html/api/load.html
deps/npm/html/api/ls.html
deps/npm/html/api/npm.html
deps/npm/html/api/outdated.html
deps/npm/html/api/owner.html
deps/npm/html/api/pack.html
deps/npm/html/api/prefix.html
deps/npm/html/api/prune.html
deps/npm/html/api/publish.html
deps/npm/html/api/rebuild.html
deps/npm/html/api/restart.html
deps/npm/html/api/root.html
deps/npm/html/api/run-script.html
deps/npm/html/api/search.html
deps/npm/html/api/shrinkwrap.html
deps/npm/html/api/start.html
deps/npm/html/api/stop.html
deps/npm/html/api/submodule.html
deps/npm/html/api/tag.html
deps/npm/html/api/test.html
deps/npm/html/api/uninstall.html
deps/npm/html/api/unpublish.html
deps/npm/html/api/update.html
deps/npm/html/api/version.html
deps/npm/html/api/view.html
deps/npm/html/api/whoami.html
deps/npm/html/doc/README.html
deps/npm/html/doc/adduser.html
deps/npm/html/doc/bin.html
deps/npm/html/doc/bugs.html
deps/npm/html/doc/build.html
deps/npm/html/doc/bundle.html
deps/npm/html/doc/cache.html
deps/npm/html/doc/changelog.html
deps/npm/html/doc/coding-style.html
deps/npm/html/doc/completion.html
deps/npm/html/doc/config.html
deps/npm/html/doc/dedupe.html
deps/npm/html/doc/deprecate.html
deps/npm/html/doc/developers.html
deps/npm/html/doc/disputes.html
deps/npm/html/doc/docs.html
deps/npm/html/doc/edit.html
deps/npm/html/doc/explore.html
deps/npm/html/doc/faq.html
deps/npm/html/doc/folders.html
deps/npm/html/doc/global.html
deps/npm/html/doc/help-search.html
deps/npm/html/doc/help.html
deps/npm/html/doc/index.html
deps/npm/html/doc/init.html
deps/npm/html/doc/install.html
deps/npm/html/doc/json.html
deps/npm/html/doc/link.html
deps/npm/html/doc/ls.html
deps/npm/html/doc/npm.html
deps/npm/html/doc/outdated.html
deps/npm/html/doc/owner.html
deps/npm/html/doc/pack.html
deps/npm/html/doc/prefix.html
deps/npm/html/doc/prune.html
deps/npm/html/doc/publish.html
deps/npm/html/doc/rebuild.html
deps/npm/html/doc/registry.html
deps/npm/html/doc/removing-npm.html
deps/npm/html/doc/restart.html
deps/npm/html/doc/rm.html
deps/npm/html/doc/root.html
deps/npm/html/doc/run-script.html
deps/npm/html/doc/scripts.html
deps/npm/html/doc/search.html
deps/npm/html/doc/semver.html
deps/npm/html/doc/shrinkwrap.html
deps/npm/html/doc/star.html
deps/npm/html/doc/stars.html
deps/npm/html/doc/start.html
deps/npm/html/doc/stop.html
deps/npm/html/doc/submodule.html
deps/npm/html/doc/tag.html
deps/npm/html/doc/test.html
deps/npm/html/doc/uninstall.html
deps/npm/html/doc/unpublish.html
deps/npm/html/doc/update.html
deps/npm/html/doc/version.html
deps/npm/html/doc/view.html
deps/npm/html/doc/whoami.html
deps/npm/lib/install.js
deps/npm/lib/shrinkwrap.js
deps/npm/man/man1/config.1
deps/npm/man/man1/developers.1
deps/npm/man/man1/ls.1
deps/npm/man/man1/npm.1
deps/npm/man/man1/shrinkwrap.1
deps/npm/man/man3/npm.3
deps/npm/node_modules/node-gyp/README.md
deps/npm/node_modules/node-gyp/node_modules/request/LICENSE [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/README.md [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/aws.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/forever.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/main.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/.npmignore [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/Makefile [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/Readme.md [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/lib/form_data.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node-form-data.sublime-project [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node-form-data.sublime-workspace [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/.gitmodules [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/LICENSE [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/Makefile [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/README.md [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/async.min.js.gzip [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.css [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/dist/async.min.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/index.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/lib/async.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/nodelint.cfg [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/package.json [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/test/test-async.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/test/test.html [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/.npmignore [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/License [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/Makefile [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/common.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-http-upload.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-auto-pause.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-pause.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-handle-source-errors.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-max-data-size.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-pipe-resumes.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-proxy-readable.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/run.js [new file with mode: 0755]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/common.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file1.txt [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file2.txt [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-callback-streams.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-data-size.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams-and-buffers-and-strings.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-max-data-size.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-unpaused-streams.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/run.js [new file with mode: 0755]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/package.json [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/common.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/fixture/bacon.txt [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-http-response.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-pipe.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-submit.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/run.js [new file with mode: 0755]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/LICENSE [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/README.md [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/mime.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/package.json [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/test.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/types/mime.types [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/types/node.types [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/oauth.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/package.json [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/googledoodle.png [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/run.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/server.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/squid.conf [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.cnf [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.crl [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.crt [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.csr [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.key [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.srl [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.cnf [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.crt [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.csr [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.key [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/npm-ca.crt [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/test.crt [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/test.key [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-body.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-cookie.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-cookiejar.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-defaults.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-errors.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-follow-all-303.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-follow-all.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-form.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-headers.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-httpModule.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-https-strict.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-https.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-oauth.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-params.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-piped-redirect.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-pipes.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-pool.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-protocol-changing-redirect.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-proxy.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-qs.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-redirect.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-s3.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-timeout.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-toJSON.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/test-tunnel.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tests/unicycle.jpg [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/tunnel.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/uuid.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/vendor/cookie/index.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/node_modules/request/vendor/cookie/jar.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/package.json
deps/npm/node_modules/npmconf/config-defs.js
deps/npm/node_modules/npmconf/package.json
deps/npm/node_modules/request/node_modules/form-data/node_modules/async/README.md
deps/npm/node_modules/request/node_modules/form-data/node_modules/async/component.json [new file with mode: 0644]
deps/npm/node_modules/request/node_modules/form-data/node_modules/async/lib/async.js
deps/npm/node_modules/request/node_modules/form-data/node_modules/async/package.json
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/Makefile
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/.npmignore [new file with mode: 0644]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/.travis.yml [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/LICENSE [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/Makefile [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/README.md [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/images/hoek.png [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/index.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/lib/escape.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/lib/index.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/package.json [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/escaper.js [new file with mode: 0644]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/index.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test1.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test2.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test3.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/package.json
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/README.md
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/lib/index.js
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/.npmignore [new file with mode: 0644]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/.travis.yml [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/LICENSE [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/Makefile [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/README.md [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/images/hoek.png [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/index.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/lib/escape.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/lib/index.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/package.json [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/escaper.js [new file with mode: 0644]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/index.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test1.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test2.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test3.js [new file with mode: 0755]
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/package.json
deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/test/index.js
deps/npm/node_modules/request/node_modules/qs/index.js
deps/npm/node_modules/request/node_modules/qs/package.json
deps/npm/package.json

index fa3e7bc..54133be 100644 (file)
@@ -721,6 +721,14 @@ character to indicate reverse sort.
 
 The shell to run for the `npm explore` command.
 
+### shrinkwrap
+
+* Default: true
+* Type: Boolean
+
+If set to false, then ignore `npm-shrinkwrap.json` files when
+installing.
+
 ### sign-git-tag
 
 * Default: false
index 7ab905b..d1ffd5a 100644 (file)
@@ -97,10 +97,34 @@ more info.
 ## Keeping files *out* of your package
 
 Use a `.npmignore` file to keep stuff out of your package.  If there's
-no .npmignore file, but there *is* a .gitignore file, then npm will
-ignore the stuff matched by the .gitignore file.  If you *want* to
-include something that is excluded by your .gitignore file, you can
-create an empty .npmignore file to override it.
+no `.npmignore` file, but there *is* a `.gitignore` file, then npm will
+ignore the stuff matched by the `.gitignore` file.  If you *want* to
+include something that is excluded by your `.gitignore` file, you can
+create an empty `.npmignore` file to override it.
+
+By default, the following paths and files are ignored, so there's no
+need to add them to `.npmignore` explicitly:
+
+* `.*.swp`
+* `._*`
+* `.DS_Store`
+* `.git`
+* `.hg`
+* `.lock-wscript`
+* `.svn`
+* `.wafpickle-*`
+* `CVS`
+* `npm-debug.log`
+
+Additionally, everything in `node_modules` is ignored, except for
+bundled dependencies. npm automatically handles this for you, so don't
+bother adding `node_modules` to `.npmignore`.
+
+The following paths and files are never ignored, so adding them to
+`.npmignore` is pointless:
+
+* `package.json`
+* `README.*`
 
 ## Link Packages
 
index 9af16f7..f0b83d5 100644 (file)
@@ -7,69 +7,72 @@ npm-shrinkwrap(1) -- Lock down dependency versions
 
 ## DESCRIPTION
 
-This command locks down the versions of a package's dependencies so that you can
-control exactly which versions of each dependency will be used when your package
-is installed. The "package.json" file is still required if you want to use "npm
-install".
-
-By default, "npm install" recursively installs the target's dependencies (as
-specified in package.json), choosing the latest available version that satisfies
-the dependency's semver pattern. In some situations, particularly when shipping
-software where each change is tightly managed, it's desirable to fully specify
-each version of each dependency recursively so that subsequent builds and
-deploys do not inadvertently pick up newer versions of a dependency that satisfy
-the semver pattern. Specifying specific semver patterns in each dependency's
-package.json would facilitate this, but that's not always possible or desirable,
-as when another author owns the npm package. It's also possible to check
-dependencies directly into source control, but that may be undesirable for other
-reasons.
+This command locks down the versions of a package's dependencies so
+that you can control exactly which versions of each dependency will be
+used when your package is installed. The "package.json" file is still
+required if you want to use "npm install".
+
+By default, "npm install" recursively installs the target's
+dependencies (as specified in package.json), choosing the latest
+available version that satisfies the dependency's semver pattern. In
+some situations, particularly when shipping software where each change
+is tightly managed, it's desirable to fully specify each version of
+each dependency recursively so that subsequent builds and deploys do
+not inadvertently pick up newer versions of a dependency that satisfy
+the semver pattern. Specifying specific semver patterns in each
+dependency's package.json would facilitate this, but that's not always
+possible or desirable, as when another author owns the npm package.
+It's also possible to check dependencies directly into source control,
+but that may be undesirable for other reasons.
 
 As an example, consider package A:
 
     {
-        "name": "A",
-        "version": "0.1.0",
-        "dependencies": {
-            "B": "<0.1.0"
-        }
+      "name": "A",
+      "version": "0.1.0",
+      "dependencies": {
+        "B": "<0.1.0"
+      }
     }
 
 package B:
 
     {
-        "name": "B",
-        "version": "0.0.1",
-        "dependencies": {
-            "C": "<0.1.0"
-        }
+      "name": "B",
+      "version": "0.0.1",
+      "dependencies": {
+        "C": "<0.1.0"
+      }
     }
 
 and package C:
 
     {
-        "name": "C,
-        "version": "0.0.1"
+      "name": "C,
+      "version": "0.0.1"
     }
 
-If these are the only versions of A, B, and C available in the registry, then
-a normal "npm install A" will install:
+If these are the only versions of A, B, and C available in the
+registry, then a normal "npm install A" will install:
 
     A@0.1.0
     `-- B@0.0.1
         `-- C@0.0.1
 
-However, if B@0.0.2 is published, then a fresh "npm install A" will install:
+However, if B@0.0.2 is published, then a fresh "npm install A" will
+install:
 
     A@0.1.0
     `-- B@0.0.2
         `-- C@0.0.1
 
-assuming the new version did not modify B's dependencies. Of course, the new
-version of B could include a new version of C and any number of new
-dependencies. If such changes are undesirable, the author of A could specify a
-dependency on B@0.0.1. However, if A's author and B's author are not the same
-person, there's no way for A's author to say that he or she does not want to
-pull in newly published versions of C when B hasn't changed at all.
+assuming the new version did not modify B's dependencies. Of course,
+the new version of B could include a new version of C and any number
+of new dependencies. If such changes are undesirable, the author of A
+could specify a dependency on B@0.0.1. However, if A's author and B's
+author are not the same person, there's no way for A's author to say
+that he or she does not want to pull in newly published versions of C
+when B hasn't changed at all.
 
 In this case, A's author can run
 
@@ -92,78 +95,88 @@ This generates npm-shrinkwrap.json, which will look something like this:
       }
     }
 
-The shrinkwrap command has locked down the dependencies based on what's
-currently installed in node_modules.  When "npm install" installs a package with
-a npm-shrinkwrap.json file in the package root, the shrinkwrap file (rather than
-package.json files) completely drives the installation of that package and all
-of its dependencies (recursively).  So now the author publishes A@0.1.0, and
-subsequent installs of this package will use B@0.0.1 and C@0.1.0, regardless the
-dependencies and versions listed in A's, B's, and C's package.json files.
+The shrinkwrap command has locked down the dependencies based on
+what's currently installed in node_modules.  When "npm install"
+installs a package with a npm-shrinkwrap.json file in the package
+root, the shrinkwrap file (rather than package.json files) completely
+drives the installation of that package and all of its dependencies
+(recursively).  So now the author publishes A@0.1.0, and subsequent
+installs of this package will use B@0.0.1 and C@0.1.0, regardless the
+dependencies and versions listed in A's, B's, and C's package.json
+files.
 
 
 ### Using shrinkwrapped packages
 
-Using a shrinkwrapped package is no different than using any other package: you
-can "npm install" it by hand, or add a dependency to your package.json file and
-"npm install" it.
+Using a shrinkwrapped package is no different than using any other
+package: you can "npm install" it by hand, or add a dependency to your
+package.json file and "npm install" it.
 
 ### Building shrinkwrapped packages
 
 To shrinkwrap an existing package:
 
-1. Run "npm install" in the package root to install the current versions of all
-   dependencies.
+1. Run "npm install" in the package root to install the current
+   versions of all dependencies.
 2. Validate that the package works as expected with these versions.
-3. Run "npm shrinkwrap", add npm-shrinkwrap.json to git, and publish your
-   package.
+3. Run "npm shrinkwrap", add npm-shrinkwrap.json to git, and publish
+   your package.
 
 To add or update a dependency in a shrinkwrapped package:
 
-1. Run "npm install" in the package root to install the current versions of all
+1. Run "npm install" in the package root to install the current
+   versions of all dependencies.
+2. Add or update dependencies. "npm install" each new or updated
+   package individually and then update package.json.  Note that they
+   must be explicitly named in order to be installed: running `npm
+   install` with no arguments will merely reproduce the existing
+   shrinkwrap.
+3. Validate that the package works as expected with the new
    dependencies.
-2. Add or update dependencies. "npm install" each new or updated package
-   individually and then update package.json.  Note that they must be
-   explicitly named in order to be installed: running `npm install` with
-   no arguments will merely reproduce the existing shrinkwrap.
-3. Validate that the package works as expected with the new dependencies.
-4. Run "npm shrinkwrap", commit the new npm-shrinkwrap.json, and publish your
-   package.
+4. Run "npm shrinkwrap", commit the new npm-shrinkwrap.json, and
+   publish your package.
 
-You can use npm-outdated(1) to view dependencies with newer versions available.
+You can use npm-outdated(1) to view dependencies with newer versions
+available.
 
 ### Other Notes
 
-Since "npm shrinkwrap" uses the locally installed packages to construct the
-shrinkwrap file, devDependencies will be included if and only if you've
-installed them already when you make the shrinkwrap.
-
-A shrinkwrap file must be consistent with the package's package.json file. "npm
-shrinkwrap" will fail if required dependencies are not already installed, since
-that would result in a shrinkwrap that wouldn't actually work. Similarly, the
-command will fail if there are extraneous packages (not referenced by
-package.json), since that would indicate that package.json is not correct.
-
-If shrinkwrapped package A depends on shrinkwrapped package B, B's shrinkwrap
-will not be used as part of the installation of A. However, because A's
-shrinkwrap is constructed from a valid installation of B and recursively
-specifies all dependencies, the contents of B's shrinkwrap will implicitly be
-included in A's shrinkwrap.
+A shrinkwrap file must be consistent with the package's package.json
+file. "npm shrinkwrap" will fail if required dependencies are not
+already installed, since that would result in a shrinkwrap that
+wouldn't actually work. Similarly, the command will fail if there are
+extraneous packages (not referenced by package.json), since that would
+indicate that package.json is not correct.
+
+Since "npm shrinkwrap" is intended to lock down your dependencies for
+production use, `devDependencies` will not be included unless you
+explicitly set the `--dev` flag when you run `npm shrinkwrap`.  If
+installed `devDependencies` are excluded, then npm will print a
+warning.  If you want them to be installed with your module by
+default, please consider adding them to `dependencies` instead.
+
+If shrinkwrapped package A depends on shrinkwrapped package B, B's
+shrinkwrap will not be used as part of the installation of A. However,
+because A's shrinkwrap is constructed from a valid installation of B
+and recursively specifies all dependencies, the contents of B's
+shrinkwrap will implicitly be included in A's shrinkwrap.
 
 ### Caveats
 
-Shrinkwrap files only lock down package versions, not actual package contents.
-While discouraged, a package author can republish an existing version of a
-package, causing shrinkwrapped packages using that version to pick up different
-code than they were before. If you want to avoid any risk that a byzantine
-author replaces a package you're using with code that breaks your application,
-you could modify the shrinkwrap file to use git URL references rather than
-version numbers so that npm always fetches all packages from git.
+Shrinkwrap files only lock down package versions, not actual package
+contents.  While discouraged, a package author can republish an
+existing version of a package, causing shrinkwrapped packages using
+that version to pick up different code than they were before. If you
+want to avoid any risk that a byzantine author replaces a package
+you're using with code that breaks your application, you could modify
+the shrinkwrap file to use git URL references rather than version
+numbers so that npm always fetches all packages from git.
 
 If you wish to lock down the specific bytes included in a package, for
-example to have 100% confidence in being able to reproduce a deployment
-or build, then you ought to check your dependencies into source control,
-or pursue some other mechanism that can verify contents rather than
-versions.
+example to have 100% confidence in being able to reproduce a
+deployment or build, then you ought to check your dependencies into
+source control, or pursue some other mechanism that can verify
+contents rather than versions.
 
 ## SEE ALSO
 
index 224f570..55fc4c6 100644 (file)
@@ -19,7 +19,7 @@
 <p>This function should not be used programmatically.  Instead, just refer
 to the <code>npm.bin</code> member.</p>
 </div>
-<p id="footer">bin &mdash; npm@1.2.23</p>
+<p id="footer">bin &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b6b2d96..6456bc3 100644 (file)
@@ -25,7 +25,7 @@ optional version number.</p>
 <p>This command will launch a browser, so this command may not be the most
 friendly for programmatic use.</p>
 </div>
-<p id="footer">bugs &mdash; npm@1.2.23</p>
+<p id="footer">bugs &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ba5cc10..3f3041e 100644 (file)
@@ -28,7 +28,7 @@ usage, or <code>man 3 npm-&lt;command&gt;</code> for programmatic usage.</p>
 
 <ul><li><a href="../doc/index.html">index(1)</a></li></ul>
 </div>
-<p id="footer">commands &mdash; npm@1.2.23</p>
+<p id="footer">commands &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3e70a64..a5a1e2b 100644 (file)
@@ -33,7 +33,7 @@ functions instead.</p>
 
 <ul><li><a href="../api/npm.html">npm(3)</a></li></ul>
 </div>
-<p id="footer">config &mdash; npm@1.2.23</p>
+<p id="footer">config &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c3b1db5..b69fc3e 100644 (file)
@@ -32,7 +32,7 @@ install the package.</p></li></ul>
 
 <ul><li><a href="../api/publish.html">publish(3)</a></li><li><a href="../api/unpublish.html">unpublish(3)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
 </div>
-<p id="footer">deprecate &mdash; npm@1.2.23</p>
+<p id="footer">deprecate &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 545b93f..ae9d0a8 100644 (file)
@@ -25,7 +25,7 @@ optional version number.</p>
 <p>This command will launch a browser, so this command may not be the most
 friendly for programmatic use.</p>
 </div>
-<p id="footer">docs &mdash; npm@1.2.23</p>
+<p id="footer">docs &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 414c003..6a0b3b9 100644 (file)
@@ -30,7 +30,7 @@ to open. The package can optionally have a version number attached.</p>
 <p>Since this command opens an editor in a new process, be careful about where
 and how this is used.</p>
 </div>
-<p id="footer">edit &mdash; npm@1.2.23</p>
+<p id="footer">edit &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index cdf2e95..f185da8 100644 (file)
@@ -24,7 +24,7 @@ sure to use <code>npm rebuild &lt;pkg&gt;</code> if you make any changes.</p>
 
 <p>The first element in the &#39;args&#39; parameter must be a package name.  After that is the optional command, which can be any number of strings. All of the strings will be combined into one, space-delimited command.</p>
 </div>
-<p id="footer">explore &mdash; npm@1.2.23</p>
+<p id="footer">explore &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 97b0443..5e0911e 100644 (file)
@@ -32,7 +32,7 @@ Name of the file that matched</li></ul>
 
 <p>The silent parameter is not neccessary not used, but it may in the future.</p>
 </div>
-<p id="footer">help-search &mdash; npm@1.2.23</p>
+<p id="footer">help-search &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9e21e1f..40d313a 100644 (file)
@@ -35,7 +35,7 @@ then go ahead and use this programmatically.</p>
 
 <p><a href="../doc/json.html">json(1)</a></p>
 </div>
-<p id="footer">init &mdash; npm@1.2.23</p>
+<p id="footer">init &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index dcad605..3bbcbd8 100644 (file)
@@ -25,7 +25,7 @@ the name of a package to be installed.</p>
 <p>Finally, &#39;callback&#39; is a function that will be called when all packages have been
 installed or when an error has been encountered.</p>
 </div>
-<p id="footer">install &mdash; npm@1.2.23</p>
+<p id="footer">install &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index fcfc95f..57e279c 100644 (file)
@@ -39,7 +39,7 @@ npm.commands.link(&#39;redis&#39;, cb)  # link-install the package</code></pre>
 <p>Now, any changes to the redis package will be reflected in
 the package in the current working directory</p>
 </div>
-<p id="footer">link &mdash; npm@1.2.23</p>
+<p id="footer">link &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 39543b4..ba9c08d 100644 (file)
@@ -32,7 +32,7 @@ config object.</p>
 
 <p>For a list of all the available command-line configs, see <code>npm help config</code></p>
 </div>
-<p id="footer">load &mdash; npm@1.2.23</p>
+<p id="footer">load &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 39abd0c..e8fe97e 100644 (file)
@@ -59,7 +59,7 @@ project.</p>
 This means that if a submodule a same dependency as a parent module, then the
 dependency will only be output once.</p>
 </div>
-<p id="footer">ls &mdash; npm@1.2.23</p>
+<p id="footer">ls &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b988742..89e7b3f 100644 (file)
@@ -24,7 +24,7 @@ npm.load([configObject,] function (er, npm) {
 
 <h2 id="VERSION">VERSION</h2>
 
-<p>1.2.23</p>
+<p>1.2.24</p>
 
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 
@@ -92,7 +92,7 @@ method names.  Use the <code>npm.deref</code> method to find the real name.</p>
 
 <pre><code>var cmd = npm.deref(&quot;unp&quot;) // cmd === &quot;unpublish&quot;</code></pre>
 </div>
-<p id="footer">npm &mdash; npm@1.2.23</p>
+<p id="footer">npm &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 2d652b3..334e5ab 100644 (file)
@@ -19,7 +19,7 @@ currently outdated.</p>
 
 <p>If the &#39;packages&#39; parameter is left out, npm will check all packages.</p>
 </div>
-<p id="footer">outdated &mdash; npm@1.2.23</p>
+<p id="footer">outdated &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 478f368..0de85ad 100644 (file)
@@ -34,7 +34,7 @@ that is not implemented at this time.</p>
 
 <ul><li><a href="../api/publish.html">publish(3)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
 </div>
-<p id="footer">owner &mdash; npm@1.2.23</p>
+<p id="footer">owner &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9721a4e..101c2dd 100644 (file)
@@ -25,7 +25,7 @@ overwritten the second time.</p>
 
 <p>If no arguments are supplied, then npm packs the current package folder.</p>
 </div>
-<p id="footer">pack &mdash; npm@1.2.23</p>
+<p id="footer">pack &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 56a019f..0dfbd72 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically</p>
 </div>
-<p id="footer">prefix &mdash; npm@1.2.23</p>
+<p id="footer">prefix &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 460b039..471ec5e 100644 (file)
@@ -23,7 +23,7 @@
 <p>Extraneous packages are packages that are not listed on the parent
 package&#39;s dependencies list.</p>
 </div>
-<p id="footer">prune &mdash; npm@1.2.23</p>
+<p id="footer">prune &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d760dac..4097f66 100644 (file)
@@ -32,7 +32,7 @@ the registry.  Overwrites when the &quot;force&quot; environment variable is set
 
 <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../api/owner.html">owner(3)</a></li></ul>
 </div>
-<p id="footer">publish &mdash; npm@1.2.23</p>
+<p id="footer">publish &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1e66b35..e222f80 100644 (file)
@@ -22,7 +22,7 @@ the new binary. If no &#39;packages&#39; parameter is specify, every package wil
 
 <p>See <code>npm help build</code></p>
 </div>
-<p id="footer">rebuild &mdash; npm@1.2.23</p>
+<p id="footer">rebuild &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b74cdeb..74beba2 100644 (file)
@@ -27,7 +27,7 @@ in the <code>packages</code> parameter.</p>
 
 <ul><li><a href="../api/start.html">start(3)</a></li><li><a href="../api/stop.html">stop(3)</a></li></ul>
 </div>
-<p id="footer">restart &mdash; npm@1.2.23</p>
+<p id="footer">restart &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 879f000..0276289 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically.</p>
 </div>
-<p id="footer">root &mdash; npm@1.2.23</p>
+<p id="footer">root &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d6cc5d4..de26092 100644 (file)
@@ -29,7 +29,7 @@ assumed to be the command to run. All other elements are ignored.</p>
 
 <ul><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../api/test.html">test(3)</a></li><li><a href="../api/start.html">start(3)</a></li><li><a href="../api/restart.html">restart(3)</a></li><li><a href="../api/stop.html">stop(3)</a></li></ul>
 </div>
-<p id="footer">run-script &mdash; npm@1.2.23</p>
+<p id="footer">run-script &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7892a3d..40a4145 100644 (file)
@@ -32,7 +32,7 @@ excluded term (the &quot;searchexclude&quot; config). The search is case insensi
 and doesn&#39;t try to read your mind (it doesn&#39;t do any verb tense matching or the
 like).</p>
 </div>
-<p id="footer">search &mdash; npm@1.2.23</p>
+<p id="footer">search &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index bc9a0ba..df35037 100644 (file)
@@ -26,7 +26,7 @@ but the shrinkwrap file will still be written.</p>
 <p>Finally, &#39;callback&#39; is a function that will be called when the shrinkwrap has
 been saved.</p>
 </div>
-<p id="footer">shrinkwrap &mdash; npm@1.2.23</p>
+<p id="footer">shrinkwrap &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6ab228f..edc58ab 100644 (file)
@@ -19,7 +19,7 @@
 <p>npm can run tests on multiple packages. Just specify multiple packages
 in the <code>packages</code> parameter.</p>
 </div>
-<p id="footer">start &mdash; npm@1.2.23</p>
+<p id="footer">start &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7f55fd5..3441751 100644 (file)
@@ -19,7 +19,7 @@
 <p>npm can run stop on multiple packages. Just specify multiple packages
 in the <code>packages</code> parameter.</p>
 </div>
-<p id="footer">stop &mdash; npm@1.2.23</p>
+<p id="footer">stop &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 492d668..aa7ca68 100644 (file)
@@ -33,7 +33,7 @@ dependencies into the submodule folder.</p>
 
 <ul><li>npm help json</li><li>git help submodule</li></ul>
 </div>
-<p id="footer">submodule &mdash; npm@1.2.23</p>
+<p id="footer">submodule &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d8b2ebb..cd84e37 100644 (file)
@@ -29,7 +29,7 @@ parameter is missing or falsey (empty), the default froom the config will be
 used. For more information about how to set this config, check
 <code>man 3 npm-config</code> for programmatic usage or <code>man npm-config</code> for cli usage.</p>
 </div>
-<p id="footer">tag &mdash; npm@1.2.23</p>
+<p id="footer">tag &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index aeb36bc..e8cd786 100644 (file)
@@ -22,7 +22,7 @@ true.</p>
 <p>npm can run tests on multiple packages. Just specify multiple packages
 in the <code>packages</code> parameter.</p>
 </div>
-<p id="footer">test &mdash; npm@1.2.23</p>
+<p id="footer">test &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ddc4011..9d04d54 100644 (file)
@@ -22,7 +22,7 @@ the name of a package to be uninstalled.</p>
 <p>Finally, &#39;callback&#39; is a function that will be called when all packages have been
 uninstalled or when an error has been encountered.</p>
 </div>
-<p id="footer">uninstall &mdash; npm@1.2.23</p>
+<p id="footer">uninstall &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b544a46..52a4054 100644 (file)
@@ -26,7 +26,7 @@ is what is meant.</p>
 <p>If no version is specified, or if all versions are removed then
 the root package entry is removed from the registry entirely.</p>
 </div>
-<p id="footer">unpublish &mdash; npm@1.2.23</p>
+<p id="footer">unpublish &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 21ca5f6..a148866 100644 (file)
@@ -18,7 +18,7 @@
 
 <p>The &#39;packages&#39; argument is an array of packages to update. The &#39;callback&#39; parameter will be called when done or when an error occurs.</p>
 </div>
-<p id="footer">update &mdash; npm@1.2.23</p>
+<p id="footer">update &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 377b742..498ce15 100644 (file)
@@ -24,7 +24,7 @@ fail if the repo is not clean.</p>
 parameter. The difference, however, is this function will fail if it does
 not have exactly one element. The only element should be a version number.</p>
 </div>
-<p id="footer">version &mdash; npm@1.2.23</p>
+<p id="footer">version &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 47d9e2d..5efa34a 100644 (file)
@@ -99,7 +99,7 @@ the field name.</p>
 
 <p>corresponding to the list of fields selected.</p>
 </div>
-<p id="footer">view &mdash; npm@1.2.23</p>
+<p id="footer">view &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index fa962a8..548a447 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically</p>
 </div>
-<p id="footer">whoami &mdash; npm@1.2.23</p>
+<p id="footer">whoami &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6ff327f..75766ee 100644 (file)
@@ -240,7 +240,7 @@ will no doubt tell you to put the output in a gist or email.</p>
 
 <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul>
 </div>
-<p id="footer"><a href="../doc/README.html">README</a> &mdash; npm@1.2.23</p>
+<p id="footer"><a href="../doc/README.html">README</a> &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0d7b5a2..c4fab65 100644 (file)
@@ -39,7 +39,7 @@ authorize on a new machine.</p>
 
 <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li></ul>
 </div>
-<p id="footer">adduser &mdash; npm@1.2.23</p>
+<p id="footer">adduser &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 145c876..20e6256 100644 (file)
@@ -20,7 +20,7 @@
 
 <ul><li><a href="../doc/prefix.html">prefix(1)</a></li><li><a href="../doc/root.html">root(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">bin &mdash; npm@1.2.23</p>
+<p id="footer">bin &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f953e78..0190450 100644 (file)
@@ -36,7 +36,7 @@ config param.</p>
 
 <ul><li><a href="../doc/docs.html">docs(1)</a></li><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
 </div>
-<p id="footer">bugs &mdash; npm@1.2.23</p>
+<p id="footer">bugs &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 39f1b45..aa70da6 100644 (file)
@@ -25,7 +25,7 @@ A folder containing a <code>package.json</code> file in its root.</li></ul>
 
 <ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
 </div>
-<p id="footer">build &mdash; npm@1.2.23</p>
+<p id="footer">build &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index cda61bc..483f44c 100644 (file)
@@ -20,7 +20,7 @@ install packages into the local space.</p>
 
 <ul><li><a href="../doc/install.html">install(1)</a></li></ul>
 </div>
-<p id="footer">bundle &mdash; npm@1.2.23</p>
+<p id="footer">bundle &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7e0c1b9..4c6c977 100644 (file)
@@ -66,7 +66,7 @@ they do not make an HTTP request to the registry.</p>
 
 <ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li></ul>
 </div>
-<p id="footer">cache &mdash; npm@1.2.23</p>
+<p id="footer">cache &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 284a4b7..9b13723 100644 (file)
@@ -65,7 +65,7 @@
 
 <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li></ul>
 </div>
-<p id="footer">changelog &mdash; npm@1.2.23</p>
+<p id="footer">changelog &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 862dcb1..297cd34 100644 (file)
@@ -182,7 +182,7 @@ set to anything.&quot;</p>
 
 <ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
 </div>
-<p id="footer">coding-style &mdash; npm@1.2.23</p>
+<p id="footer">coding-style &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index dfa023e..c524919 100644 (file)
@@ -33,7 +33,7 @@ completions based on the arguments.</p>
 
 <ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
 </div>
-<p id="footer">completion &mdash; npm@1.2.23</p>
+<p id="footer">completion &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f62817f..164239c 100644 (file)
@@ -636,6 +636,13 @@ Windows</li><li>Type: path</li></ul>
 
 <p>The shell to run for the <code>npm explore</code> command.</p>
 
+<h3 id="shrinkwrap">shrinkwrap</h3>
+
+<ul><li>Default: true</li><li>Type: Boolean</li></ul>
+
+<p>If set to false, then ignore <code>npm-shrinkwrap.json</code> files when
+installing.</p>
+
 <h3 id="sign-git-tag">sign-git-tag</h3>
 
 <ul><li>Default: false</li><li>Type: Boolean</li></ul>
@@ -771,7 +778,7 @@ then answer &quot;no&quot; to any prompt.</p>
 
 <ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
 </div>
-<p id="footer">config &mdash; npm@1.2.23</p>
+<p id="footer">config &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6951cd2..b9f750f 100644 (file)
@@ -57,7 +57,7 @@ registry.</p>
 
 <ul><li><a href="../doc/ls.html">ls(1)</a></li><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
 </div>
-<p id="footer">dedupe &mdash; npm@1.2.23</p>
+<p id="footer">dedupe &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c94c976..c7d951d 100644 (file)
@@ -31,7 +31,7 @@ something like this:</p>
 
 <ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
 </div>
-<p id="footer">deprecate &mdash; npm@1.2.23</p>
+<p id="footer">deprecate &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a86ca5c..920fb96 100644 (file)
@@ -82,10 +82,24 @@ more info.</p>
 <h2 id="Keeping-files-out-of-your-package">Keeping files <em>out</em> of your package</h2>
 
 <p>Use a <code>.npmignore</code> file to keep stuff out of your package.  If there&#39;s
-no .npmignore file, but there <em>is</em> a .gitignore file, then npm will
-ignore the stuff matched by the .gitignore file.  If you <em>want</em> to
-include something that is excluded by your .gitignore file, you can
-create an empty .npmignore file to override it.</p>
+no <code>.npmignore</code> file, but there <em>is</em> a <code>.gitignore</code> file, then npm will
+ignore the stuff matched by the <code>.gitignore</code> file.  If you <em>want</em> to
+include something that is excluded by your <code>.gitignore</code> file, you can
+create an empty <code>.npmignore</code> file to override it.</p>
+
+<p>By default, the following paths and files are ignored, so there&#39;s no
+need to add them to <code>.npmignore</code> explicitly:</p>
+
+<ul><li><code>.*.swp</code></li><li><code>._*</code></li><li><code>.DS_Store</code></li><li><code>.git</code></li><li><code>.hg</code></li><li><code>.lock-wscript</code></li><li><code>.svn</code></li><li><code>.wafpickle-*</code></li><li><code>CVS</code></li><li><code>npm-debug.log</code></li></ul>
+
+<p>Additionally, everything in <code>node_modules</code> is ignored, except for
+bundled dependencies. npm automatically handles this for you, so don&#39;t
+bother adding <code>node_modules</code> to <code>.npmignore</code>.</p>
+
+<p>The following paths and files are never ignored, so adding them to
+<code>.npmignore</code> is pointless:</p>
+
+<ul><li><code>package.json</code></li><li><code><a href="../doc/README.html">README</a>.*</code></li></ul>
 
 <h2 id="Link-Packages">Link Packages</h2>
 
@@ -160,7 +174,7 @@ from a fresh checkout.</p>
 
 <ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
 </div>
-<p id="footer">developers &mdash; npm@1.2.23</p>
+<p id="footer">developers &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f21ed97..4dc9b84 100644 (file)
@@ -91,7 +91,7 @@ things into it.</li></ol>
 
 <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li></ul>
 </div>
-<p id="footer">disputes &mdash; npm@1.2.23</p>
+<p id="footer">disputes &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9acec90..698f323 100644 (file)
@@ -37,7 +37,7 @@ config param.</p>
 
 <ul><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
 </div>
-<p id="footer">docs &mdash; npm@1.2.23</p>
+<p id="footer">docs &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e84272c..f330a0e 100644 (file)
@@ -37,7 +37,7 @@ or <code>&quot;notepad&quot;</code> on Windows.</li><li>Type: path</li></ul>
 
 <ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/explore.html">explore(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">edit &mdash; npm@1.2.23</p>
+<p id="footer">edit &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e53ef5c..bd54524 100644 (file)
@@ -40,7 +40,7 @@ Windows</li><li>Type: path</li></ul>
 
 <ul><li><a href="../doc/submodule.html">submodule(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/edit.html">edit(1)</a></li><li><a href="../doc/rebuild.html">rebuild(1)</a></li><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
 </div>
-<p id="footer">explore &mdash; npm@1.2.23</p>
+<p id="footer">explore &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7de8dc4..8934c95 100644 (file)
@@ -302,7 +302,7 @@ There is not sufficient need to impose namespace rules on everyone.</p>
 
 <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li></ul>
 </div>
-<p id="footer">faq &mdash; npm@1.2.23</p>
+<p id="footer">faq &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a79ce3d..1a0891e 100644 (file)
@@ -205,7 +205,7 @@ cannot be found elsewhere.  See <code><a href="../doc/json.html">json(1)</a></co
 
 <ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li></ul>
 </div>
-<p id="footer">folders &mdash; npm@1.2.23</p>
+<p id="footer">folders &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3bb911b..0bc91dd 100644 (file)
@@ -205,7 +205,7 @@ cannot be found elsewhere.  See <code><a href="../doc/json.html">json(1)</a></co
 
 <ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li></ul>
 </div>
-<p id="footer">global &mdash; npm@1.2.23</p>
+<p id="footer">global &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 325ec27..92b2232 100644 (file)
@@ -38,7 +38,7 @@ where the terms were found in the documentation.</p>
 
 <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li></ul>
 </div>
-<p id="footer">help-search &mdash; npm@1.2.23</p>
+<p id="footer">help-search &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0d8ce47..64c7a03 100644 (file)
@@ -36,7 +36,7 @@ matches are equivalent to specifying a topic name.</p>
 
 <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/README.html">README</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/help-search.html">help-search(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul>
 </div>
-<p id="footer">help &mdash; npm@1.2.23</p>
+<p id="footer">help &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 71bac8e..5255447 100644 (file)
 
 <p> Display npm username</p>
 </div>
-<p id="footer">index &mdash; npm@1.2.23</p>
+<p id="footer">index &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3695c1c..b2601fe 100644 (file)
@@ -29,7 +29,7 @@ without a really good reason to do so.</p>
 
 <ul><li><a href="https://github.com/isaacs/init-package-json">https://github.com/isaacs/init-package-json</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/version.html">version(1)</a></li></ul>
 </div>
-<p id="footer">init &mdash; npm@1.2.23</p>
+<p id="footer">init &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 20c0670..8072df2 100644 (file)
@@ -136,7 +136,7 @@ affects a real use-case, it will be investigated.</p>
 
 <ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/rebuild.html">rebuild(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/tag.html">tag(1)</a></li><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/shrinkwrap.html">shrinkwrap(1)</a></li></ul>
 </div>
-<p id="footer">install &mdash; npm@1.2.23</p>
+<p id="footer">install &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c250a58..f7e285a 100644 (file)
@@ -546,7 +546,7 @@ overridden.</p>
 
 <ul><li><a href="../doc/semver.html">semver(1)</a></li><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/version.html">version(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/rm.html">rm(1)</a></li></ul>
 </div>
-<p id="footer">json &mdash; npm@1.2.23</p>
+<p id="footer">json &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 4adfa61..50e6d20 100644 (file)
@@ -61,7 +61,7 @@ installation target into your project&#39;s <code>node_modules</code> folder.</p
 
 <ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">link &mdash; npm@1.2.23</p>
+<p id="footer">link &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c920ab9..cbc7899 100644 (file)
@@ -25,7 +25,7 @@ limit the results to only the paths to the packages named.  Note that
 nested packages will <em>also</em> show the paths to the specified packages.
 For example, running <code>npm ls promzard</code> in npm&#39;s source tree will show:</p>
 
-<pre><code>npm@1.2.23 /path/to/npm
+<pre><code>npm@1.2.24 /path/to/npm
 └─┬ init-package-json@0.0.4
   └── promzard@0.1.5</code></pre>
 
@@ -64,7 +64,7 @@ project.</p>
 
 <ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/outdated.html">outdated(1)</a></li><li><a href="../doc/update.html">update(1)</a></li></ul>
 </div>
-<p id="footer">ls &mdash; npm@1.2.23</p>
+<p id="footer">ls &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 858ef4f..478f56d 100644 (file)
@@ -14,7 +14,7 @@
 
 <h2 id="VERSION">VERSION</h2>
 
-<p>1.2.23</p>
+<p>1.2.24</p>
 
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 
@@ -135,7 +135,7 @@ will no doubt tell you to put the output in a gist or email.</p>
 
 <ul><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/README.html">README</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/index.html">index(1)</a></li><li><a href="../api/npm.html">npm(3)</a></li></ul>
 </div>
-<p id="footer">npm &mdash; npm@1.2.23</p>
+<p id="footer">npm &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d361a6e..407ff03 100644 (file)
@@ -21,7 +21,7 @@ packages are currently outdated.</p>
 
 <ul><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li></ul>
 </div>
-<p id="footer">outdated &mdash; npm@1.2.23</p>
+<p id="footer">outdated &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 594f1f8..c9fa27c 100644 (file)
@@ -34,7 +34,7 @@ that is not implemented at this time.</p>
 
 <ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/disputes.html">disputes(1)</a></li></ul>
 </div>
-<p id="footer">owner &mdash; npm@1.2.23</p>
+<p id="footer">owner &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9e06e2c..22e5d8f 100644 (file)
@@ -29,7 +29,7 @@ overwritten the second time.</p>
 
 <ul><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">pack &mdash; npm@1.2.23</p>
+<p id="footer">pack &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ae3badb..b53cc31 100644 (file)
@@ -20,7 +20,7 @@
 
 <ul><li><a href="../doc/root.html">root(1)</a></li><li><a href="../doc/bin.html">bin(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">prefix &mdash; npm@1.2.23</p>
+<p id="footer">prefix &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index af64457..1009f83 100644 (file)
@@ -25,7 +25,7 @@ package&#39;s dependencies list.</p>
 
 <ul><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
 </div>
-<p id="footer">prune &mdash; npm@1.2.23</p>
+<p id="footer">prune &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index fdeacba..a90ddc1 100644 (file)
@@ -29,7 +29,7 @@ the registry.  Overwrites when the &quot;--force&quot; flag is set.</p>
 
 <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li><li><a href="../doc/deprecate.html">deprecate(1)</a></li><li><a href="../doc/tag.html">tag(1)</a></li></ul>
 </div>
-<p id="footer">publish &mdash; npm@1.2.23</p>
+<p id="footer">publish &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5faa1a4..16cf38c 100644 (file)
@@ -25,7 +25,7 @@ the new binary.</p>
 
 <ul><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
 </div>
-<p id="footer">rebuild &mdash; npm@1.2.23</p>
+<p id="footer">rebuild &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b93279e..dcd87ce 100644 (file)
@@ -95,7 +95,7 @@ ask for help on the <a href="mailto:npm-@googlegroups.com">npm-@googlegroups.com
 
 <ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/disputes.html">disputes(1)</a></li></ul>
 </div>
-<p id="footer">registry &mdash; npm@1.2.23</p>
+<p id="footer">registry &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 10a22a7..7799965 100644 (file)
@@ -58,7 +58,7 @@ modules.  To track those down, you can do the following:</p>
 
 <ul><li><a href="../doc/README.html">README</a></li><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/prune.html">prune(1)</a></li></ul>
 </div>
-<p id="footer">removing-npm &mdash; npm@1.2.23</p>
+<p id="footer">removing-npm &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0b8888d..2e711ce 100644 (file)
@@ -24,7 +24,7 @@ the &quot;start&quot; script.</p>
 
 <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
 </div>
-<p id="footer">restart &mdash; npm@1.2.23</p>
+<p id="footer">restart &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 56803ae..94e9fb3 100644 (file)
@@ -22,7 +22,7 @@ on its behalf.</p>
 
 <ul><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">rm &mdash; npm@1.2.23</p>
+<p id="footer">rm &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 2768fde..b83190d 100644 (file)
@@ -20,7 +20,7 @@
 
 <ul><li><a href="../doc/prefix.html">prefix(1)</a></li><li><a href="../doc/bin.html">bin(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">root &mdash; npm@1.2.23</p>
+<p id="footer">root &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d0d14a8..6e9067a 100644 (file)
@@ -23,7 +23,7 @@ called directly, as well.</p>
 
 <ul><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
 </div>
-<p id="footer">run-script &mdash; npm@1.2.23</p>
+<p id="footer">run-script &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ab74252..61e4230 100644 (file)
@@ -218,7 +218,7 @@ will sudo the npm command in question.</li></ul>
 
 <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
 </div>
-<p id="footer">scripts &mdash; npm@1.2.23</p>
+<p id="footer">scripts &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7bc6679..e6a6ef0 100644 (file)
@@ -24,7 +24,7 @@ expression characters must be escaped or quoted in most shells.)</p>
 
 <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/view.html">view(1)</a></li></ul>
 </div>
-<p id="footer">search &mdash; npm@1.2.23</p>
+<p id="footer">search &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5ec2a44..feeb61a 100644 (file)
@@ -104,7 +104,7 @@ that satisfies the range, or null if none of them do.</li></ul>
 
 <ul><li><a href="../doc/json.html">json(1)</a></li></ul>
 </div>
-<p id="footer">semver &mdash; npm@1.2.23</p>
+<p id="footer">semver &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 872db78..9c37872 100644 (file)
 
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 
-<p>This command locks down the versions of a package&#39;s dependencies so that you can
-control exactly which versions of each dependency will be used when your package
-is installed. The &quot;package.json&quot; file is still required if you want to use &quot;npm
-install&quot;.</p>
-
-<p>By default, &quot;npm install&quot; recursively installs the target&#39;s dependencies (as
-specified in package.json), choosing the latest available version that satisfies
-the dependency&#39;s semver pattern. In some situations, particularly when shipping
-software where each change is tightly managed, it&#39;s desirable to fully specify
-each version of each dependency recursively so that subsequent builds and
-deploys do not inadvertently pick up newer versions of a dependency that satisfy
-the semver pattern. Specifying specific semver patterns in each dependency&#39;s
-package.json would facilitate this, but that&#39;s not always possible or desirable,
-as when another author owns the npm package. It&#39;s also possible to check
-dependencies directly into source control, but that may be undesirable for other
-reasons.</p>
+<p>This command locks down the versions of a package&#39;s dependencies so
+that you can control exactly which versions of each dependency will be
+used when your package is installed. The &quot;package.json&quot; file is still
+required if you want to use &quot;npm install&quot;.</p>
+
+<p>By default, &quot;npm install&quot; recursively installs the target&#39;s
+dependencies (as specified in package.json), choosing the latest
+available version that satisfies the dependency&#39;s semver pattern. In
+some situations, particularly when shipping software where each change
+is tightly managed, it&#39;s desirable to fully specify each version of
+each dependency recursively so that subsequent builds and deploys do
+not inadvertently pick up newer versions of a dependency that satisfy
+the semver pattern. Specifying specific semver patterns in each
+dependency&#39;s package.json would facilitate this, but that&#39;s not always
+possible or desirable, as when another author owns the npm package.
+It&#39;s also possible to check dependencies directly into source control,
+but that may be undesirable for other reasons.</p>
 
 <p>As an example, consider package A:</p>
 
 <pre><code>{
-    &quot;name&quot;: &quot;A&quot;,
-    &quot;version&quot;: &quot;0.1.0&quot;,
-    &quot;dependencies&quot;: {
-        &quot;B&quot;: &quot;&lt;0.1.0&quot;
-    }
+  &quot;name&quot;: &quot;A&quot;,
+  &quot;version&quot;: &quot;0.1.0&quot;,
+  &quot;dependencies&quot;: {
+    &quot;B&quot;: &quot;&lt;0.1.0&quot;
+  }
 }</code></pre>
 
 <p>package B:</p>
 
 <pre><code>{
-    &quot;name&quot;: &quot;B&quot;,
-    &quot;version&quot;: &quot;0.0.1&quot;,
-    &quot;dependencies&quot;: {
-        &quot;C&quot;: &quot;&lt;0.1.0&quot;
-    }
+  &quot;name&quot;: &quot;B&quot;,
+  &quot;version&quot;: &quot;0.0.1&quot;,
+  &quot;dependencies&quot;: {
+    &quot;C&quot;: &quot;&lt;0.1.0&quot;
+  }
 }</code></pre>
 
 <p>and package C:</p>
 
 <pre><code>{
-    &quot;name&quot;: &quot;C,
-    &quot;version&quot;: &quot;0.0.1&quot;
+  &quot;name&quot;: &quot;C,
+  &quot;version&quot;: &quot;0.0.1&quot;
 }</code></pre>
 
-<p>If these are the only versions of A, B, and C available in the registry, then
-a normal &quot;npm install A&quot; will install:</p>
+<p>If these are the only versions of A, B, and C available in the
+registry, then a normal &quot;npm install A&quot; will install:</p>
 
 <pre><code>A@0.1.0
 `-- B@0.0.1
     `-- C@0.0.1</code></pre>
 
-<p>However, if B@0.0.2 is published, then a fresh &quot;npm install A&quot; will install:</p>
+<p>However, if B@0.0.2 is published, then a fresh &quot;npm install A&quot; will
+install:</p>
 
 <pre><code>A@0.1.0
 `-- B@0.0.2
     `-- C@0.0.1</code></pre>
 
-<p>assuming the new version did not modify B&#39;s dependencies. Of course, the new
-version of B could include a new version of C and any number of new
-dependencies. If such changes are undesirable, the author of A could specify a
-dependency on B@0.0.1. However, if A&#39;s author and B&#39;s author are not the same
-person, there&#39;s no way for A&#39;s author to say that he or she does not want to
-pull in newly published versions of C when B hasn&#39;t changed at all.</p>
+<p>assuming the new version did not modify B&#39;s dependencies. Of course,
+the new version of B could include a new version of C and any number
+of new dependencies. If such changes are undesirable, the author of A
+could specify a dependency on B@0.0.1. However, if A&#39;s author and B&#39;s
+author are not the same person, there&#39;s no way for A&#39;s author to say
+that he or she does not want to pull in newly published versions of C
+when B hasn&#39;t changed at all.</p>
 
 <p>In this case, A&#39;s author can run</p>
 
@@ -99,78 +102,88 @@ pull in newly published versions of C when B hasn&#39;t changed at all.</p>
   }
 }</code></pre>
 
-<p>The shrinkwrap command has locked down the dependencies based on what&#39;s
-currently installed in node_modules.  When &quot;npm install&quot; installs a package with
-a npm-shrinkwrap.json file in the package root, the shrinkwrap file (rather than
-package.json files) completely drives the installation of that package and all
-of its dependencies (recursively).  So now the author publishes A@0.1.0, and
-subsequent installs of this package will use B@0.0.1 and C@0.1.0, regardless the
-dependencies and versions listed in A&#39;s, B&#39;s, and C&#39;s package.json files.</p>
+<p>The shrinkwrap command has locked down the dependencies based on
+what&#39;s currently installed in node_modules.  When &quot;npm install&quot;
+installs a package with a npm-shrinkwrap.json file in the package
+root, the shrinkwrap file (rather than package.json files) completely
+drives the installation of that package and all of its dependencies
+(recursively).  So now the author publishes A@0.1.0, and subsequent
+installs of this package will use B@0.0.1 and C@0.1.0, regardless the
+dependencies and versions listed in A&#39;s, B&#39;s, and C&#39;s package.json
+files.</p>
 
 <h3 id="Using-shrinkwrapped-packages">Using shrinkwrapped packages</h3>
 
-<p>Using a shrinkwrapped package is no different than using any other package: you
-can &quot;npm install&quot; it by hand, or add a dependency to your package.json file and
-&quot;npm install&quot; it.</p>
+<p>Using a shrinkwrapped package is no different than using any other
+package: you can &quot;npm install&quot; it by hand, or add a dependency to your
+package.json file and &quot;npm install&quot; it.</p>
 
 <h3 id="Building-shrinkwrapped-packages">Building shrinkwrapped packages</h3>
 
 <p>To shrinkwrap an existing package:</p>
 
-<ol><li>Run &quot;npm install&quot; in the package root to install the current versions of all
-dependencies.</li><li>Validate that the package works as expected with these versions.</li><li>Run &quot;npm shrinkwrap&quot;, add npm-shrinkwrap.json to git, and publish your
-package.</li></ol>
+<ol><li>Run &quot;npm install&quot; in the package root to install the current
+versions of all dependencies.</li><li>Validate that the package works as expected with these versions.</li><li>Run &quot;npm shrinkwrap&quot;, add npm-shrinkwrap.json to git, and publish
+your package.</li></ol>
 
 <p>To add or update a dependency in a shrinkwrapped package:</p>
 
-<ol><li>Run &quot;npm install&quot; in the package root to install the current versions of all
-dependencies.</li><li>Add or update dependencies. &quot;npm install&quot; each new or updated package
-individually and then update package.json.  Note that they must be
-explicitly named in order to be installed: running <code>npm install</code> with
-no arguments will merely reproduce the existing shrinkwrap.</li><li>Validate that the package works as expected with the new dependencies.</li><li>Run &quot;npm shrinkwrap&quot;, commit the new npm-shrinkwrap.json, and publish your
-package.</li></ol>
+<ol><li>Run &quot;npm install&quot; in the package root to install the current
+versions of all dependencies.</li><li>Add or update dependencies. &quot;npm install&quot; each new or updated
+package individually and then update package.json.  Note that they
+must be explicitly named in order to be installed: running <code>npm
+install</code> with no arguments will merely reproduce the existing
+shrinkwrap.</li><li>Validate that the package works as expected with the new
+dependencies.</li><li>Run &quot;npm shrinkwrap&quot;, commit the new npm-shrinkwrap.json, and
+publish your package.</li></ol>
 
-<p>You can use <a href="../doc/outdated.html">outdated(1)</a> to view dependencies with newer versions available.</p>
+<p>You can use <a href="../doc/outdated.html">outdated(1)</a> to view dependencies with newer versions
+available.</p>
 
 <h3 id="Other-Notes">Other Notes</h3>
 
-<p>Since &quot;npm shrinkwrap&quot; uses the locally installed packages to construct the
-shrinkwrap file, devDependencies will be included if and only if you&#39;ve
-installed them already when you make the shrinkwrap.</p>
-
-<p>A shrinkwrap file must be consistent with the package&#39;s package.json file. &quot;npm
-shrinkwrap&quot; will fail if required dependencies are not already installed, since
-that would result in a shrinkwrap that wouldn&#39;t actually work. Similarly, the
-command will fail if there are extraneous packages (not referenced by
-package.json), since that would indicate that package.json is not correct.</p>
-
-<p>If shrinkwrapped package A depends on shrinkwrapped package B, B&#39;s shrinkwrap
-will not be used as part of the installation of A. However, because A&#39;s
-shrinkwrap is constructed from a valid installation of B and recursively
-specifies all dependencies, the contents of B&#39;s shrinkwrap will implicitly be
-included in A&#39;s shrinkwrap.</p>
+<p>A shrinkwrap file must be consistent with the package&#39;s package.json
+file. &quot;npm shrinkwrap&quot; will fail if required dependencies are not
+already installed, since that would result in a shrinkwrap that
+wouldn&#39;t actually work. Similarly, the command will fail if there are
+extraneous packages (not referenced by package.json), since that would
+indicate that package.json is not correct.</p>
+
+<p>Since &quot;npm shrinkwrap&quot; is intended to lock down your dependencies for
+production use, <code>devDependencies</code> will not be included unless you
+explicitly set the <code>--dev</code> flag when you run <code>npm shrinkwrap</code>.  If
+installed <code>devDependencies</code> are excluded, then npm will print a
+warning.  If you want them to be installed with your module by
+default, please consider adding them to <code>dependencies</code> instead.</p>
+
+<p>If shrinkwrapped package A depends on shrinkwrapped package B, B&#39;s
+shrinkwrap will not be used as part of the installation of A. However,
+because A&#39;s shrinkwrap is constructed from a valid installation of B
+and recursively specifies all dependencies, the contents of B&#39;s
+shrinkwrap will implicitly be included in A&#39;s shrinkwrap.</p>
 
 <h3 id="Caveats">Caveats</h3>
 
-<p>Shrinkwrap files only lock down package versions, not actual package contents.
-While discouraged, a package author can republish an existing version of a
-package, causing shrinkwrapped packages using that version to pick up different
-code than they were before. If you want to avoid any risk that a byzantine
-author replaces a package you&#39;re using with code that breaks your application,
-you could modify the shrinkwrap file to use git URL references rather than
-version numbers so that npm always fetches all packages from git.</p>
+<p>Shrinkwrap files only lock down package versions, not actual package
+contents.  While discouraged, a package author can republish an
+existing version of a package, causing shrinkwrapped packages using
+that version to pick up different code than they were before. If you
+want to avoid any risk that a byzantine author replaces a package
+you&#39;re using with code that breaks your application, you could modify
+the shrinkwrap file to use git URL references rather than version
+numbers so that npm always fetches all packages from git.</p>
 
 <p>If you wish to lock down the specific bytes included in a package, for
-example to have 100% confidence in being able to reproduce a deployment
-or build, then you ought to check your dependencies into source control,
-or pursue some other mechanism that can verify contents rather than
-versions.</p>
+example to have 100% confidence in being able to reproduce a
+deployment or build, then you ought to check your dependencies into
+source control, or pursue some other mechanism that can verify
+contents rather than versions.</p>
 
 <h2 id="SEE-ALSO">SEE ALSO</h2>
 
 <ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
 </div>
-<p id="footer">shrinkwrap &mdash; npm@1.2.23</p>
+<p id="footer">shrinkwrap &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6392b2f..8efd6bf 100644 (file)
@@ -26,7 +26,7 @@ a vaguely positive way to show that you care.</p>
 
 <ul><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul>
 </div>
-<p id="footer">star &mdash; npm@1.2.23</p>
+<p id="footer">star &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0c15302..881834f 100644 (file)
@@ -25,7 +25,7 @@ you will most certainly enjoy this command.</p>
 
 <ul><li><a href="../doc/star.html">star(1)</a></li><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul>
 </div>
-<p id="footer">stars &mdash; npm@1.2.23</p>
+<p id="footer">stars &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6fd760d..7513ef4 100644 (file)
@@ -20,7 +20,7 @@
 
 <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
 </div>
-<p id="footer">start &mdash; npm@1.2.23</p>
+<p id="footer">start &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 35472c7..a577f62 100644 (file)
@@ -20,7 +20,7 @@
 
 <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li></ul>
 </div>
-<p id="footer">stop &mdash; npm@1.2.23</p>
+<p id="footer">stop &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 706da50..47749cc 100644 (file)
@@ -33,7 +33,7 @@ dependencies into the submodule folder.</p>
 
 <ul><li><a href="../doc/json.html">json(1)</a></li><li>git help submodule</li></ul>
 </div>
-<p id="footer">submodule &mdash; npm@1.2.23</p>
+<p id="footer">submodule &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index eb90946..af74d8b 100644 (file)
@@ -21,7 +21,7 @@
 
 <ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">tag &mdash; npm@1.2.23</p>
+<p id="footer">tag &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e91c19e..e13ca5f 100644 (file)
@@ -23,7 +23,7 @@ true.</p>
 
 <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
 </div>
-<p id="footer">test &mdash; npm@1.2.23</p>
+<p id="footer">test &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ffe0e8d..75b8c39 100644 (file)
@@ -22,7 +22,7 @@ on its behalf.</p>
 
 <ul><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">uninstall &mdash; npm@1.2.23</p>
+<p id="footer">uninstall &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6de217c..4f19000 100644 (file)
@@ -34,7 +34,7 @@ the root package entry is removed from the registry entirely.</p>
 
 <ul><li><a href="../doc/deprecate.html">deprecate(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li></ul>
 </div>
-<p id="footer">unpublish &mdash; npm@1.2.23</p>
+<p id="footer">unpublish &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c72f436..ad1c3eb 100644 (file)
@@ -26,7 +26,7 @@ If no package name is specified, all packages in the specified location (global
 
 <ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/outdated.html">outdated(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
 </div>
-<p id="footer">update &mdash; npm@1.2.23</p>
+<p id="footer">update &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8ae3a07..b66199a 100644 (file)
@@ -49,7 +49,7 @@ Enter passphrase:</code></pre>
 
 <ul><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/semver.html">semver(1)</a></li></ul>
 </div>
-<p id="footer">version &mdash; npm@1.2.23</p>
+<p id="footer">version &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 148f401..aa1a41c 100644 (file)
@@ -90,7 +90,7 @@ the field name.</p>
 
 <ul><li><a href="../doc/search.html">search(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/docs.html">docs(1)</a></li></ul>
 </div>
-<p id="footer">view &mdash; npm@1.2.23</p>
+<p id="footer">view &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9f8a769..05822b6 100644 (file)
@@ -20,7 +20,7 @@
 
 <ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul>
 </div>
-<p id="footer">whoami &mdash; npm@1.2.23</p>
+<p id="footer">whoami &mdash; npm@1.2.24</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 4db8d58..50ba5eb 100644 (file)
@@ -250,6 +250,10 @@ function readDependencies (context, where, opts, cb) {
       })
     }
 
+    // User has opted out of shrinkwraps entirely
+    if (npm.config.get("shrinkwrap") === false)
+      return cb(null, data, null)
+
     if (wrap) {
       log.verbose("readDependencies: using existing wrap", [where, wrap])
       var rv = {}
@@ -288,6 +292,14 @@ function readDependencies (context, where, opts, cb) {
       Object.keys(newwrap.dependencies || {}).forEach(function (key) {
         rv.dependencies[key] = readWrap(newwrap.dependencies[key])
       })
+
+      // fold in devDependencies if not already present, at top level
+      if (opts && opts.dev) {
+        Object.keys(data.devDependencies || {}).forEach(function (k) {
+          rv.dependencies[k] = rv.dependencies[k] || data.devDependencies[k]
+        })
+      }
+
       log.verbose("readDependencies returned deps", rv.dependencies)
       return cb(null, rv, newwrap.dependencies)
     })
@@ -568,7 +580,10 @@ function installMany (what, where, context, cb) {
       })
       asyncMap(targets, function (target, cb) {
         log.info("installOne", target._id)
-        var newWrap = wrap ? wrap[target.name].dependencies || {} : null
+        var wrapData = wrap ? wrap[target.name] : null
+        var newWrap = wrapData && wrapData.dependencies
+                    ? wrap[target.name].dependencies || {}
+                    : null
         var newContext = { family: newPrev
                          , ancestors: newAnc
                          , parent: parent
index e41f8cf..14711df 100644 (file)
@@ -7,6 +7,7 @@ var npm = require("./npm.js")
   , log = require("npmlog")
   , fs = require("fs")
   , path = require("path")
+  , readJson = require("read-package-json")
 
 shrinkwrap.usage = "npm shrinkwrap"
 
@@ -19,16 +20,37 @@ function shrinkwrap (args, silent, cb) {
 
   npm.commands.ls([], true, function (er, _, pkginfo) {
     if (er) return cb(er)
-    shrinkwrap_(pkginfo, silent, cb)
+    shrinkwrap_(pkginfo, silent, npm.config.get("dev"), cb)
   })
 }
 
-function shrinkwrap_ (pkginfo, silent, cb) {
+function shrinkwrap_ (pkginfo, silent, dev, cb) {
   if (pkginfo.problems) {
     return cb(new Error("Problems were encountered\n"
                        +"Please correct and try again.\n"
                        +pkginfo.problems.join("\n")))
   }
+
+  if (!dev) {
+    // remove dev deps unless the user does --dev
+    readJson(path.resolve(npm.prefix, "package.json"), function (er, data) {
+      if (er)
+        return cb(er)
+      if (data.devDependencies) {
+        Object.keys(data.devDependencies).forEach(function (dep) {
+          log.warn("shrinkwrap", "Excluding devDependency: %s", dep)
+          delete pkginfo.dependencies[dep]
+        })
+      }
+      save(pkginfo, silent, cb)
+    })
+  } else {
+    save(pkginfo, silent, cb)
+  }
+}
+
+
+function save (pkginfo, silent, cb) {
   try {
     var swdata = JSON.stringify(pkginfo, null, 2) + "\n"
   } catch (er) {
index 0ad8b44..3a07110 100644 (file)
@@ -1245,6 +1245,20 @@ Type: path
 .P
 The shell to run for the \fBnpm explore\fR command\.
 .
+.SS "shrinkwrap"
+.
+.IP "\(bu" 4
+Default: true
+.
+.IP "\(bu" 4
+Type: Boolean
+.
+.IP "" 0
+.
+.P
+If set to false, then ignore \fBnpm\-shrinkwrap\.json\fR files when
+installing\.
+.
 .SS "sign\-git\-tag"
 .
 .IP "\(bu" 4
index 8fa54ba..ef49a51 100644 (file)
@@ -137,10 +137,62 @@ more info\.
 .
 .SH "Keeping files "
 Use a \fB\|\.npmignore\fR file to keep stuff out of your package\.  If there\'s
-no \.npmignore file, but there \fIis\fR a \.gitignore file, then npm will
-ignore the stuff matched by the \.gitignore file\.  If you \fIwant\fR to
-include something that is excluded by your \.gitignore file, you can
-create an empty \.npmignore file to override it\.
+no \fB\|\.npmignore\fR file, but there \fIis\fR a \fB\|\.gitignore\fR file, then npm will
+ignore the stuff matched by the \fB\|\.gitignore\fR file\.  If you \fIwant\fR to
+include something that is excluded by your \fB\|\.gitignore\fR file, you can
+create an empty \fB\|\.npmignore\fR file to override it\.
+.
+.P
+By default, the following paths and files are ignored, so there\'s no
+need to add them to \fB\|\.npmignore\fR explicitly:
+.
+.IP "\(bu" 4
+\fB\|\.*\.swp\fR
+.
+.IP "\(bu" 4
+\fB\|\._*\fR
+.
+.IP "\(bu" 4
+\fB\|\.DS_Store\fR
+.
+.IP "\(bu" 4
+\fB\|\.git\fR
+.
+.IP "\(bu" 4
+\fB\|\.hg\fR
+.
+.IP "\(bu" 4
+\fB\|\.lock\-wscript\fR
+.
+.IP "\(bu" 4
+\fB\|\.svn\fR
+.
+.IP "\(bu" 4
+\fB\|\.wafpickle\-*\fR
+.
+.IP "\(bu" 4
+\fBCVS\fR
+.
+.IP "\(bu" 4
+\fBnpm\-debug\.log\fR
+.
+.IP "" 0
+.
+.P
+Additionally, everything in \fBnode_modules\fR is ignored, except for
+bundled dependencies\. npm automatically handles this for you, so don\'t
+bother adding \fBnode_modules\fR to \fB\|\.npmignore\fR\|\.
+.
+.P
+The following paths and files are never ignored, so adding them to \fB\|\.npmignore\fR is pointless:
+.
+.IP "\(bu" 4
+\fBpackage\.json\fR
+.
+.IP "\(bu" 4
+\fBREADME\.*\fR
+.
+.IP "" 0
 .
 .SH "Link Packages"
 \fBnpm link\fR is designed to install a development package and see the
index 1bac195..e3f7af3 100644 (file)
@@ -29,7 +29,7 @@ For example, running \fBnpm ls promzard\fR in npm\'s source tree will show:
 .IP "" 4
 .
 .nf
-npm@1.2.23 /path/to/npm
+npm@1.2.24 /path/to/npm
 └─┬ init\-package\-json@0\.0\.4
   └── promzard@0\.1\.5
 .
index 2a899c6..116c796 100644 (file)
@@ -14,7 +14,7 @@ npm <command> [args]
 .fi
 .
 .SH "VERSION"
-1.2.23
+1.2.24
 .
 .SH "DESCRIPTION"
 npm is the package manager for the Node JavaScript platform\.  It puts
index b121958..6e7e55a 100644 (file)
@@ -14,23 +14,24 @@ npm shrinkwrap
 .fi
 .
 .SH "DESCRIPTION"
-This command locks down the versions of a package\'s dependencies so that you can
-control exactly which versions of each dependency will be used when your package
-is installed\. The "package\.json" file is still required if you want to use "npm
-install"\.
+This command locks down the versions of a package\'s dependencies so
+that you can control exactly which versions of each dependency will be
+used when your package is installed\. The "package\.json" file is still
+required if you want to use "npm install"\.
 .
 .P
-By default, "npm install" recursively installs the target\'s dependencies (as
-specified in package\.json), choosing the latest available version that satisfies
-the dependency\'s semver pattern\. In some situations, particularly when shipping
-software where each change is tightly managed, it\'s desirable to fully specify
-each version of each dependency recursively so that subsequent builds and
-deploys do not inadvertently pick up newer versions of a dependency that satisfy
-the semver pattern\. Specifying specific semver patterns in each dependency\'s
-package\.json would facilitate this, but that\'s not always possible or desirable,
-as when another author owns the npm package\. It\'s also possible to check
-dependencies directly into source control, but that may be undesirable for other
-reasons\.
+By default, "npm install" recursively installs the target\'s
+dependencies (as specified in package\.json), choosing the latest
+available version that satisfies the dependency\'s semver pattern\. In
+some situations, particularly when shipping software where each change
+is tightly managed, it\'s desirable to fully specify each version of
+each dependency recursively so that subsequent builds and deploys do
+not inadvertently pick up newer versions of a dependency that satisfy
+the semver pattern\. Specifying specific semver patterns in each
+dependency\'s package\.json would facilitate this, but that\'s not always
+possible or desirable, as when another author owns the npm package\.
+It\'s also possible to check dependencies directly into source control,
+but that may be undesirable for other reasons\.
 .
 .P
 As an example, consider package A:
@@ -39,11 +40,11 @@ As an example, consider package A:
 .
 .nf
 {
-    "name": "A",
-    "version": "0\.1\.0",
-    "dependencies": {
-        "B": "<0\.1\.0"
-    }
+  "name": "A",
+  "version": "0\.1\.0",
+  "dependencies": {
+    "B": "<0\.1\.0"
+  }
 }
 .
 .fi
@@ -57,11 +58,11 @@ package B:
 .
 .nf
 {
-    "name": "B",
-    "version": "0\.0\.1",
-    "dependencies": {
-        "C": "<0\.1\.0"
-    }
+  "name": "B",
+  "version": "0\.0\.1",
+  "dependencies": {
+    "C": "<0\.1\.0"
+  }
 }
 .
 .fi
@@ -75,8 +76,8 @@ and package C:
 .
 .nf
 {
-    "name": "C,
-    "version": "0\.0\.1"
+  "name": "C,
+  "version": "0\.0\.1"
 }
 .
 .fi
@@ -84,8 +85,8 @@ and package C:
 .IP "" 0
 .
 .P
-If these are the only versions of A, B, and C available in the registry, then
-a normal "npm install A" will install:
+If these are the only versions of A, B, and C available in the
+registry, then a normal "npm install A" will install:
 .
 .IP "" 4
 .
@@ -99,7 +100,8 @@ A@0\.1\.0
 .IP "" 0
 .
 .P
-However, if B@0\.0\.2 is published, then a fresh "npm install A" will install:
+However, if B@0\.0\.2 is published, then a fresh "npm install A" will
+install:
 .
 .IP "" 4
 .
@@ -113,12 +115,13 @@ A@0\.1\.0
 .IP "" 0
 .
 .P
-assuming the new version did not modify B\'s dependencies\. Of course, the new
-version of B could include a new version of C and any number of new
-dependencies\. If such changes are undesirable, the author of A could specify a
-dependency on B@0\.0\.1\. However, if A\'s author and B\'s author are not the same
-person, there\'s no way for A\'s author to say that he or she does not want to
-pull in newly published versions of C when B hasn\'t changed at all\.
+assuming the new version did not modify B\'s dependencies\. Of course,
+the new version of B could include a new version of C and any number
+of new dependencies\. If such changes are undesirable, the author of A
+could specify a dependency on B@0\.0\.1\. However, if A\'s author and B\'s
+author are not the same person, there\'s no way for A\'s author to say
+that he or she does not want to pull in newly published versions of C
+when B hasn\'t changed at all\.
 .
 .P
 In this case, A\'s author can run
@@ -158,32 +161,34 @@ This generates npm\-shrinkwrap\.json, which will look something like this:
 .IP "" 0
 .
 .P
-The shrinkwrap command has locked down the dependencies based on what\'s
-currently installed in node_modules\.  When "npm install" installs a package with
-a npm\-shrinkwrap\.json file in the package root, the shrinkwrap file (rather than
-package\.json files) completely drives the installation of that package and all
-of its dependencies (recursively)\.  So now the author publishes A@0\.1\.0, and
-subsequent installs of this package will use B@0\.0\.1 and C@0\.1\.0, regardless the
-dependencies and versions listed in A\'s, B\'s, and C\'s package\.json files\.
+The shrinkwrap command has locked down the dependencies based on
+what\'s currently installed in node_modules\.  When "npm install"
+installs a package with a npm\-shrinkwrap\.json file in the package
+root, the shrinkwrap file (rather than package\.json files) completely
+drives the installation of that package and all of its dependencies
+(recursively)\.  So now the author publishes A@0\.1\.0, and subsequent
+installs of this package will use B@0\.0\.1 and C@0\.1\.0, regardless the
+dependencies and versions listed in A\'s, B\'s, and C\'s package\.json
+files\.
 .
 .SS "Using shrinkwrapped packages"
-Using a shrinkwrapped package is no different than using any other package: you
-can "npm install" it by hand, or add a dependency to your package\.json file and
-"npm install" it\.
+Using a shrinkwrapped package is no different than using any other
+package: you can "npm install" it by hand, or add a dependency to your
+package\.json file and "npm install" it\.
 .
 .SS "Building shrinkwrapped packages"
 To shrinkwrap an existing package:
 .
 .IP "1" 4
-Run "npm install" in the package root to install the current versions of all
-dependencies\.
+Run "npm install" in the package root to install the current
+versions of all dependencies\.
 .
 .IP "2" 4
 Validate that the package works as expected with these versions\.
 .
 .IP "3" 4
-Run "npm shrinkwrap", add npm\-shrinkwrap\.json to git, and publish your
-package\.
+Run "npm shrinkwrap", add npm\-shrinkwrap\.json to git, and publish
+your package\.
 .
 .IP "" 0
 .
@@ -191,61 +196,69 @@ package\.
 To add or update a dependency in a shrinkwrapped package:
 .
 .IP "1" 4
-Run "npm install" in the package root to install the current versions of all
-dependencies\.
+Run "npm install" in the package root to install the current
+versions of all dependencies\.
 .
 .IP "2" 4
-Add or update dependencies\. "npm install" each new or updated package
-individually and then update package\.json\.  Note that they must be
-explicitly named in order to be installed: running \fBnpm install\fR with
-no arguments will merely reproduce the existing shrinkwrap\.
+Add or update dependencies\. "npm install" each new or updated
+package individually and then update package\.json\.  Note that they
+must be explicitly named in order to be installed: running \fBnpm
+install\fR with no arguments will merely reproduce the existing
+shrinkwrap\.
 .
 .IP "3" 4
-Validate that the package works as expected with the new dependencies\.
+Validate that the package works as expected with the new
+dependencies\.
 .
 .IP "4" 4
-Run "npm shrinkwrap", commit the new npm\-shrinkwrap\.json, and publish your
-package\.
+Run "npm shrinkwrap", commit the new npm\-shrinkwrap\.json, and
+publish your package\.
 .
 .IP "" 0
 .
 .P
-You can use npm help outdated to view dependencies with newer versions available\.
+You can use npm help outdated to view dependencies with newer versions
+available\.
 .
 .SS "Other Notes"
-Since "npm shrinkwrap" uses the locally installed packages to construct the
-shrinkwrap file, devDependencies will be included if and only if you\'ve
-installed them already when you make the shrinkwrap\.
+A shrinkwrap file must be consistent with the package\'s package\.json
+file\. "npm shrinkwrap" will fail if required dependencies are not
+already installed, since that would result in a shrinkwrap that
+wouldn\'t actually work\. Similarly, the command will fail if there are
+extraneous packages (not referenced by package\.json), since that would
+indicate that package\.json is not correct\.
 .
 .P
-A shrinkwrap file must be consistent with the package\'s package\.json file\. "npm
-shrinkwrap" will fail if required dependencies are not already installed, since
-that would result in a shrinkwrap that wouldn\'t actually work\. Similarly, the
-command will fail if there are extraneous packages (not referenced by
-package\.json), since that would indicate that package\.json is not correct\.
+Since "npm shrinkwrap" is intended to lock down your dependencies for
+production use, \fBdevDependencies\fR will not be included unless you
+explicitly set the \fB\-\-dev\fR flag when you run \fBnpm shrinkwrap\fR\|\.  If
+installed \fBdevDependencies\fR are excluded, then npm will print a
+warning\.  If you want them to be installed with your module by
+default, please consider adding them to \fBdependencies\fR instead\.
 .
 .P
-If shrinkwrapped package A depends on shrinkwrapped package B, B\'s shrinkwrap
-will not be used as part of the installation of A\. However, because A\'s
-shrinkwrap is constructed from a valid installation of B and recursively
-specifies all dependencies, the contents of B\'s shrinkwrap will implicitly be
-included in A\'s shrinkwrap\.
+If shrinkwrapped package A depends on shrinkwrapped package B, B\'s
+shrinkwrap will not be used as part of the installation of A\. However,
+because A\'s shrinkwrap is constructed from a valid installation of B
+and recursively specifies all dependencies, the contents of B\'s
+shrinkwrap will implicitly be included in A\'s shrinkwrap\.
 .
 .SS "Caveats"
-Shrinkwrap files only lock down package versions, not actual package contents\.
-While discouraged, a package author can republish an existing version of a
-package, causing shrinkwrapped packages using that version to pick up different
-code than they were before\. If you want to avoid any risk that a byzantine
-author replaces a package you\'re using with code that breaks your application,
-you could modify the shrinkwrap file to use git URL references rather than
-version numbers so that npm always fetches all packages from git\.
+Shrinkwrap files only lock down package versions, not actual package
+contents\.  While discouraged, a package author can republish an
+existing version of a package, causing shrinkwrapped packages using
+that version to pick up different code than they were before\. If you
+want to avoid any risk that a byzantine author replaces a package
+you\'re using with code that breaks your application, you could modify
+the shrinkwrap file to use git URL references rather than version
+numbers so that npm always fetches all packages from git\.
 .
 .P
 If you wish to lock down the specific bytes included in a package, for
-example to have 100% confidence in being able to reproduce a deployment
-or build, then you ought to check your dependencies into source control,
-or pursue some other mechanism that can verify contents rather than
-versions\.
+example to have 100% confidence in being able to reproduce a
+deployment or build, then you ought to check your dependencies into
+source control, or pursue some other mechanism that can verify
+contents rather than versions\.
 .
 .SH "SEE ALSO"
 .
index 304a7c5..dc2e3c2 100644 (file)
@@ -21,7 +21,7 @@ npm\.load([configObject,] function (er, npm) {
 .fi
 .
 .SH "VERSION"
-1.2.23
+1.2.24
 .
 .SH "DESCRIPTION"
 This is the API documentation for npm\.
index f05f820..cfc9820 100644 (file)
@@ -32,7 +32,7 @@ $ npm install -g node-gyp
 You will also need to install:
 
   * On Unix:
-    * `python`
+    * `python` (`v2.7` recommended, `v3.x.x` is __*not*__ supported)
     * `make`
     * A proper C/C++ compiler toolchain, like GCC
   * On Windows:
@@ -42,7 +42,7 @@ You will also need to install:
       * For 64-bit builds of node and native modules you will _**also**_ need the [Windows 7 64-bit SDK][win7sdk]
         * If the install fails, try uninstalling any C++ 2010 x64&x86 Redistributable that you have installed first.
       * If you get errors that the 64-bit compilers are not installed you may also need the [compiler update for the Windows SDK 7.1]
-    * Windows 8:
+    * Windows 7/8:
       * Microsoft Visual Studio C++ 2012 for Windows Desktop ([Express][msvc2012] version works well)
 
 Note that OS X is just a flavour of Unix and so needs `python`, `make`, and C/C++.
@@ -93,7 +93,7 @@ your package, alongside the `package.json` file.
 
 A barebones `gyp` file appropriate for building a node addon looks like:
 
-``` json
+``` python
 {
   "targets": [
     {
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/LICENSE b/deps/npm/node_modules/node-gyp/node_modules/request/LICENSE
new file mode 100644 (file)
index 0000000..a4a9aee
--- /dev/null
@@ -0,0 +1,55 @@
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/README.md b/deps/npm/node_modules/node-gyp/node_modules/request/README.md
new file mode 100644 (file)
index 0000000..d1f5c56
--- /dev/null
@@ -0,0 +1,310 @@
+# Request -- Simplified HTTP request method
+
+## Install
+
+<pre>
+  npm install request
+</pre>
+
+Or from source:
+
+<pre>
+  git clone git://github.com/mikeal/request.git 
+  cd request
+  npm link
+</pre>
+
+## Super simple to use
+
+Request is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.
+
+```javascript
+var request = require('request');
+request('http://www.google.com', function (error, response, body) {
+  if (!error && response.statusCode == 200) {
+    console.log(body) // Print the google web page.
+  }
+})
+```
+
+## Streaming
+
+You can stream any response to a file stream.
+
+```javascript
+request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))
+```
+
+You can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.
+
+```javascript
+fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))
+```
+
+Request can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.
+
+```javascript
+request.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))
+```
+
+Now let's get fancy.
+
+```javascript
+http.createServer(function (req, resp) {
+  if (req.url === '/doodle.png') {
+    if (req.method === 'PUT') {
+      req.pipe(request.put('http://mysite.com/doodle.png'))
+    } else if (req.method === 'GET' || req.method === 'HEAD') {
+      request.get('http://mysite.com/doodle.png').pipe(resp)
+    } 
+  }
+})
+```
+
+You can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:
+
+```javascript
+http.createServer(function (req, resp) {
+  if (req.url === '/doodle.png') {
+    var x = request('http://mysite.com/doodle.png')
+    req.pipe(x)
+    x.pipe(resp)
+  }
+})
+```
+
+And since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)
+
+```javascript
+req.pipe(request('http://mysite.com/doodle.png')).pipe(resp)
+```
+
+Also, none of this new functionality conflicts with requests previous features, it just expands them.
+
+```javascript
+var r = request.defaults({'proxy':'http://localproxy.com'})
+
+http.createServer(function (req, resp) {
+  if (req.url === '/doodle.png') {
+    r.get('http://google.com/doodle.png').pipe(resp)
+  }
+})
+```
+You can still use intermediate proxies, the requests will still follow HTTP forwards, etc.
+
+## Forms
+
+`request` supports `application/x-www-form-urlencoded` and `multipart/form-data` form uploads. For `multipart/related` refer to the `multipart` API.
+
+Url encoded forms are simple
+
+```javascript
+request.post('http://service.com/upload', {form:{key:'value'}})
+// or
+request.post('http://service.com/upload').form({key:'value'})
+```
+
+For `multipart/form-data` we use the [form-data](https://github.com/felixge/node-form-data) library by [@felixge](https://github.com/felixge). You don't need to worry about piping the form object or setting the headers, `request` will handle that for you.
+
+```javascript
+var r = request.post('http://service.com/upload')
+var form = r.form()
+form.append('my_field', 'my_value')
+form.append('my_buffer', new Buffer([1, 2, 3]))
+form.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png'))
+form.append('remote_file', request('http://google.com/doodle.png'))
+```
+
+## OAuth Signing
+
+```javascript
+// Twitter OAuth
+var qs = require('querystring')
+  , oauth =
+    { callback: 'http://mysite.com/callback/'
+    , consumer_key: CONSUMER_KEY
+    , consumer_secret: CONSUMER_SECRET
+    }
+  , url = 'https://api.twitter.com/oauth/request_token'
+  ;
+request.post({url:url, oauth:oauth}, function (e, r, body) {
+  // Assume by some stretch of magic you aquired the verifier
+  var access_token = qs.parse(body)
+    , oauth = 
+      { consumer_key: CONSUMER_KEY
+      , consumer_secret: CONSUMER_SECRET
+      , token: access_token.oauth_token
+      , verifier: VERIFIER
+      , token_secret: access_token.oauth_token_secret
+      }
+    , url = 'https://api.twitter.com/oauth/access_token'
+    ;
+  request.post({url:url, oauth:oauth}, function (e, r, body) {
+    var perm_token = qs.parse(body)
+      , oauth = 
+        { consumer_key: CONSUMER_KEY
+        , consumer_secret: CONSUMER_SECRET
+        , token: perm_token.oauth_token
+        , token_secret: perm_token.oauth_token_secret
+        }
+      , url = 'https://api.twitter.com/1/users/show.json?'
+      , params = 
+        { screen_name: perm_token.screen_name
+        , user_id: perm_token.user_id
+        }
+      ;
+    url += qs.stringify(params)
+    request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {
+      console.log(user)
+    })
+  })
+})
+```
+
+
+
+### request(options, callback)
+
+The first argument can be either a url or an options object. The only required option is uri, all others are optional.
+
+* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()
+* `qs` - object containing querystring values to be appended to the uri
+* `method` - http method, defaults to GET
+* `headers` - http headers, defaults to {}
+* `body` - entity body for POST and PUT requests. Must be buffer or string.
+* `form` - when passed an object this will set `body` but to a querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header. When passed no option a FormData instance is returned that will be piped to request.
+* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header.  Additionally, parses the response body as json.
+* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.
+* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.
+* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.
+* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.
+* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.
+* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.
+* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.
+* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request       
+* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.
+* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.
+* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.
+* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)
+* `aws` - object containing aws signing information, should have the properties `key` and `secret` as well as `bucket` unless you're specifying your bucket as part of the path, or you are making a request that doesn't use a bucket (i.e. GET Services)
+
+
+The callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.
+
+## Convenience methods
+
+There are also shorthand methods for different HTTP METHODs and some other conveniences.
+
+### request.defaults(options)  
+  
+This method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.
+
+### request.put
+
+Same as request() but defaults to `method: "PUT"`.
+
+```javascript
+request.put(url)
+```
+
+### request.post
+
+Same as request() but defaults to `method: "POST"`.
+
+```javascript
+request.post(url)
+```
+
+### request.head
+
+Same as request() but defaults to `method: "HEAD"`.
+
+```javascript
+request.head(url)
+```
+
+### request.del
+
+Same as request() but defaults to `method: "DELETE"`.
+
+```javascript
+request.del(url)
+```
+
+### request.get
+
+Alias to normal request method for uniformity.
+
+```javascript
+request.get(url)
+```
+### request.cookie
+
+Function that creates a new cookie.
+
+```javascript
+request.cookie('cookie_string_here')
+```
+### request.jar
+
+Function that creates a new cookie jar.
+
+```javascript
+request.jar()
+```
+
+
+## Examples:
+
+```javascript
+  var request = require('request')
+    , rand = Math.floor(Math.random()*100000000).toString()
+    ;
+  request(
+    { method: 'PUT'
+    , uri: 'http://mikeal.iriscouch.com/testjs/' + rand
+    , multipart: 
+      [ { 'content-type': 'application/json'
+        ,  body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
+        }
+      , { body: 'I am an attachment' }
+      ] 
+    }
+  , function (error, response, body) {
+      if(response.statusCode == 201){
+        console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)
+      } else {
+        console.log('error: '+ response.statusCode)
+        console.log(body)
+      }
+    }
+  )
+```
+Cookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent).
+
+```javascript
+var request = request.defaults({jar: false})
+request('http://www.google.com', function () {
+  request('http://images.google.com')
+})
+```
+
+If you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:
+
+```javascript
+var j = request.jar()
+var request = request.defaults({jar:j})
+request('http://www.google.com', function () {
+  request('http://images.google.com')
+})
+```
+OR
+
+```javascript
+var j = request.jar()
+var cookie = request.cookie('your_cookie_here')
+j.add(cookie)
+request({url: 'http://www.google.com', jar: j}, function () {
+  request('http://images.google.com')
+})
+```
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/aws.js b/deps/npm/node_modules/node-gyp/node_modules/request/aws.js
new file mode 100644 (file)
index 0000000..4d8d950
--- /dev/null
@@ -0,0 +1,191 @@
+
+/*!
+ * knox - auth
+ * Copyright(c) 2010 LearnBoost <dev@learnboost.com>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var crypto = require('crypto')
+  , parse = require('url').parse
+  ;
+
+/**
+ * Valid keys.
+ */
+
+var keys = 
+  [ 'acl'
+  , 'location'
+  , 'logging'
+  , 'notification'
+  , 'partNumber'
+  , 'policy'
+  , 'requestPayment'
+  , 'torrent'
+  , 'uploadId'
+  , 'uploads'
+  , 'versionId'
+  , 'versioning'
+  , 'versions'
+  , 'website'
+  ]
+
+/**
+ * Return an "Authorization" header value with the given `options`
+ * in the form of "AWS <key>:<signature>"
+ *
+ * @param {Object} options
+ * @return {String}
+ * @api private
+ */
+
+exports.authorization = function(options){
+  return 'AWS ' + options.key + ':' + exports.sign(options)
+}
+
+/**
+ * Simple HMAC-SHA1 Wrapper
+ *
+ * @param {Object} options
+ * @return {String}
+ * @api private
+ */ 
+
+exports.hmacSha1 = function(options){
+  return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64')
+}
+
+/**
+ * Create a base64 sha1 HMAC for `options`. 
+ * 
+ * @param {Object} options
+ * @return {String}
+ * @api private
+ */
+
+exports.sign = function(options){
+  options.message = exports.stringToSign(options)
+  return exports.hmacSha1(options)
+}
+
+/**
+ * Create a base64 sha1 HMAC for `options`. 
+ *
+ * Specifically to be used with S3 presigned URLs
+ * 
+ * @param {Object} options
+ * @return {String}
+ * @api private
+ */
+
+exports.signQuery = function(options){
+  options.message = exports.queryStringToSign(options)
+  return exports.hmacSha1(options)
+}
+
+/**
+ * Return a string for sign() with the given `options`.
+ *
+ * Spec:
+ * 
+ *    <verb>\n
+ *    <md5>\n
+ *    <content-type>\n
+ *    <date>\n
+ *    [headers\n]
+ *    <resource>
+ *
+ * @param {Object} options
+ * @return {String}
+ * @api private
+ */
+
+exports.stringToSign = function(options){
+  var headers = options.amazonHeaders || ''
+  if (headers) headers += '\n'
+  var r = 
+    [ options.verb
+    , options.md5
+    , options.contentType
+    , options.date.toUTCString()
+    , headers + options.resource
+    ]
+  return r.join('\n')
+}
+
+/**
+ * Return a string for sign() with the given `options`, but is meant exclusively
+ * for S3 presigned URLs
+ *
+ * Spec:
+ * 
+ *    <date>\n
+ *    <resource>
+ *
+ * @param {Object} options
+ * @return {String}
+ * @api private
+ */
+
+exports.queryStringToSign = function(options){
+  return 'GET\n\n\n' + options.date + '\n' + options.resource
+};
+
+/**
+ * Perform the following:
+ *
+ *  - ignore non-amazon headers
+ *  - lowercase fields
+ *  - sort lexicographically
+ *  - trim whitespace between ":"
+ *  - join with newline
+ *
+ * @param {Object} headers
+ * @return {String}
+ * @api private
+ */
+
+exports.canonicalizeHeaders = function(headers){
+  var buf = []
+    , fields = Object.keys(headers)
+    ;
+  for (var i = 0, len = fields.length; i < len; ++i) {
+    var field = fields[i]
+      , val = headers[field]
+      , field = field.toLowerCase()
+      ;
+    if (0 !== field.indexOf('x-amz')) continue
+    buf.push(field + ':' + val)
+  }
+  return buf.sort().join('\n')
+};
+
+/**
+ * Perform the following:
+ *
+ *  - ignore non sub-resources
+ *  - sort lexicographically
+ *
+ * @param {String} resource
+ * @return {String}
+ * @api private
+ */
+
+exports.canonicalizeResource = function(resource){
+  var url = parse(resource, true)
+    , path = url.pathname
+    , buf = []
+    ;
+
+  Object.keys(url.query).forEach(function(key){
+    if (!~keys.indexOf(key)) return
+    var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key])
+    buf.push(key + val)
+  })
+
+  return path + (buf.length ? '?' + buf.sort().join('&') : '')
+};
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/forever.js b/deps/npm/node_modules/node-gyp/node_modules/request/forever.js
new file mode 100644 (file)
index 0000000..1e1d4b9
--- /dev/null
@@ -0,0 +1,103 @@
+module.exports = ForeverAgent
+ForeverAgent.SSL = ForeverAgentSSL
+
+var util = require('util')
+  , Agent = require('http').Agent
+  , net = require('net')
+  , tls = require('tls')
+  , AgentSSL = require('https').Agent
+
+function ForeverAgent(options) {
+  var self = this
+  self.options = options || {}
+  self.requests = {}
+  self.sockets = {}
+  self.freeSockets = {}
+  self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets
+  self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets
+  self.on('free', function(socket, host, port) {
+    var name = host + ':' + port
+    if (self.requests[name] && self.requests[name].length) {
+      self.requests[name].shift().onSocket(socket)
+    } else if (self.sockets[name].length < self.minSockets) {
+      if (!self.freeSockets[name]) self.freeSockets[name] = []
+      self.freeSockets[name].push(socket)
+      
+      // if an error happens while we don't use the socket anyway, meh, throw the socket away
+      function onIdleError() {
+        socket.destroy()
+      }
+      socket._onIdleError = onIdleError
+      socket.on('error', onIdleError)
+    } else {
+      // If there are no pending requests just destroy the
+      // socket and it will get removed from the pool. This
+      // gets us out of timeout issues and allows us to
+      // default to Connection:keep-alive.
+      socket.destroy()
+    }
+  })
+
+}
+util.inherits(ForeverAgent, Agent)
+
+ForeverAgent.defaultMinSockets = 5
+
+
+ForeverAgent.prototype.createConnection = net.createConnection
+ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest
+ForeverAgent.prototype.addRequest = function(req, host, port) {
+  var name = host + ':' + port
+  if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) {
+    var idleSocket = this.freeSockets[name].pop()
+    idleSocket.removeListener('error', idleSocket._onIdleError)
+    delete idleSocket._onIdleError
+    req._reusedSocket = true
+    req.onSocket(idleSocket)
+  } else {
+    this.addRequestNoreuse(req, host, port)
+  }
+}
+
+ForeverAgent.prototype.removeSocket = function(s, name, host, port) {
+  if (this.sockets[name]) {
+    var index = this.sockets[name].indexOf(s)
+    if (index !== -1) {
+      this.sockets[name].splice(index, 1)
+    }
+  } else if (this.sockets[name] && this.sockets[name].length === 0) {
+    // don't leak
+    delete this.sockets[name]
+    delete this.requests[name]
+  }
+  
+  if (this.freeSockets[name]) {
+    var index = this.freeSockets[name].indexOf(s)
+    if (index !== -1) {
+      this.freeSockets[name].splice(index, 1)
+      if (this.freeSockets[name].length === 0) {
+        delete this.freeSockets[name]
+      }
+    }
+  }
+
+  if (this.requests[name] && this.requests[name].length) {
+    // If we have pending requests and a socket gets closed a new one
+    // needs to be created to take over in the pool for the one that closed.
+    this.createSocket(name, host, port).emit('free')
+  }
+}
+
+function ForeverAgentSSL (options) {
+  ForeverAgent.call(this, options)
+}
+util.inherits(ForeverAgentSSL, ForeverAgent)
+
+ForeverAgentSSL.prototype.createConnection = createConnectionSSL
+ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest
+
+function createConnectionSSL (port, host, options) {
+  options.port = port
+  options.host = host
+  return tls.connect(options)
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/main.js b/deps/npm/node_modules/node-gyp/node_modules/request/main.js
new file mode 100644 (file)
index 0000000..27b470b
--- /dev/null
@@ -0,0 +1,1123 @@
+// Copyright 2010-2012 Mikeal Rogers
+//
+//    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.
+
+var http = require('http')
+  , https = false
+  , tls = false
+  , url = require('url')
+  , util = require('util')
+  , stream = require('stream')
+  , qs = require('querystring')
+  , oauth = require('./oauth')
+  , uuid = require('./uuid')
+  , ForeverAgent = require('./forever')
+  , Cookie = require('./vendor/cookie')
+  , CookieJar = require('./vendor/cookie/jar')
+  , cookieJar = new CookieJar
+  , tunnel = require('./tunnel')
+  , aws = require('./aws')
+  
+  , mime = require('mime')
+  , FormData = require('form-data')
+  ;
+  
+if (process.logging) {
+  var log = process.logging('request')
+}
+
+try {
+  https = require('https')
+} catch (e) {}
+
+try {
+  tls = require('tls')
+} catch (e) {}
+
+function toBase64 (str) {
+  return (new Buffer(str || "", "ascii")).toString("base64")
+}
+
+// Hacky fix for pre-0.4.4 https
+if (https && !https.Agent) {
+  https.Agent = function (options) {
+    http.Agent.call(this, options)
+  }
+  util.inherits(https.Agent, http.Agent)
+  https.Agent.prototype._getConnection = function (host, port, cb) {
+    var s = tls.connect(port, host, this.options, function () {
+      // do other checks here?
+      if (cb) cb()
+    })
+    return s
+  }
+}
+
+function isReadStream (rs) {
+  if (rs.readable && rs.path && rs.mode) {
+    return true
+  }
+}
+
+function copy (obj) {
+  var o = {}
+  Object.keys(obj).forEach(function (i) {
+    o[i] = obj[i]
+  })
+  return o
+}
+
+var isUrl = /^https?:/
+
+var globalPool = {}
+
+function Request (options) {
+  stream.Stream.call(this)
+  this.readable = true
+  this.writable = true
+
+  if (typeof options === 'string') {
+    options = {uri:options}
+  }
+  
+  var reserved = Object.keys(Request.prototype)
+  for (var i in options) {
+    if (reserved.indexOf(i) === -1) {
+      this[i] = options[i]
+    } else {
+      if (typeof options[i] === 'function') {
+        delete options[i]
+      }
+    }
+  }
+  options = copy(options)
+  
+  this.init(options)
+}
+util.inherits(Request, stream.Stream)
+Request.prototype.init = function (options) {
+  var self = this
+  
+  if (!options) options = {}
+  if (process.env.NODE_DEBUG && /request/.test(process.env.NODE_DEBUG)) console.error('REQUEST', options)
+  if (!self.pool && self.pool !== false) self.pool = globalPool
+  self.dests = []
+  self.__isRequestRequest = true
+  
+  // Protect against double callback
+  if (!self._callback && self.callback) {
+    self._callback = self.callback
+    self.callback = function () {
+      if (self._callbackCalled) return // Print a warning maybe?
+      self._callback.apply(self, arguments)
+      self._callbackCalled = true
+    }
+    self.on('error', self.callback.bind())
+    self.on('complete', self.callback.bind(self, null))
+  }
+
+  if (self.url) {
+    // People use this property instead all the time so why not just support it.
+    self.uri = self.url
+    delete self.url
+  }
+
+  if (!self.uri) {
+    // this will throw if unhandled but is handleable when in a redirect
+    return self.emit('error', new Error("options.uri is a required argument"))
+  } else {
+    if (typeof self.uri == "string") self.uri = url.parse(self.uri)
+  }
+  if (self.proxy) {
+    if (typeof self.proxy == 'string') self.proxy = url.parse(self.proxy)
+
+    // do the HTTP CONNECT dance using koichik/node-tunnel
+    if (http.globalAgent && self.uri.protocol === "https:") {
+      var tunnelFn = self.proxy.protocol === "http:"
+                   ? tunnel.httpsOverHttp : tunnel.httpsOverHttps
+
+      var tunnelOptions = { proxy: { host: self.proxy.hostname
+                                   , port: +self.proxy.port
+                                   , proxyAuth: self.proxy.auth }
+                          , ca: this.ca }
+
+      self.agent = tunnelFn(tunnelOptions)
+      self.tunnel = true
+    }
+  }
+
+  if (!self.uri.host || !self.uri.pathname) {
+    // Invalid URI: it may generate lot of bad errors, like "TypeError: Cannot call method 'indexOf' of undefined" in CookieJar
+    // Detect and reject it as soon as possible
+    var faultyUri = url.format(self.uri)
+    var message = 'Invalid URI "' + faultyUri + '"'
+    if (Object.keys(options).length === 0) {
+      // No option ? This can be the sign of a redirect
+      // As this is a case where the user cannot do anything (he didn't call request directly with this URL)
+      // he should be warned that it can be caused by a redirection (can save some hair)
+      message += '. This can be caused by a crappy redirection.'
+    }
+    self.emit('error', new Error(message))
+    return // This error was fatal
+  }
+
+  self._redirectsFollowed = self._redirectsFollowed || 0
+  self.maxRedirects = (self.maxRedirects !== undefined) ? self.maxRedirects : 10
+  self.followRedirect = (self.followRedirect !== undefined) ? self.followRedirect : true
+  self.followAllRedirects = (self.followAllRedirects !== undefined) ? self.followAllRedirects : false
+  if (self.followRedirect || self.followAllRedirects)
+    self.redirects = self.redirects || []
+
+  self.headers = self.headers ? copy(self.headers) : {}
+
+  self.setHost = false
+  if (!self.headers.host) {
+    self.headers.host = self.uri.hostname
+    if (self.uri.port) {
+      if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') &&
+           !(self.uri.port === 443 && self.uri.protocol === 'https:') )
+      self.headers.host += (':'+self.uri.port)
+    }
+    self.setHost = true
+  }
+  
+  self.jar(self._jar || options.jar)
+
+  if (!self.uri.pathname) {self.uri.pathname = '/'}
+  if (!self.uri.port) {
+    if (self.uri.protocol == 'http:') {self.uri.port = 80}
+    else if (self.uri.protocol == 'https:') {self.uri.port = 443}
+  }
+
+  if (self.proxy && !self.tunnel) {
+    self.port = self.proxy.port
+    self.host = self.proxy.hostname
+  } else {
+    self.port = self.uri.port
+    self.host = self.uri.hostname
+  }
+
+  self.clientErrorHandler = function (error) {
+    if (self._aborted) return
+    
+    if (self.setHost) delete self.headers.host
+    if (self.req._reusedSocket && error.code === 'ECONNRESET'
+        && self.agent.addRequestNoreuse) {
+      self.agent = { addRequest: self.agent.addRequestNoreuse.bind(self.agent) }
+      self.start()
+      self.req.end()
+      return
+    }
+    if (self.timeout && self.timeoutTimer) {
+      clearTimeout(self.timeoutTimer)
+      self.timeoutTimer = null
+    }
+    self.emit('error', error)
+  }
+
+  self._parserErrorHandler = function (error) {
+    if (this.res) {
+      if (this.res.request) {
+        this.res.request.emit('error', error)
+      } else {
+        this.res.emit('error', error)
+      }
+    } else {
+      this._httpMessage.emit('error', error)
+    }
+  }
+
+  if (options.form) {
+    self.form(options.form)
+  }
+
+  if (options.oauth) {
+    self.oauth(options.oauth)
+  }
+  
+  if (options.aws) {
+    self.aws(options.aws)
+  }
+
+  if (self.uri.auth && !self.headers.authorization) {
+    self.headers.authorization = "Basic " + toBase64(self.uri.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':'))
+  }
+  if (self.proxy && self.proxy.auth && !self.headers['proxy-authorization'] && !self.tunnel) {
+    self.headers['proxy-authorization'] = "Basic " + toBase64(self.proxy.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':'))
+  }
+
+  if (options.qs) self.qs(options.qs)
+
+  if (self.uri.path) {
+    self.path = self.uri.path
+  } else {
+    self.path = self.uri.pathname + (self.uri.search || "")
+  }
+
+  if (self.path.length === 0) self.path = '/'
+
+  if (self.proxy && !self.tunnel) self.path = (self.uri.protocol + '//' + self.uri.host + self.path)
+
+  if (options.json) {
+    self.json(options.json)
+  } else if (options.multipart) {
+    self.boundary = uuid()
+    self.multipart(options.multipart)
+  }
+
+  if (self.body) {
+    var length = 0
+    if (!Buffer.isBuffer(self.body)) {
+      if (Array.isArray(self.body)) {
+        for (var i = 0; i < self.body.length; i++) {
+          length += self.body[i].length
+        }
+      } else {
+        self.body = new Buffer(self.body)
+        length = self.body.length
+      }
+    } else {
+      length = self.body.length
+    }
+    if (length) {
+      if(!self.headers['content-length'] && !self.headers['Content-Length'])
+      self.headers['content-length'] = length
+    } else {
+      throw new Error('Argument error, options.body.')
+    }
+  }
+
+  var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol
+    , defaultModules = {'http:':http, 'https:':https}
+    , httpModules = self.httpModules || {}
+    ;
+  self.httpModule = httpModules[protocol] || defaultModules[protocol]
+
+  if (!self.httpModule) return this.emit('error', new Error("Invalid protocol"))
+
+  if (options.ca) self.ca = options.ca
+
+  if (!self.agent) {
+    if (options.agentOptions) self.agentOptions = options.agentOptions
+
+    if (options.agentClass) {
+      self.agentClass = options.agentClass
+    } else if (options.forever) {
+      self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL
+    } else {
+      self.agentClass = self.httpModule.Agent
+    }
+  }
+
+  if (self.pool === false) {
+    self.agent = false
+  } else {
+    self.agent = self.agent || self.getAgent()
+    if (self.maxSockets) {
+      // Don't use our pooling if node has the refactored client
+      self.agent.maxSockets = self.maxSockets
+    }
+    if (self.pool.maxSockets) {
+      // Don't use our pooling if node has the refactored client
+      self.agent.maxSockets = self.pool.maxSockets
+    }
+  }
+
+  self.once('pipe', function (src) {
+    if (self.ntick && self._started) throw new Error("You cannot pipe to this stream after the outbound request has started.")
+    self.src = src
+    if (isReadStream(src)) {
+      if (!self.headers['content-type'] && !self.headers['Content-Type'])
+        self.headers['content-type'] = mime.lookup(src.path)
+    } else {
+      if (src.headers) {
+        for (var i in src.headers) {
+          if (!self.headers[i]) {
+            self.headers[i] = src.headers[i]
+          }
+        }
+      }
+      if (self._json && !self.headers['content-type'] && !self.headers['Content-Type'])
+        self.headers['content-type'] = 'application/json'
+      if (src.method && !self.method) {
+        self.method = src.method
+      }
+    }
+
+    self.on('pipe', function () {
+      console.error("You have already piped to this stream. Pipeing twice is likely to break the request.")
+    })
+  })
+
+  process.nextTick(function () {
+    if (self._aborted) return
+    
+    if (self._form) {
+      self.setHeaders(self._form.getHeaders())
+      self._form.pipe(self)
+    }
+    if (self.body) {
+      if (Array.isArray(self.body)) {
+        self.body.forEach(function (part) {
+          self.write(part)
+        })
+      } else {
+        self.write(self.body)
+      }
+      self.end()
+    } else if (self.requestBodyStream) {
+      console.warn("options.requestBodyStream is deprecated, please pass the request object to stream.pipe.")
+      self.requestBodyStream.pipe(self)
+    } else if (!self.src) {
+      if (self.method !== 'GET' && typeof self.method !== 'undefined') {
+        self.headers['content-length'] = 0
+      }
+      self.end()
+    }
+    self.ntick = true
+  })
+}
+
+// Must call this when following a redirect from https to http or vice versa
+// Attempts to keep everything as identical as possible, but update the
+// httpModule, Tunneling agent, and/or Forever Agent in use.
+Request.prototype._updateProtocol = function () {
+  var self = this
+  var protocol = self.uri.protocol
+
+  if (protocol === 'https:') {
+    // previously was doing http, now doing https
+    // if it's https, then we might need to tunnel now.
+    if (self.proxy) {
+      self.tunnel = true
+      var tunnelFn = self.proxy.protocol === 'http:'
+                   ? tunnel.httpsOverHttp : tunnel.httpsOverHttps
+      var tunnelOptions = { proxy: { host: self.proxy.hostname
+                                   , post: +self.proxy.port
+                                   , proxyAuth: self.proxy.auth }
+                          , ca: self.ca }
+      self.agent = tunnelFn(tunnelOptions)
+      return
+    }
+
+    self.httpModule = https
+    switch (self.agentClass) {
+      case ForeverAgent:
+        self.agentClass = ForeverAgent.SSL
+        break
+      case http.Agent:
+        self.agentClass = https.Agent
+        break
+      default:
+        // nothing we can do.  Just hope for the best.
+        return
+    }
+
+    // if there's an agent, we need to get a new one.
+    if (self.agent) self.agent = self.getAgent()
+
+  } else {
+    if (log) log('previously https, now http')
+    // previously was doing https, now doing http
+    // stop any tunneling.
+    if (self.tunnel) self.tunnel = false
+    self.httpModule = http
+    switch (self.agentClass) {
+      case ForeverAgent.SSL:
+        self.agentClass = ForeverAgent
+        break
+      case https.Agent:
+        self.agentClass = http.Agent
+        break
+      default:
+        // nothing we can do.  just hope for the best
+        return
+    }
+
+    // if there's an agent, then get a new one.
+    if (self.agent) {
+      self.agent = null
+      self.agent = self.getAgent()
+    }
+  }
+}
+
+Request.prototype.getAgent = function () {
+  var Agent = this.agentClass
+  var options = {}
+  if (this.agentOptions) {
+    for (var i in this.agentOptions) {
+      options[i] = this.agentOptions[i]
+    }
+  }
+  if (this.ca) options.ca = this.ca
+
+  var poolKey = ''
+
+  // different types of agents are in different pools
+  if (Agent !== this.httpModule.Agent) {
+    poolKey += Agent.name
+  }
+
+  if (!this.httpModule.globalAgent) {
+    // node 0.4.x
+    options.host = this.host
+    options.port = this.port
+    if (poolKey) poolKey += ':'
+    poolKey += this.host + ':' + this.port
+  }
+
+  // ca option is only relevant if proxy or destination are https
+  var proxy = this.proxy
+  if (typeof proxy === 'string') proxy = url.parse(proxy)
+  var caRelevant = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:'
+  if (options.ca && caRelevant) {
+    if (poolKey) poolKey += ':'
+    poolKey += options.ca
+  }
+
+  if (!poolKey && Agent === this.httpModule.Agent && this.httpModule.globalAgent) {
+    // not doing anything special.  Use the globalAgent
+    return this.httpModule.globalAgent
+  }
+
+  // we're using a stored agent.  Make sure it's protocol-specific
+  poolKey = this.uri.protocol + poolKey
+
+  // already generated an agent for this setting
+  if (this.pool[poolKey]) return this.pool[poolKey]
+
+  return this.pool[poolKey] = new Agent(options)
+}
+
+Request.prototype.start = function () {
+  var self = this
+
+  if (self._aborted) return
+
+  self._started = true
+  self.method = self.method || 'GET'
+  self.href = self.uri.href
+  if (log) log('%method %href', self)
+
+  if (self.src && self.src.stat && self.src.stat.size && !self.headers['content-length'] && !self.headers['Content-Length']) {
+    self.headers['content-length'] = self.src.stat.size
+  }
+  if (self._aws) {
+    self.aws(self._aws, true)
+  }
+  self.req = self.httpModule.request(self, function (response) {
+    if (response.connection.listeners('error').indexOf(self._parserErrorHandler) === -1) {
+      response.connection.once('error', self._parserErrorHandler)
+    }
+    if (self._aborted) return
+    if (self._paused) response.pause()
+
+    self.response = response
+    response.request = self
+    response.toJSON = toJSON
+
+    if (self.httpModule === https &&
+        self.strictSSL &&
+        !response.client.authorized) {
+      var sslErr = response.client.authorizationError
+      self.emit('error', new Error('SSL Error: '+ sslErr))
+      return
+    }
+
+    if (self.setHost) delete self.headers.host
+    if (self.timeout && self.timeoutTimer) {
+      clearTimeout(self.timeoutTimer)
+      self.timeoutTimer = null
+    }  
+
+    var addCookie = function (cookie) {
+      if (self._jar) self._jar.add(new Cookie(cookie))
+      else cookieJar.add(new Cookie(cookie))
+    }
+
+    if (response.headers['set-cookie'] && (!self._disableCookies)) {
+      if (Array.isArray(response.headers['set-cookie'])) response.headers['set-cookie'].forEach(addCookie)
+      else addCookie(response.headers['set-cookie'])
+    }
+
+    if (response.statusCode >= 300 && response.statusCode < 400  &&
+        (self.followAllRedirects ||
+         (self.followRedirect && (self.method !== 'PUT' && self.method !== 'POST' && self.method !== 'DELETE'))) &&
+        response.headers.location) {
+      if (self._redirectsFollowed >= self.maxRedirects) {
+        self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop "+self.uri.href))
+        return
+      }
+      self._redirectsFollowed += 1
+
+      if (!isUrl.test(response.headers.location)) {
+        response.headers.location = url.resolve(self.uri.href, response.headers.location)
+      }
+
+      var uriPrev = self.uri
+      self.uri = url.parse(response.headers.location)
+
+      // handle the case where we change protocol from https to http or vice versa
+      if (self.uri.protocol !== uriPrev.protocol) {
+        self._updateProtocol()
+      }
+
+      self.redirects.push(
+        { statusCode : response.statusCode
+        , redirectUri: response.headers.location 
+        }
+      )
+      if (self.followAllRedirects) self.method = 'GET'
+      // self.method = 'GET' // Force all redirects to use GET || commented out fixes #215
+      delete self.src
+      delete self.req
+      delete self.agent
+      delete self._started
+      delete self.body
+      delete self._form
+      if (self.headers) {
+        delete self.headers.host
+        delete self.headers['content-type']
+        delete self.headers['content-length']
+      }
+      if (log) log('Redirect to %uri', self)
+      self.init()
+      return // Ignore the rest of the response
+    } else {
+      self._redirectsFollowed = self._redirectsFollowed || 0
+      // Be a good stream and emit end when the response is finished.
+      // Hack to emit end on close because of a core bug that never fires end
+      response.on('close', function () {
+        if (!self._ended) self.response.emit('end')
+      })
+
+      if (self.encoding) {
+        if (self.dests.length !== 0) {
+          console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.")
+        } else {
+          response.setEncoding(self.encoding)
+        }
+      }
+
+      self.dests.forEach(function (dest) {
+        self.pipeDest(dest)
+      })
+
+      response.on("data", function (chunk) {
+        self._destdata = true
+        self.emit("data", chunk)
+      })
+      response.on("end", function (chunk) {
+        self._ended = true
+        self.emit("end", chunk)
+      })
+      response.on("close", function () {self.emit("close")})
+
+      self.emit('response', response)
+
+      if (self.callback) {
+        var buffer = []
+        var bodyLen = 0
+        self.on("data", function (chunk) {
+          buffer.push(chunk)
+          bodyLen += chunk.length
+        })
+        self.on("end", function () {
+          if (self._aborted) return
+          
+          if (buffer.length && Buffer.isBuffer(buffer[0])) {
+            var body = new Buffer(bodyLen)
+            var i = 0
+            buffer.forEach(function (chunk) {
+              chunk.copy(body, i, 0, chunk.length)
+              i += chunk.length
+            })
+            if (self.encoding === null) {
+              response.body = body
+            } else {
+              response.body = body.toString(self.encoding)
+            }
+          } else if (buffer.length) {
+            response.body = buffer.join('')
+          }
+
+          if (self._json) {
+            try {
+              response.body = JSON.parse(response.body)
+            } catch (e) {}
+          }
+          
+          self.emit('complete', response, response.body)
+        })
+      }
+    }
+  })
+
+  if (self.timeout && !self.timeoutTimer) {
+    self.timeoutTimer = setTimeout(function () {
+      self.req.abort()
+      var e = new Error("ETIMEDOUT")
+      e.code = "ETIMEDOUT"
+      self.emit("error", e)
+    }, self.timeout)
+    
+    // Set additional timeout on socket - in case if remote
+    // server freeze after sending headers
+    if (self.req.setTimeout) { // only works on node 0.6+
+      self.req.setTimeout(self.timeout, function () {
+        if (self.req) {
+          self.req.abort()
+          var e = new Error("ESOCKETTIMEDOUT")
+          e.code = "ESOCKETTIMEDOUT"
+          self.emit("error", e)
+        }
+      })
+    }
+  }
+  
+  self.req.on('error', self.clientErrorHandler)
+  self.req.on('drain', function() {
+    self.emit('drain')
+  })
+  self.on('end', function() {
+    if ( self.req.connection ) self.req.connection.removeListener('error', self._parserErrorHandler)
+  })
+  self.emit('request', self.req)
+}
+
+Request.prototype.abort = function () {
+  this._aborted = true
+  
+  if (this.req) {
+    this.req.abort()
+  }
+  else if (this.response) {
+    this.response.abort()
+  }
+  
+  this.emit("abort")
+}
+
+Request.prototype.pipeDest = function (dest) {
+  var response = this.response
+  // Called after the response is received
+  if (dest.headers) {
+    dest.headers['content-type'] = response.headers['content-type']
+    if (response.headers['content-length']) {
+      dest.headers['content-length'] = response.headers['content-length']
+    }
+  }
+  if (dest.setHeader) {
+    for (var i in response.headers) {
+      dest.setHeader(i, response.headers[i])
+    }
+    dest.statusCode = response.statusCode
+  }
+  if (this.pipefilter) this.pipefilter(response, dest)
+}
+
+// Composable API
+Request.prototype.setHeader = function (name, value, clobber) {
+  if (clobber === undefined) clobber = true
+  if (clobber || !this.headers.hasOwnProperty(name)) this.headers[name] = value
+  else this.headers[name] += ',' + value
+  return this
+}
+Request.prototype.setHeaders = function (headers) {
+  for (var i in headers) {this.setHeader(i, headers[i])}
+  return this
+}
+Request.prototype.qs = function (q, clobber) {
+  var base
+  if (!clobber && this.uri.query) base = qs.parse(this.uri.query)
+  else base = {}
+  
+  for (var i in q) {
+    base[i] = q[i]
+  }
+  
+  this.uri = url.parse(this.uri.href.split('?')[0] + '?' + qs.stringify(base))
+  this.url = this.uri
+  
+  return this
+}
+Request.prototype.form = function (form) {
+  if (form) {
+    this.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8'
+    this.body = qs.stringify(form).toString('utf8')
+    return this
+  } 
+  // create form-data object
+  this._form = new FormData()
+  return this._form
+}
+Request.prototype.multipart = function (multipart) {
+  var self = this
+  self.body = []
+
+  if (!self.headers['content-type']) {
+    self.headers['content-type'] = 'multipart/related; boundary=' + self.boundary
+  } else {
+    self.headers['content-type'] = self.headers['content-type'].split(';')[0] + '; boundary=' + self.boundary
+  }
+
+  if (!multipart.forEach) throw new Error('Argument error, options.multipart.')
+
+  if (self.preambleCRLF) {
+    self.body.push(new Buffer('\r\n'))
+  }
+  
+  multipart.forEach(function (part) {
+    var body = part.body
+    if(body == null) throw Error('Body attribute missing in multipart.')
+    delete part.body
+    var preamble = '--' + self.boundary + '\r\n'
+    Object.keys(part).forEach(function (key) {
+      preamble += key + ': ' + part[key] + '\r\n'
+    })
+    preamble += '\r\n'
+    self.body.push(new Buffer(preamble))
+    self.body.push(new Buffer(body))
+    self.body.push(new Buffer('\r\n'))
+  })
+  self.body.push(new Buffer('--' + self.boundary + '--'))
+  return self
+}
+Request.prototype.json = function (val) {
+  this.setHeader('accept', 'application/json')
+  this._json = true
+  if (typeof val === 'boolean') {
+    if (typeof this.body === 'object') {
+      this.setHeader('content-type', 'application/json')
+      this.body = JSON.stringify(this.body)
+    }
+  } else {
+    this.setHeader('content-type', 'application/json')
+    this.body = JSON.stringify(val)
+  }
+  return this
+}
+function getHeader(name, headers) {
+    var result, re, match
+    Object.keys(headers).forEach(function (key) {
+        re = new RegExp(name, 'i')
+        match = key.match(re)
+        if (match) result = headers[key]
+    })
+    return result
+}
+Request.prototype.aws = function (opts, now) {
+  if (!now) {
+    this._aws = opts
+    return this
+  }
+  var date = new Date()
+  this.setHeader('date', date.toUTCString())
+  var auth =
+    { key: opts.key
+    , secret: opts.secret
+    , verb: this.method.toUpperCase()
+    , date: date
+    , contentType: getHeader('content-type', this.headers) || ''
+    , md5: getHeader('content-md5', this.headers) || ''
+    , amazonHeaders: aws.canonicalizeHeaders(this.headers)
+    }
+  if (opts.bucket && this.path) {
+    auth.resource = '/' + opts.bucket + this.path
+  } else if (opts.bucket && !this.path) {
+    auth.resource = '/' + opts.bucket
+  } else if (!opts.bucket && this.path) {
+    auth.resource = this.path
+  } else if (!opts.bucket && !this.path) {
+    auth.resource = '/'
+  }
+  auth.resource = aws.canonicalizeResource(auth.resource)
+  this.setHeader('authorization', aws.authorization(auth))
+  
+  return this
+}
+
+Request.prototype.oauth = function (_oauth) {
+  var form
+  if (this.headers['content-type'] && 
+      this.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) ===
+        'application/x-www-form-urlencoded' 
+     ) {
+    form = qs.parse(this.body)
+  }
+  if (this.uri.query) {
+    form = qs.parse(this.uri.query)
+  } 
+  if (!form) form = {}
+  var oa = {}
+  for (var i in form) oa[i] = form[i]
+  for (var i in _oauth) oa['oauth_'+i] = _oauth[i]
+  if (!oa.oauth_version) oa.oauth_version = '1.0'
+  if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( (new Date()).getTime() / 1000 ).toString()
+  if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '')
+  
+  oa.oauth_signature_method = 'HMAC-SHA1'
+  
+  var consumer_secret = oa.oauth_consumer_secret
+  delete oa.oauth_consumer_secret
+  var token_secret = oa.oauth_token_secret
+  delete oa.oauth_token_secret
+  
+  var baseurl = this.uri.protocol + '//' + this.uri.host + this.uri.pathname
+  var signature = oauth.hmacsign(this.method, baseurl, oa, consumer_secret, token_secret)
+  
+  // oa.oauth_signature = signature
+  for (var i in form) {
+    if ( i.slice(0, 'oauth_') in _oauth) {
+      // skip 
+    } else {
+      delete oa['oauth_'+i]
+      if (i !== 'x_auth_mode') delete oa[i]
+    }
+  }
+  this.headers.Authorization = 
+    'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',')
+  this.headers.Authorization += ',oauth_signature="' + oauth.rfc3986(signature) + '"'
+  return this
+}
+Request.prototype.jar = function (jar) {
+  var cookies
+  
+  if (this._redirectsFollowed === 0) {
+    this.originalCookieHeader = this.headers.cookie
+  }
+  
+  if (jar === false) {
+    // disable cookies
+    cookies = false
+    this._disableCookies = true
+  } else if (jar) {
+    // fetch cookie from the user defined cookie jar
+    cookies = jar.get({ url: this.uri.href })
+  } else {
+    // fetch cookie from the global cookie jar
+    cookies = cookieJar.get({ url: this.uri.href })
+  }
+  
+  if (cookies && cookies.length) {
+    var cookieString = cookies.map(function (c) {
+      return c.name + "=" + c.value
+    }).join("; ")
+
+    if (this.originalCookieHeader) {
+      // Don't overwrite existing Cookie header
+      this.headers.cookie = this.originalCookieHeader + '; ' + cookieString
+    } else {
+      this.headers.cookie = cookieString
+    }
+  }
+  this._jar = jar
+  return this
+}
+
+
+// Stream API
+Request.prototype.pipe = function (dest, opts) {
+  if (this.response) {
+    if (this._destdata) {
+      throw new Error("You cannot pipe after data has been emitted from the response.")
+    } else if (this._ended) {
+      throw new Error("You cannot pipe after the response has been ended.")
+    } else {
+      stream.Stream.prototype.pipe.call(this, dest, opts)
+      this.pipeDest(dest)
+      return dest
+    }
+  } else {
+    this.dests.push(dest)
+    stream.Stream.prototype.pipe.call(this, dest, opts)
+    return dest
+  }
+}
+Request.prototype.write = function () {
+  if (!this._started) this.start()
+  return this.req.write.apply(this.req, arguments)
+}
+Request.prototype.end = function (chunk) {
+  if (chunk) this.write(chunk)
+  if (!this._started) this.start()
+  this.req.end()
+}
+Request.prototype.pause = function () {
+  if (!this.response) this._paused = true
+  else this.response.pause.apply(this.response, arguments)
+}
+Request.prototype.resume = function () {
+  if (!this.response) this._paused = false
+  else this.response.resume.apply(this.response, arguments)
+}
+Request.prototype.destroy = function () {
+  if (!this._ended) this.end()
+}
+
+// organize params for post, put, head, del
+function initParams(uri, options, callback) {
+  if ((typeof options === 'function') && !callback) callback = options
+  if (options && typeof options === 'object') {
+    options.uri = uri
+  } else if (typeof uri === 'string') {
+    options = {uri:uri}
+  } else {
+    options = uri
+    uri = options.uri
+  }
+  return { uri: uri, options: options, callback: callback }
+}
+
+function request (uri, options, callback) {
+  if (typeof uri === 'undefined') throw new Error('undefined is not a valid uri or options object.')
+  if ((typeof options === 'function') && !callback) callback = options
+  if (options && typeof options === 'object') {
+    options.uri = uri
+  } else if (typeof uri === 'string') {
+    options = {uri:uri}
+  } else {
+    options = uri
+  }
+
+  if (callback) options.callback = callback
+  var r = new Request(options)
+  return r
+}
+
+module.exports = request
+
+request.initParams = initParams
+
+request.defaults = function (options, requester) {
+  var def = function (method) {
+    var d = function (uri, opts, callback) {
+      var params = initParams(uri, opts, callback)
+      for (var i in options) {
+        if (params.options[i] === undefined) params.options[i] = options[i]
+      }
+      if(typeof requester === 'function') {
+        if(method === request) {
+          method = requester
+        } else {
+          params.options._requester = requester
+        }
+      }
+      return method(params.options, params.callback)
+    }
+    return d
+  }
+  var de = def(request)
+  de.get = def(request.get)
+  de.post = def(request.post)
+  de.put = def(request.put)
+  de.head = def(request.head)
+  de.del = def(request.del)
+  de.cookie = def(request.cookie)
+  de.jar = request.jar
+  return de
+}
+
+request.forever = function (agentOptions, optionsArg) {
+  var options = {}
+  if (optionsArg) {
+    for (option in optionsArg) {
+      options[option] = optionsArg[option]
+    }
+  }
+  if (agentOptions) options.agentOptions = agentOptions
+  options.forever = true
+  return request.defaults(options)
+}
+
+request.get = request
+request.post = function (uri, options, callback) {
+  var params = initParams(uri, options, callback)
+  params.options.method = 'POST'
+  return request(params.uri || null, params.options, params.callback)
+}
+request.put = function (uri, options, callback) {
+  var params = initParams(uri, options, callback)
+  params.options.method = 'PUT'
+  return request(params.uri || null, params.options, params.callback)
+}
+request.head = function (uri, options, callback) {
+  var params = initParams(uri, options, callback)
+  params.options.method = 'HEAD'
+  if (params.options.body || 
+      params.options.requestBodyStream || 
+      (params.options.json && typeof params.options.json !== 'boolean') || 
+      params.options.multipart) {
+    throw new Error("HTTP HEAD requests MUST NOT include a request body.")
+  }
+  return request(params.uri || null, params.options, params.callback)
+}
+request.del = function (uri, options, callback) {
+  var params = initParams(uri, options, callback)
+  params.options.method = 'DELETE'
+  if(typeof params.options._requester === 'function') {
+    request = params.options._requester
+  }
+  return request(params.uri || null, params.options, params.callback)
+}
+request.jar = function () {
+  return new CookieJar
+}
+request.cookie = function (str) {
+  if (str && str.uri) str = str.uri
+  if (typeof str !== 'string') throw new Error("The cookie function only accepts STRING as param")
+  return new Cookie(str)
+}
+
+// Safe toJSON
+
+function getSafe (self, uuid) {  
+  if (typeof self === 'object' || typeof self === 'function') var safe = {}
+  if (Array.isArray(self)) var safe = []
+
+  var recurse = []
+  
+  Object.defineProperty(self, uuid, {})
+  
+  var attrs = Object.keys(self).filter(function (i) {
+    if (i === uuid) return false 
+    if ( (typeof self[i] !== 'object' && typeof self[i] !== 'function') || self[i] === null) return true
+    return !(Object.getOwnPropertyDescriptor(self[i], uuid))
+  })
+  
+  
+  for (var i=0;i<attrs.length;i++) {
+    if ( (typeof self[attrs[i]] !== 'object' && typeof self[attrs[i]] !== 'function') || 
+          self[attrs[i]] === null
+        ) {
+      safe[attrs[i]] = self[attrs[i]]
+    } else {
+      recurse.push(attrs[i])
+      Object.defineProperty(self[attrs[i]], uuid, {})
+    }
+  }
+
+  for (var i=0;i<recurse.length;i++) {
+    safe[recurse[i]] = getSafe(self[recurse[i]], uuid)
+  }
+  
+  return safe
+}
+
+function toJSON () {
+  return getSafe(this, (((1+Math.random())*0x10000)|0).toString(16))
+}
+
+Request.prototype.toJSON = toJSON
+
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/.npmignore b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/.npmignore
new file mode 100644 (file)
index 0000000..8595734
--- /dev/null
@@ -0,0 +1,5 @@
+*.un~
+/node_modules/*
+/test/tmp
+/.idea
+*.iml
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/Makefile b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/Makefile
new file mode 100644 (file)
index 0000000..b4ff85a
--- /dev/null
@@ -0,0 +1,7 @@
+SHELL := /bin/bash
+
+test:
+       @./test/run.js
+
+.PHONY: test
+
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/Readme.md b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/Readme.md
new file mode 100644 (file)
index 0000000..3bf153f
--- /dev/null
@@ -0,0 +1,86 @@
+# form-data
+
+A module to create readable `"multipart/form-data"` streams.  Can be used to
+submit forms and file uploads to other web applications.
+
+The API of this module is inspired by the
+[XMLHttpRequest-2 FormData Interface][xhr2-fd].
+
+[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface
+
+## Install
+
+Sorry, this isn't ready for you yet.
+
+## Usage
+
+In this example we are constructing a form with 3 fields that contain a string,
+a buffer and a file stream.
+
+``` javascript
+var FormData = require('form-data');
+var fs = require('fs');
+
+var form = new FormData();
+form.append('my_field', 'my value');
+form.append('my_buffer', new Buffer(10));
+form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
+```
+
+Also you can use http-response stream:
+
+``` javascript
+var FormData = require('form-data');
+var http = require('http');
+
+var form = new FormData();
+
+http.request('http://nodejs.org/images/logo.png', function(response) {
+  form.append('my_field', 'my value');
+  form.append('my_buffer', new Buffer(10));
+  form.append('my_logo', response);
+});
+```
+
+Or @mikeal's request stream:
+
+``` javascript
+var FormData = require('form-data');
+var request = require('request');
+
+var form = new FormData();
+
+form.append('my_field', 'my value');
+form.append('my_buffer', new Buffer(10));
+form.append('my_logo', request('http://nodejs.org/images/logo.png'));
+```
+
+In order to submit this form to a web application, you can use node's http
+client interface:
+
+``` javascript
+var http = require('http');
+
+var request = http.request({
+  method: 'post',
+  host: 'example.org',
+  path: '/upload',
+  headers: form.getHeaders()
+});
+
+form.pipe(request);
+
+request.on('response', function(res) {
+  console.log(res.statusCode);
+});
+```
+
+Or if you would prefer the `'Content-Length'` header to be set for you:
+
+``` javascript
+form.submit('example.org/upload', function(err, res) {
+  console.log(res.statusCode);
+});
+```
+
+[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/lib/form_data.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/lib/form_data.js
new file mode 100644 (file)
index 0000000..426b06f
--- /dev/null
@@ -0,0 +1,237 @@
+var CombinedStream = require('combined-stream');
+var util = require('util');
+var path = require('path');
+var http = require('http');
+var https = require('https');
+var parseUrl = require('url').parse;
+var fs = require('fs');
+var mime = require('mime');
+var async = require('async');
+
+module.exports = FormData;
+function FormData() {
+  this._overheadLength = 0;
+  this._valueLength = 0;
+  this._lengthRetrievers = [];
+
+  CombinedStream.call(this);
+}
+util.inherits(FormData, CombinedStream);
+
+FormData.LINE_BREAK = '\r\n';
+
+FormData.prototype.append = function(field, value) {
+  var append = CombinedStream.prototype.append.bind(this);
+
+  // all that streamy business can't handle numbers
+  if (typeof value == 'number') value = ''+value;
+
+  var header = this._multiPartHeader(field, value);
+  var footer = this._multiPartFooter(field, value);
+
+  append(header);
+  append(value);
+  append(footer);
+
+  this._trackLength(header, value)
+};
+
+FormData.prototype._trackLength = function(header, value) {
+  var valueLength = 0;
+  if (Buffer.isBuffer(value)) {
+    valueLength = value.length;
+  } else if (typeof value === 'string') {
+    valueLength = Buffer.byteLength(value);
+  }
+
+  this._valueLength += valueLength;
+  this._overheadLength +=
+    Buffer.byteLength(header) +
+    + FormData.LINE_BREAK.length;
+
+  // empty or ethier doesn't have path or not an http response
+  if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) {
+    return;
+  }
+
+  this._lengthRetrievers.push(function(next) {
+
+    // check if it's local file
+    if (value.hasOwnProperty('fd')) {
+      fs.stat(value.path, function(err, stat) {
+        if (err) {
+          next(err);
+          return;
+        }
+
+        next(null, stat.size);
+      });
+
+    // or http response
+    } else if (value.hasOwnProperty('httpVersion')) {
+      next(null, +value.headers['content-length']);
+
+    // or request stream http://github.com/mikeal/request
+    } else if (value.hasOwnProperty('httpModule')) {
+      // wait till response come back
+      value.on('response', function(response) {
+        value.pause();
+        next(null, +response.headers['content-length']);
+      });
+      value.resume();
+
+    // something else
+    } else {
+      next('Unknown stream');
+    }
+  });
+};
+
+FormData.prototype._multiPartHeader = function(field, value) {
+  var boundary = this.getBoundary();
+  var header =
+    '--' + boundary + FormData.LINE_BREAK +
+    'Content-Disposition: form-data; name="' + field + '"';
+
+  // fs- and request- streams have path property
+  // TODO: Use request's response mime-type
+  if (value.path) {
+    header +=
+      '; filename="' + path.basename(value.path) + '"' + FormData.LINE_BREAK +
+      'Content-Type: ' + mime.lookup(value.path);
+
+  // http response has not
+  } else if (value.readable && value.hasOwnProperty('httpVersion')) {
+    header +=
+      '; filename="' + path.basename(value.client._httpMessage.path) + '"' + FormData.LINE_BREAK +
+      'Content-Type: ' + value.headers['content-type'];
+  }
+
+  header += FormData.LINE_BREAK + FormData.LINE_BREAK;
+  return header;
+};
+
+FormData.prototype._multiPartFooter = function(field, value) {
+  return function(next) {
+    var footer = FormData.LINE_BREAK;
+
+    var lastPart = (this._streams.length === 0);
+    if (lastPart) {
+      footer += this._lastBoundary();
+    }
+
+    next(footer);
+  }.bind(this);
+};
+
+FormData.prototype._lastBoundary = function() {
+  return '--' + this.getBoundary() + '--';
+};
+
+FormData.prototype.getHeaders = function(userHeaders) {
+  var formHeaders = {
+    'content-type': 'multipart/form-data; boundary=' + this.getBoundary()
+  };
+
+  for (var header in userHeaders) {
+    formHeaders[header.toLowerCase()] = userHeaders[header];
+  }
+
+  return formHeaders;
+}
+
+FormData.prototype.getCustomHeaders = function(contentType) {
+    contentType = contentType ? contentType : 'multipart/form-data';
+
+    var formHeaders = {
+        'content-type': contentType + '; boundary=' + this.getBoundary(),
+        'content-length': this.getLengthSync()
+    };
+
+    return formHeaders;
+}
+
+FormData.prototype.getBoundary = function() {
+  if (!this._boundary) {
+    this._generateBoundary();
+  }
+
+  return this._boundary;
+};
+
+FormData.prototype._generateBoundary = function() {
+  // This generates a 50 character boundary similar to those used by Firefox.
+  // They are optimized for boyer-moore parsing.
+  var boundary = '--------------------------';
+  for (var i = 0; i < 24; i++) {
+    boundary += Math.floor(Math.random() * 10).toString(16);
+  }
+
+  this._boundary = boundary;
+};
+
+FormData.prototype.getLengthSync = function() {
+    var knownLength = this._overheadLength + this._valueLength;
+
+    if (this._streams.length) {
+        knownLength += this._lastBoundary().length;
+    }
+
+    return knownLength;
+};
+
+FormData.prototype.getLength = function(cb) {
+  var knownLength = this._overheadLength + this._valueLength;
+
+  if (this._streams.length) {
+    knownLength += this._lastBoundary().length;
+  }
+
+  if (!this._lengthRetrievers.length) {
+    process.nextTick(cb.bind(this, null, knownLength));
+    return;
+  }
+
+  async.parallel(this._lengthRetrievers, function(err, values) {
+    if (err) {
+      cb(err);
+      return;
+    }
+
+    values.forEach(function(length) {
+      knownLength += length;
+    });
+
+    cb(null, knownLength);
+  });
+};
+
+FormData.prototype.submit = function(url, cb) {
+  this.getLength(function(err, length) {
+    var request
+      , parsedUrl = parseUrl(url)
+      , options = {
+          method: 'post',
+          port: parsedUrl.port || 80,
+          path: parsedUrl.pathname,
+          headers: this.getHeaders({'Content-Length': length}),
+          host: parsedUrl.hostname
+        };
+
+    if (parsedUrl.protocol == 'https:') {
+      // override default port
+      if (!parsedUrl.port) options.port = 443;
+      request = https.request(options);
+    } else {
+      request = http.request(options);
+    }
+
+    this.pipe(request);
+    if (cb) {
+      request.on('error', cb);
+      request.on('response', cb.bind(this, null));
+    }
+
+    return request;
+  }.bind(this));
+};
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node-form-data.sublime-project b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node-form-data.sublime-project
new file mode 100644 (file)
index 0000000..38100b8
--- /dev/null
@@ -0,0 +1,8 @@
+{
+       "folders":
+       [
+               {
+                       "path": "/Users/alexi/Dropbox/Projects/node-form-data"
+               }
+       ]
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node-form-data.sublime-workspace b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node-form-data.sublime-workspace
new file mode 100644 (file)
index 0000000..735990f
--- /dev/null
@@ -0,0 +1,508 @@
+{
+       "auto_complete":
+       {
+               "selected_items":
+               [
+                       [
+                               "back",
+                               "background-clip"
+                       ],
+                       [
+                               "di",
+                               "display"
+                       ],
+                       [
+                               "background-",
+                               "background-position"
+                       ],
+                       [
+                               "de",
+                               "defaults"
+                       ],
+                       [
+                               "no",
+                               "normal"
+                       ],
+                       [
+                               "line",
+                               "line-height"
+                       ]
+               ]
+       },
+       "buffers":
+       [
+               {
+                       "file": "test/integration/test-pipe.js",
+                       "settings":
+                       {
+                               "buffer_size": 3291,
+                               "line_ending": "Unix"
+                       }
+               },
+               {
+                       "file": "package.json",
+                       "settings":
+                       {
+                               "buffer_size": 671,
+                               "line_ending": "Unix"
+                       }
+               },
+               {
+                       "file": "lib/form_data.js",
+                       "settings":
+                       {
+                               "buffer_size": 6087,
+                               "line_ending": "Unix"
+                       }
+               },
+               {
+                       "file": "test/integration/test-submit.js",
+                       "settings":
+                       {
+                               "buffer_size": 3304,
+                               "line_ending": "Unix"
+                       }
+               },
+               {
+                       "file": "test/integration/test-http-response.js",
+                       "settings":
+                       {
+                               "buffer_size": 3109,
+                               "line_ending": "Unix"
+                       }
+               },
+               {
+                       "file": "Readme.md",
+                       "settings":
+                       {
+                               "buffer_size": 2039,
+                               "line_ending": "Unix"
+                       }
+               }
+       ],
+       "build_system": "",
+       "command_palette":
+       {
+               "height": 87.0,
+               "selected_items":
+               [
+                       [
+                               "Package Control: in",
+                               "Package Control: Install Package"
+                       ],
+                       [
+                               "Package Control: ins",
+                               "Package Control: Install Package"
+                       ],
+                       [
+                               "ins",
+                               "Package Control: Install Package"
+                       ],
+                       [
+                               "insta",
+                               "Package Control: Install Package"
+                       ]
+               ],
+               "width": 467.0
+       },
+       "console":
+       {
+               "height": 125.0
+       },
+       "distraction_free":
+       {
+               "menu_visible": true,
+               "show_minimap": false,
+               "show_open_files": false,
+               "show_tabs": false,
+               "side_bar_visible": false,
+               "status_bar_visible": false
+       },
+       "file_history":
+       [
+               "/Users/alexi/Dropbox/Projects/node-form-data/test/integration/test-http-respone.js",
+               "/Users/alexi/Dropbox/Projects/node-form-data/test/run.js",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/sftp-config-alt.json",
+               "/Users/alexi/Desktop/test/file.txt",
+               "/Users/alexi/Desktop/stuff/kodak/web.js",
+               "/Users/alexi/Desktop/test/test1.js",
+               "/Users/alexi/Desktop/test/spdy.js",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/bin/echo.js",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/static/test.html",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/bin/passthrough_stream.js",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/request/main.js",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/request/tests/test-pipes.js",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/static/a/main.js",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/flickr/lib/flickr.js",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/socket.io/lib/socket.io.js",
+               "/var/folders/xn/475pdrpd72n4s6gdh4y_c2dm0000gn/T/sublime-sftp-browse-1342313240/mapped/var/www/libereco.ia.gs/node_modules/oauth/lib/oauth.js",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/flickr/node_modules/oauth/lib/oauth.js",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/flickr/index.js",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/socket.io/index.js",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/sftp-config.json",
+               "/Users/alexi/Dropbox/Projects/libereco.ia.gs/public/index.html",
+               "/Users/alexi/Desktop/kodak/dns.js",
+               "/Users/alexi/Dropbox/Projects/500.ia.gs/htdocs/s/fonts.css",
+               "/Users/alexi/Dropbox/Projects/ia.gs/sftp-config.json",
+               "/Users/alexi/Downloads/fabric_plaid.png",
+               "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/Default/Global.sublime-settings",
+               "/Users/alexi/Dropbox/Projects/ia.gs/node_modules/director/lib/director/router.js",
+               "/Users/alexi/Dropbox/Projects/ia.gs/web/e/404.html",
+               "/Users/alexi/Dropbox/Projects/ia.gs/web/e/500.html",
+               "/Users/alexi/Dropbox/Projects/ia.gs/node_modules/director/lib/director/http/index.js",
+               "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/SFTP/SFTP.sublime-settings",
+               "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/SFTP/Default (OSX).sublime-keymap",
+               "/Users/alexi/Sites/new/sftp-config.json",
+               "/Users/alexi/Sites/new/polarbear.css",
+               "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/User/Base File.sublime-settings",
+               "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/Default/Base File.sublime-settings",
+               "/Users/alexi/Sites/new/include/Controllers/Home/HomepageController.php"
+       ],
+       "find":
+       {
+               "height": 35.0
+       },
+       "find_in_files":
+       {
+               "height": 0.0,
+               "where_history":
+               [
+                       ""
+               ]
+       },
+       "find_state":
+       {
+               "case_sensitive": false,
+               "find_history":
+               [
+                       "argument",
+                       "mikeal",
+                       "return;",
+                       "throw arguments[1]",
+                       "arguments[1]",
+                       "throw arguments",
+                       "throw arguments[1]",
+                       "path",
+                       "conso",
+                       "isStreamLike",
+                       "parseUrl",
+                       "stream",
+                       "node.js",
+                       "stream",
+                       "http://libereco.ia.gs/",
+                       "flickr_message_nopro",
+                       "auth:done",
+                       "con",
+                       "console",
+                       "photos",
+                       "isReadStream",
+                       "Buffer",
+                       "Bufer",
+                       "multipart",
+                       "sig",
+                       "api",
+                       "api_",
+                       "api_sig",
+                       "writeFile",
+                       "googledoodle.png",
+                       "attachment",
+                       "_write",
+                       "fs",
+                       "mime",
+                       "_putOrPost",
+                       "_performSecureRequest",
+                       "8034",
+                       "try",
+                       "paramsToQueryString",
+                       "_executeOAuthAPIRequest",
+                       "oauth_client",
+                       "_createClient",
+                       "authorization",
+                       "body",
+                       "_performSecureRequest",
+                       "query",
+                       "io.",
+                       ".listen",
+                       "io",
+                       "config",
+                       "set",
+                       "console",
+                       "'next'",
+                       "console",
+                       "_asyncEverySeries",
+                       "runlist",
+                       "function",
+                       "async",
+                       "local",
+                       "Find schools",
+                       "What's up"
+               ],
+               "highlight": true,
+               "in_selection": false,
+               "preserve_case": false,
+               "regex": false,
+               "replace_history":
+               [
+               ],
+               "reverse": false,
+               "show_context": true,
+               "use_buffer2": true,
+               "whole_word": false,
+               "wrap": true
+       },
+       "groups":
+       [
+               {
+                       "selected": 5,
+                       "sheets":
+                       [
+                               {
+                                       "buffer": 0,
+                                       "file": "test/integration/test-pipe.js",
+                                       "settings":
+                                       {
+                                               "buffer_size": 3291,
+                                               "regions":
+                                               {
+                                               },
+                                               "selection":
+                                               [
+                                                       [
+                                                               3213,
+                                                               3213
+                                                       ]
+                                               ],
+                                               "settings":
+                                               {
+                                                       "remote_loading": false,
+                                                       "synced": false,
+                                                       "syntax": "Packages/JavaScript/JavaScript.tmLanguage"
+                                               },
+                                               "translation.x": 0.0,
+                                               "translation.y": 914.0,
+                                               "zoom_level": 1.0
+                                       },
+                                       "type": "text"
+                               },
+                               {
+                                       "buffer": 1,
+                                       "file": "package.json",
+                                       "settings":
+                                       {
+                                               "buffer_size": 671,
+                                               "regions":
+                                               {
+                                               },
+                                               "selection":
+                                               [
+                                                       [
+                                                               542,
+                                                               542
+                                                       ]
+                                               ],
+                                               "settings":
+                                               {
+                                                       "remote_loading": false,
+                                                       "synced": false,
+                                                       "syntax": "Packages/JavaScript/JSON.tmLanguage"
+                                               },
+                                               "translation.x": 0.0,
+                                               "translation.y": 0.0,
+                                               "zoom_level": 1.0
+                                       },
+                                       "type": "text"
+                               },
+                               {
+                                       "buffer": 2,
+                                       "file": "lib/form_data.js",
+                                       "settings":
+                                       {
+                                               "buffer_size": 6087,
+                                               "regions":
+                                               {
+                                               },
+                                               "selection":
+                                               [
+                                                       [
+                                                               5918,
+                                                               5918
+                                                       ]
+                                               ],
+                                               "settings":
+                                               {
+                                                       "remote_loading": false,
+                                                       "synced": false,
+                                                       "syntax": "Packages/JavaScript/JavaScript.tmLanguage"
+                                               },
+                                               "translation.x": 0.0,
+                                               "translation.y": 2804.0,
+                                               "zoom_level": 1.0
+                                       },
+                                       "type": "text"
+                               },
+                               {
+                                       "buffer": 3,
+                                       "file": "test/integration/test-submit.js",
+                                       "settings":
+                                       {
+                                               "buffer_size": 3304,
+                                               "regions":
+                                               {
+                                               },
+                                               "selection":
+                                               [
+                                                       [
+                                                               3222,
+                                                               3222
+                                                       ]
+                                               ],
+                                               "settings":
+                                               {
+                                                       "remote_loading": false,
+                                                       "synced": false,
+                                                       "syntax": "Packages/JavaScript/JavaScript.tmLanguage"
+                                               },
+                                               "translation.x": 0.0,
+                                               "translation.y": 854.0,
+                                               "zoom_level": 1.0
+                                       },
+                                       "type": "text"
+                               },
+                               {
+                                       "buffer": 4,
+                                       "file": "test/integration/test-http-response.js",
+                                       "settings":
+                                       {
+                                               "buffer_size": 3109,
+                                               "regions":
+                                               {
+                                               },
+                                               "selection":
+                                               [
+                                                       [
+                                                               2156,
+                                                               2156
+                                                       ]
+                                               ],
+                                               "settings":
+                                               {
+                                                       "remote_loading": false,
+                                                       "synced": false,
+                                                       "syntax": "Packages/JavaScript/JavaScript.tmLanguage"
+                                               },
+                                               "translation.x": 0.0,
+                                               "translation.y": 0.0,
+                                               "zoom_level": 1.0
+                                       },
+                                       "type": "text"
+                               },
+                               {
+                                       "buffer": 5,
+                                       "file": "Readme.md",
+                                       "settings":
+                                       {
+                                               "buffer_size": 2039,
+                                               "regions":
+                                               {
+                                               },
+                                               "selection":
+                                               [
+                                                       [
+                                                               971,
+                                                               971
+                                                       ]
+                                               ],
+                                               "settings":
+                                               {
+                                                       "remote_loading": false,
+                                                       "synced": false,
+                                                       "syntax": "Packages/Markdown/Markdown.tmLanguage"
+                                               },
+                                               "translation.x": 0.0,
+                                               "translation.y": 539.0,
+                                               "zoom_level": 1.0
+                                       },
+                                       "type": "text"
+                               }
+                       ]
+               }
+       ],
+       "incremental_find":
+       {
+               "height": 0.0
+       },
+       "input":
+       {
+               "height": 31.0
+       },
+       "layout":
+       {
+               "cells":
+               [
+                       [
+                               0,
+                               0,
+                               1,
+                               1
+                       ]
+               ],
+               "cols":
+               [
+                       0.0,
+                       1.0
+               ],
+               "rows":
+               [
+                       0.0,
+                       1.0
+               ]
+       },
+       "menu_visible": true,
+       "output.sftp":
+       {
+               "height": 108.0
+       },
+       "replace":
+       {
+               "height": 0.0
+       },
+       "save_all_on_build": true,
+       "select_file":
+       {
+               "height": 0.0,
+               "selected_items":
+               [
+                       [
+                               "homepagecon",
+                               "include/Controllers/Home/HomepageController.php"
+                       ],
+                       [
+                               "polar",
+                               "polarbear.css"
+                       ],
+                       [
+                               "homepageco",
+                               "include/Controllers/Home/HomepageController.php"
+                       ],
+                       [
+                               "homepage.js",
+                               "include/js/application/homepage/homepage.js"
+                       ]
+               ],
+               "width": 0.0
+       },
+       "select_project":
+       {
+               "height": 0.0,
+               "selected_items":
+               [
+               ],
+               "width": 0.0
+       },
+       "show_minimap": true,
+       "show_open_files": true,
+       "show_tabs": true,
+       "side_bar_visible": true,
+       "side_bar_width": 250.0,
+       "status_bar_visible": true
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/.gitmodules b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/.gitmodules
new file mode 100644 (file)
index 0000000..a9aae98
--- /dev/null
@@ -0,0 +1,9 @@
+[submodule "deps/nodeunit"]
+       path = deps/nodeunit
+       url = git://github.com/caolan/nodeunit.git
+[submodule "deps/UglifyJS"]
+       path = deps/UglifyJS
+       url = https://github.com/mishoo/UglifyJS.git
+[submodule "deps/nodelint"]
+       path = deps/nodelint
+       url = https://github.com/tav/nodelint.git
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/LICENSE b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/LICENSE
new file mode 100644 (file)
index 0000000..b7f9d50
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2010 Caolan McMahon
+
+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.
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/Makefile b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/Makefile
new file mode 100644 (file)
index 0000000..00f07ea
--- /dev/null
@@ -0,0 +1,21 @@
+PACKAGE = asyncjs
+NODEJS = $(if $(shell test -f /usr/bin/nodejs && echo "true"),nodejs,node)
+
+BUILDDIR = dist
+
+all: build
+
+build: $(wildcard  lib/*.js)
+       mkdir -p $(BUILDDIR)
+       uglifyjs lib/async.js > $(BUILDDIR)/async.min.js
+
+test:
+       nodeunit test
+
+clean:
+       rm -rf $(BUILDDIR)
+
+lint:
+       nodelint --config nodelint.cfg lib/async.js
+
+.PHONY: test build all
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/README.md b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/README.md
new file mode 100644 (file)
index 0000000..039d942
--- /dev/null
@@ -0,0 +1,970 @@
+# Async.js
+
+Async is a utility module which provides straight-forward, powerful functions
+for working with asynchronous JavaScript. Although originally designed for
+use with [node.js](http://nodejs.org), it can also be used directly in the
+browser.
+
+Async provides around 20 functions that include the usual 'functional'
+suspects (map, reduce, filter, forEach…) as well as some common patterns
+for asynchronous flow control (parallel, series, waterfall…). All these
+functions assume you follow the node.js convention of providing a single
+callback as the last argument of your async function.
+
+
+## Quick Examples
+
+    async.map(['file1','file2','file3'], fs.stat, function(err, results){
+        // results is now an array of stats for each file
+    });
+
+    async.filter(['file1','file2','file3'], path.exists, function(results){
+        // results now equals an array of the existing files
+    });
+
+    async.parallel([
+        function(){ ... },
+        function(){ ... }
+    ], callback);
+
+    async.series([
+        function(){ ... },
+        function(){ ... }
+    ]);
+
+There are many more functions available so take a look at the docs below for a
+full list. This module aims to be comprehensive, so if you feel anything is
+missing please create a GitHub issue for it.
+
+
+## Download
+
+Releases are available for download from
+[GitHub](http://github.com/caolan/async/downloads).
+Alternatively, you can install using Node Package Manager (npm):
+
+    npm install async
+
+
+__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 17.5kb Uncompressed
+
+__Production:__ [async.min.js](https://github.com/caolan/async/raw/master/dist/async.min.js) - 1.7kb Packed and Gzipped
+
+
+## In the Browser
+
+So far its been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage:
+
+    <script type="text/javascript" src="async.js"></script>
+    <script type="text/javascript">
+
+        async.map(data, asyncProcess, function(err, results){
+            alert(results);
+        });
+
+    </script>
+
+
+## Documentation
+
+### Collections
+
+* [forEach](#forEach)
+* [map](#map)
+* [filter](#filter)
+* [reject](#reject)
+* [reduce](#reduce)
+* [detect](#detect)
+* [sortBy](#sortBy)
+* [some](#some)
+* [every](#every)
+* [concat](#concat)
+
+### Flow Control
+
+* [series](#series)
+* [parallel](#parallel)
+* [whilst](#whilst)
+* [until](#until)
+* [waterfall](#waterfall)
+* [queue](#queue)
+* [auto](#auto)
+* [iterator](#iterator)
+* [apply](#apply)
+* [nextTick](#nextTick)
+
+### Utils
+
+* [memoize](#memoize)
+* [log](#log)
+* [dir](#dir)
+* [noConflict](#noConflict)
+
+
+## Collections
+
+<a name="forEach" />
+### forEach(arr, iterator, callback)
+
+Applies an iterator function to each item in an array, in parallel.
+The iterator is called with an item from the list and a callback for when it
+has finished. If the iterator passes an error to this callback, the main
+callback for the forEach function is immediately called with the error.
+
+Note, that since this function applies the iterator to each item in parallel
+there is no guarantee that the iterator functions will complete in order.
+
+__Arguments__
+
+* arr - An array to iterate over.
+* iterator(item, callback) - A function to apply to each item in the array.
+  The iterator is passed a callback which must be called once it has completed.
+* callback(err) - A callback which is called after all the iterator functions
+  have finished, or an error has occurred.
+
+__Example__
+
+    // assuming openFiles is an array of file names and saveFile is a function
+    // to save the modified contents of that file:
+
+    async.forEach(openFiles, saveFile, function(err){
+        // if any of the saves produced an error, err would equal that error
+    });
+
+---------------------------------------
+
+<a name="forEachSeries" />
+### forEachSeries(arr, iterator, callback)
+
+The same as forEach only the iterator is applied to each item in the array in
+series. The next iterator is only called once the current one has completed
+processing. This means the iterator functions will complete in order.
+
+
+---------------------------------------
+
+<a name="map" />
+### map(arr, iterator, callback)
+
+Produces a new array of values by mapping each value in the given array through
+the iterator function. The iterator is called with an item from the array and a
+callback for when it has finished processing. The callback takes 2 arguments, 
+an error and the transformed item from the array. If the iterator passes an
+error to this callback, the main callback for the map function is immediately
+called with the error.
+
+Note, that since this function applies the iterator to each item in parallel
+there is no guarantee that the iterator functions will complete in order, however
+the results array will be in the same order as the original array.
+
+__Arguments__
+
+* arr - An array to iterate over.
+* iterator(item, callback) - A function to apply to each item in the array.
+  The iterator is passed a callback which must be called once it has completed
+  with an error (which can be null) and a transformed item.
+* callback(err, results) - A callback which is called after all the iterator
+  functions have finished, or an error has occurred. Results is an array of the
+  transformed items from the original array.
+
+__Example__
+
+    async.map(['file1','file2','file3'], fs.stat, function(err, results){
+        // results is now an array of stats for each file
+    });
+
+---------------------------------------
+
+<a name="mapSeries" />
+### mapSeries(arr, iterator, callback)
+
+The same as map only the iterator is applied to each item in the array in
+series. The next iterator is only called once the current one has completed
+processing. The results array will be in the same order as the original.
+
+
+---------------------------------------
+
+<a name="filter" />
+### filter(arr, iterator, callback)
+
+__Alias:__ select
+
+Returns a new array of all the values which pass an async truth test.
+_The callback for each iterator call only accepts a single argument of true or
+false, it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like path.exists. This operation is
+performed in parallel, but the results array will be in the same order as the
+original.
+
+__Arguments__
+
+* arr - An array to iterate over.
+* iterator(item, callback) - A truth test to apply to each item in the array.
+  The iterator is passed a callback which must be called once it has completed.
+* callback(results) - A callback which is called after all the iterator
+  functions have finished.
+
+__Example__
+
+    async.filter(['file1','file2','file3'], path.exists, function(results){
+        // results now equals an array of the existing files
+    });
+
+---------------------------------------
+
+<a name="filterSeries" />
+### filterSeries(arr, iterator, callback)
+
+__alias:__ selectSeries
+
+The same as filter only the iterator is applied to each item in the array in
+series. The next iterator is only called once the current one has completed
+processing. The results array will be in the same order as the original.
+
+---------------------------------------
+
+<a name="reject" />
+### reject(arr, iterator, callback)
+
+The opposite of filter. Removes values that pass an async truth test.
+
+---------------------------------------
+
+<a name="rejectSeries" />
+### rejectSeries(arr, iterator, callback)
+
+The same as filter, only the iterator is applied to each item in the array
+in series.
+
+
+---------------------------------------
+
+<a name="reduce" />
+### reduce(arr, memo, iterator, callback)
+
+__aliases:__ inject, foldl
+
+Reduces a list of values into a single value using an async iterator to return
+each successive step. Memo is the initial state of the reduction. This
+function only operates in series. For performance reasons, it may make sense to
+split a call to this function into a parallel map, then use the normal
+Array.prototype.reduce on the results. This function is for situations where
+each step in the reduction needs to be async, if you can get the data before
+reducing it then its probably a good idea to do so.
+
+__Arguments__
+
+* arr - An array to iterate over.
+* memo - The initial state of the reduction.
+* iterator(memo, item, callback) - A function applied to each item in the
+  array to produce the next step in the reduction. The iterator is passed a
+  callback which accepts an optional error as its first argument, and the state
+  of the reduction as the second. If an error is passed to the callback, the
+  reduction is stopped and the main callback is immediately called with the
+  error.
+* callback(err, result) - A callback which is called after all the iterator
+  functions have finished. Result is the reduced value.
+
+__Example__
+
+    async.reduce([1,2,3], 0, function(memo, item, callback){
+        // pointless async:
+        process.nextTick(function(){
+            callback(null, memo + item)
+        });
+    }, function(err, result){
+        // result is now equal to the last value of memo, which is 6
+    });
+
+---------------------------------------
+
+<a name="reduceRight" />
+### reduceRight(arr, memo, iterator, callback)
+
+__Alias:__ foldr
+
+Same as reduce, only operates on the items in the array in reverse order.
+
+
+---------------------------------------
+
+<a name="detect" />
+### detect(arr, iterator, callback)
+
+Returns the first value in a list that passes an async truth test. The
+iterator is applied in parallel, meaning the first iterator to return true will
+fire the detect callback with that result. That means the result might not be
+the first item in the original array (in terms of order) that passes the test.
+
+If order within the original array is important then look at detectSeries.
+
+__Arguments__
+
+* arr - An array to iterate over.
+* iterator(item, callback) - A truth test to apply to each item in the array.
+  The iterator is passed a callback which must be called once it has completed.
+* callback(result) - A callback which is called as soon as any iterator returns
+  true, or after all the iterator functions have finished. Result will be
+  the first item in the array that passes the truth test (iterator) or the
+  value undefined if none passed.
+
+__Example__
+
+    async.detect(['file1','file2','file3'], path.exists, function(result){
+        // result now equals the first file in the list that exists
+    });
+
+---------------------------------------
+
+<a name="detectSeries" />
+### detectSeries(arr, iterator, callback)
+
+The same as detect, only the iterator is applied to each item in the array
+in series. This means the result is always the first in the original array (in
+terms of array order) that passes the truth test.
+
+
+---------------------------------------
+
+<a name="sortBy" />
+### sortBy(arr, iterator, callback)
+
+Sorts a list by the results of running each value through an async iterator.
+
+__Arguments__
+
+* arr - An array to iterate over.
+* iterator(item, callback) - A function to apply to each item in the array.
+  The iterator is passed a callback which must be called once it has completed
+  with an error (which can be null) and a value to use as the sort criteria.
+* callback(err, results) - A callback which is called after all the iterator
+  functions have finished, or an error has occurred. Results is the items from
+  the original array sorted by the values returned by the iterator calls.
+
+__Example__
+
+    async.sortBy(['file1','file2','file3'], function(file, callback){
+        fs.stat(file, function(err, stats){
+            callback(err, stats.mtime);
+        });
+    }, function(err, results){
+        // results is now the original array of files sorted by
+        // modified date
+    });
+
+
+---------------------------------------
+
+<a name="some" />
+### some(arr, iterator, callback)
+
+__Alias:__ any
+
+Returns true if at least one element in the array satisfies an async test.
+_The callback for each iterator call only accepts a single argument of true or
+false, it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like path.exists. Once any iterator
+call returns true, the main callback is immediately called.
+
+__Arguments__
+
+* arr - An array to iterate over.
+* iterator(item, callback) - A truth test to apply to each item in the array.
+  The iterator is passed a callback which must be called once it has completed.
+* callback(result) - A callback which is called as soon as any iterator returns
+  true, or after all the iterator functions have finished. Result will be
+  either true or false depending on the values of the async tests.
+
+__Example__
+
+    async.some(['file1','file2','file3'], path.exists, function(result){
+        // if result is true then at least one of the files exists
+    });
+
+---------------------------------------
+
+<a name="every" />
+### every(arr, iterator, callback)
+
+__Alias:__ all
+
+Returns true if every element in the array satisfies an async test.
+_The callback for each iterator call only accepts a single argument of true or
+false, it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like path.exists.
+
+__Arguments__
+
+* arr - An array to iterate over.
+* iterator(item, callback) - A truth test to apply to each item in the array.
+  The iterator is passed a callback which must be called once it has completed.
+* callback(result) - A callback which is called after all the iterator
+  functions have finished. Result will be either true or false depending on
+  the values of the async tests.
+
+__Example__
+
+    async.every(['file1','file2','file3'], path.exists, function(result){
+        // if result is true then every file exists
+    });
+
+---------------------------------------
+
+<a name="concat" />
+### concat(arr, iterator, callback)
+
+Applies an iterator to each item in a list, concatenating the results. Returns the
+concatenated list. The iterators are called in parallel, and the results are
+concatenated as they return. There is no guarantee that the results array will
+be returned in the original order of the arguments passed to the iterator function.
+
+__Arguments__
+
+* arr - An array to iterate over
+* iterator(item, callback) - A function to apply to each item in the array.
+  The iterator is passed a callback which must be called once it has completed
+  with an error (which can be null) and an array of results.
+* callback(err, results) - A callback which is called after all the iterator
+  functions have finished, or an error has occurred. Results is an array containing
+  the concatenated results of the iterator function.
+
+__Example__
+
+    async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){
+        // files is now a list of filenames that exist in the 3 directories
+    });
+
+---------------------------------------
+
+<a name="concatSeries" />
+### concatSeries(arr, iterator, callback)
+
+Same as async.concat, but executes in series instead of parallel.
+
+
+## Flow Control
+
+<a name="series" />
+### series(tasks, [callback])
+
+Run an array of functions in series, each one running once the previous
+function has completed. If any functions in the series pass an error to its
+callback, no more functions are run and the callback for the series is
+immediately called with the value of the error. Once the tasks have completed,
+the results are passed to the final callback as an array.
+
+It is also possible to use an object instead of an array. Each property will be
+run as a function and the results will be passed to the final callback as an object
+instead of an array. This can be a more readable way of handling results from
+async.series.
+
+
+__Arguments__
+
+* tasks - An array or object containing functions to run, each function is passed
+  a callback it must call on completion.
+* callback(err, results) - An optional callback to run once all the functions
+  have completed. This function gets an array of all the arguments passed to
+  the callbacks used in the array.
+
+__Example__
+
+    async.series([
+        function(callback){
+            // do some stuff ...
+            callback(null, 'one');
+        },
+        function(callback){
+            // do some more stuff ...
+            callback(null, 'two');
+        },
+    ],
+    // optional callback
+    function(err, results){
+        // results is now equal to ['one', 'two']
+    });
+
+
+    // an example using an object instead of an array
+    async.series({
+        one: function(callback){
+            setTimeout(function(){
+                callback(null, 1);
+            }, 200);
+        },
+        two: function(callback){
+            setTimeout(function(){
+                callback(null, 2);
+            }, 100);
+        },
+    },
+    function(err, results) {
+        // results is now equals to: {one: 1, two: 2}
+    });
+
+
+---------------------------------------
+
+<a name="parallel" />
+### parallel(tasks, [callback])
+
+Run an array of functions in parallel, without waiting until the previous
+function has completed. If any of the functions pass an error to its
+callback, the main callback is immediately called with the value of the error.
+Once the tasks have completed, the results are passed to the final callback as an
+array.
+
+It is also possible to use an object instead of an array. Each property will be
+run as a function and the results will be passed to the final callback as an object
+instead of an array. This can be a more readable way of handling results from
+async.parallel.
+
+
+__Arguments__
+
+* tasks - An array or object containing functions to run, each function is passed a
+  callback it must call on completion.
+* callback(err, results) - An optional callback to run once all the functions
+  have completed. This function gets an array of all the arguments passed to
+  the callbacks used in the array.
+
+__Example__
+
+    async.parallel([
+        function(callback){
+            setTimeout(function(){
+                callback(null, 'one');
+            }, 200);
+        },
+        function(callback){
+            setTimeout(function(){
+                callback(null, 'two');
+            }, 100);
+        },
+    ],
+    // optional callback
+    function(err, results){
+        // in this case, the results array will equal ['two','one']
+        // because the functions were run in parallel and the second
+        // function had a shorter timeout before calling the callback.
+    });
+
+
+    // an example using an object instead of an array
+    async.parallel({
+        one: function(callback){
+            setTimeout(function(){
+                callback(null, 1);
+            }, 200);
+        },
+        two: function(callback){
+            setTimeout(function(){
+                callback(null, 2);
+            }, 100);
+        },
+    },
+    function(err, results) {
+        // results is now equals to: {one: 1, two: 2}
+    });
+
+
+---------------------------------------
+
+<a name="whilst" />
+### whilst(test, fn, callback)
+
+Repeatedly call fn, while test returns true. Calls the callback when stopped,
+or an error occurs.
+
+__Arguments__
+
+* test() - synchronous truth test to perform before each execution of fn.
+* fn(callback) - A function to call each time the test passes. The function is
+  passed a callback which must be called once it has completed with an optional
+  error as the first argument.
+* callback(err) - A callback which is called after the test fails and repeated
+  execution of fn has stopped.
+
+__Example__
+
+    var count = 0;
+
+    async.whilst(
+        function () { return count < 5; },
+        function (callback) {
+            count++;
+            setTimeout(callback, 1000);
+        },
+        function (err) {
+            // 5 seconds have passed
+        }
+    });
+
+
+---------------------------------------
+
+<a name="until" />
+### until(test, fn, callback)
+
+Repeatedly call fn, until test returns true. Calls the callback when stopped,
+or an error occurs.
+
+The inverse of async.whilst.
+
+
+---------------------------------------
+
+<a name="waterfall" />
+### waterfall(tasks, [callback])
+
+Runs an array of functions in series, each passing their results to the next in
+the array. However, if any of the functions pass an error to the callback, the
+next function is not executed and the main callback is immediately called with
+the error.
+
+__Arguments__
+
+* tasks - An array of functions to run, each function is passed a callback it
+  must call on completion.
+* callback(err) - An optional callback to run once all the functions have
+  completed. This function gets passed any error that may have occurred.
+
+__Example__
+
+    async.waterfall([
+        function(callback){
+            callback(null, 'one', 'two');
+        },
+        function(arg1, arg2, callback){
+            callback(null, 'three');
+        },
+        function(arg1, callback){
+            // arg1 now equals 'three'
+            callback(null, 'done');
+        }
+    ]);
+
+
+---------------------------------------
+
+<a name="queue" />
+### queue(worker, concurrency)
+
+Creates a queue object with the specified concurrency. Tasks added to the
+queue will be processed in parallel (up to the concurrency limit). If all
+workers are in progress, the task is queued until one is available. Once
+a worker has completed a task, the task's callback is called.
+
+__Arguments__
+
+* worker(task, callback) - An asynchronous function for processing a queued
+  task.
+* concurrency - An integer for determining how many worker functions should be
+  run in parallel.
+
+__Queue objects__
+
+The queue object returned by this function has the following properties and
+methods:
+
+* length() - a function returning the number of items waiting to be processed.
+* concurrency - an integer for determining how many worker functions should be
+  run in parallel. This property can be changed after a queue is created to
+  alter the concurrency on-the-fly.
+* push(task, [callback]) - add a new task to the queue, the callback is called
+  once the worker has finished processing the task.
+* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued
+* empty - a callback that is called when the last item from the queue is given to a worker
+* drain - a callback that is called when the last item from the queue has returned from the worker
+
+__Example__
+
+    // create a queue object with concurrency 2
+
+    var q = async.queue(function (task, callback) {
+        console.log('hello ' + task.name).
+        callback();
+    }, 2);
+
+
+    // assign a callback
+    q.drain = function() {
+        console.log('all items have been processed');
+    }
+
+    // add some items to the queue
+
+    q.push({name: 'foo'}, function (err) {
+        console.log('finished processing foo');
+    });
+    q.push({name: 'bar'}, function (err) {
+        console.log('finished processing bar');
+    });
+
+
+---------------------------------------
+
+<a name="auto" />
+### auto(tasks, [callback])
+
+Determines the best order for running functions based on their requirements.
+Each function can optionally depend on other functions being completed first,
+and each function is run as soon as its requirements are satisfied. If any of
+the functions pass and error to their callback, that function will not complete
+(so any other functions depending on it will not run) and the main callback
+will be called immediately with the error.
+
+__Arguments__
+
+* tasks - An object literal containing named functions or an array of
+  requirements, with the function itself the last item in the array. The key
+  used for each function or array is used when specifying requirements. The
+  syntax is easier to understand by looking at the example.
+* callback(err) - An optional callback which is called when all the tasks have
+  been completed. The callback may receive an error as an argument.
+
+__Example__
+
+    async.auto({
+        get_data: function(callback){
+            // async code to get some data
+        },
+        make_folder: function(callback){
+            // async code to create a directory to store a file in
+            // this is run at the same time as getting the data
+        },
+        write_file: ['get_data', 'make_folder', function(callback){
+            // once there is some data and the directory exists,
+            // write the data to a file in the directory
+        }],
+        email_link: ['write_file', function(callback){
+            // once the file is written let's email a link to it...
+        }]
+    });
+
+This is a fairly trivial example, but to do this using the basic parallel and
+series functions would look like this:
+
+    async.parallel([
+        function(callback){
+            // async code to get some data
+        },
+        function(callback){
+            // async code to create a directory to store a file in
+            // this is run at the same time as getting the data
+        }
+    ],
+    function(results){
+        async.series([
+            function(callback){
+                // once there is some data and the directory exists,
+                // write the data to a file in the directory
+            },
+            email_link: ['write_file', function(callback){
+                // once the file is written let's email a link to it...
+            }
+        ]);
+    });
+
+For a complicated series of async tasks using the auto function makes adding
+new tasks much easier and makes the code more readable. 
+
+
+---------------------------------------
+
+<a name="iterator" />
+### iterator(tasks)
+
+Creates an iterator function which calls the next function in the array,
+returning a continuation to call the next one after that. Its also possible to
+'peek' the next iterator by doing iterator.next().
+
+This function is used internally by the async module but can be useful when
+you want to manually control the flow of functions in series.
+
+__Arguments__
+
+* tasks - An array of functions to run, each function is passed a callback it
+  must call on completion.
+
+__Example__
+
+    var iterator = async.iterator([
+        function(){ sys.p('one'); },
+        function(){ sys.p('two'); },
+        function(){ sys.p('three'); }
+    ]);
+
+    node> var iterator2 = iterator();
+    'one'
+    node> var iterator3 = iterator2();
+    'two'
+    node> iterator3();
+    'three'
+    node> var nextfn = iterator2.next();
+    node> nextfn();
+    'three'
+
+
+---------------------------------------
+
+<a name="apply" />
+### apply(function, arguments..)
+
+Creates a continuation function with some arguments already applied, a useful
+shorthand when combined with other flow control functions. Any arguments
+passed to the returned function are added to the arguments originally passed
+to apply.
+
+__Arguments__
+
+* function - The function you want to eventually apply all arguments to.
+* arguments... - Any number of arguments to automatically apply when the
+  continuation is called.
+
+__Example__
+
+    // using apply
+
+    async.parallel([
+        async.apply(fs.writeFile, 'testfile1', 'test1'),
+        async.apply(fs.writeFile, 'testfile2', 'test2'),
+    ]);
+
+
+    // the same process without using apply
+
+    async.parallel([
+        function(callback){
+            fs.writeFile('testfile1', 'test1', callback);
+        },
+        function(callback){
+            fs.writeFile('testfile2', 'test2', callback);
+        },
+    ]);
+
+It's possible to pass any number of additional arguments when calling the
+continuation:
+
+    node> var fn = async.apply(sys.puts, 'one');
+    node> fn('two', 'three');
+    one
+    two
+    three
+
+---------------------------------------
+
+<a name="nextTick" />
+### nextTick(callback)
+
+Calls the callback on a later loop around the event loop. In node.js this just
+calls process.nextTick, in the browser it falls back to setTimeout(callback, 0),
+which means other higher priority events may precede the execution of the callback.
+
+This is used internally for browser-compatibility purposes.
+
+__Arguments__
+
+* callback - The function to call on a later loop around the event loop.
+
+__Example__
+
+    var call_order = [];
+    async.nextTick(function(){
+        call_order.push('two');
+        // call_order now equals ['one','two]
+    });
+    call_order.push('one')
+
+
+## Utils
+
+<a name="memoize" />
+### memoize(fn, [hasher])
+
+Caches the results of an async function. When creating a hash to store function
+results against, the callback is omitted from the hash and an optional hash
+function can be used.
+
+__Arguments__
+
+* fn - the function you to proxy and cache results from.
+* hasher - an optional function for generating a custom hash for storing
+  results, it has all the arguments applied to it apart from the callback, and
+  must be synchronous.
+
+__Example__
+
+    var slow_fn = function (name, callback) {
+        // do something
+        callback(null, result);
+    };
+    var fn = async.memoize(slow_fn);
+
+    // fn can now be used as if it were slow_fn
+    fn('some name', function () {
+        // callback
+    });
+
+
+<a name="log" />
+### log(function, arguments)
+
+Logs the result of an async function to the console. Only works in node.js or
+in browsers that support console.log and console.error (such as FF and Chrome).
+If multiple arguments are returned from the async function, console.log is
+called on each argument in order.
+
+__Arguments__
+
+* function - The function you want to eventually apply all arguments to.
+* arguments... - Any number of arguments to apply to the function.
+
+__Example__
+
+    var hello = function(name, callback){
+        setTimeout(function(){
+            callback(null, 'hello ' + name);
+        }, 1000);
+    };
+
+    node> async.log(hello, 'world');
+    'hello world'
+
+
+---------------------------------------
+
+<a name="dir" />
+### dir(function, arguments)
+
+Logs the result of an async function to the console using console.dir to
+display the properties of the resulting object. Only works in node.js or
+in browsers that support console.dir and console.error (such as FF and Chrome).
+If multiple arguments are returned from the async function, console.dir is
+called on each argument in order.
+
+__Arguments__
+
+* function - The function you want to eventually apply all arguments to.
+* arguments... - Any number of arguments to apply to the function.
+
+__Example__
+
+    var hello = function(name, callback){
+        setTimeout(function(){
+            callback(null, {hello: name});
+        }, 1000);
+    };
+
+    node> async.dir(hello, 'world');
+    {hello: 'world'}
+
+
+---------------------------------------
+
+<a name="noConflict" />
+### noConflict()
+
+Changes the value of async back to its original value, returning a reference to the
+async object.
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/async.min.js.gzip b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/async.min.js.gzip
new file mode 100644 (file)
index 0000000..e1c3294
Binary files /dev/null and b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/async.min.js.gzip differ
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.css b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.css
new file mode 100644 (file)
index 0000000..274434a
--- /dev/null
@@ -0,0 +1,70 @@
+/*!
+ * Styles taken from qunit.css
+ */
+
+h1#nodeunit-header, h1.nodeunit-header {
+    padding: 15px;
+    font-size: large;
+    background-color: #06b;
+    color: white;
+    font-family: 'trebuchet ms', verdana, arial;
+    margin: 0;
+}
+
+h1#nodeunit-header a {
+    color: white;
+}
+
+h2#nodeunit-banner {
+    height: 2em;
+    border-bottom: 1px solid white;
+    background-color: #eee;
+    margin: 0;
+    font-family: 'trebuchet ms', verdana, arial;
+}
+h2#nodeunit-banner.pass {
+    background-color: green;
+}
+h2#nodeunit-banner.fail {
+    background-color: red;
+}
+
+h2#nodeunit-userAgent, h2.nodeunit-userAgent {
+    padding: 10px;
+    background-color: #eee;
+    color: black;
+    margin: 0;
+    font-size: small;
+    font-weight: normal;
+    font-family: 'trebuchet ms', verdana, arial;
+    font-size: 10pt;
+}
+
+div#nodeunit-testrunner-toolbar {
+    background: #eee;
+    border-top: 1px solid black;
+    padding: 10px;
+    font-family: 'trebuchet ms', verdana, arial;
+    margin: 0;
+    font-size: 10pt;
+}
+
+ol#nodeunit-tests {
+    font-family: 'trebuchet ms', verdana, arial;
+    font-size: 10pt;
+}
+ol#nodeunit-tests li strong {
+    cursor:pointer;
+}
+ol#nodeunit-tests .pass {
+    color: green;
+} 
+ol#nodeunit-tests .fail {
+    color: red;
+} 
+
+p#nodeunit-testresult {
+    margin-left: 1em;
+    font-size: 10pt;
+    font-family: 'trebuchet ms', verdana, arial;
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.js
new file mode 100644 (file)
index 0000000..5957184
--- /dev/null
@@ -0,0 +1,1966 @@
+/*!
+ * Nodeunit
+ * https://github.com/caolan/nodeunit
+ * Copyright (c) 2010 Caolan McMahon
+ * MIT Licensed
+ *
+ * json2.js
+ * http://www.JSON.org/json2.js
+ * Public Domain.
+ * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+ */
+nodeunit = (function(){
+/*
+    http://www.JSON.org/json2.js
+    2010-11-17
+
+    Public Domain.
+
+    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+    See http://www.JSON.org/js.html
+
+
+    This code should be minified before deployment.
+    See http://javascript.crockford.com/jsmin.html
+
+    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+    NOT CONTROL.
+
+
+    This file creates a global JSON object containing two methods: stringify
+    and parse.
+
+        JSON.stringify(value, replacer, space)
+            value       any JavaScript value, usually an object or array.
+
+            replacer    an optional parameter that determines how object
+                        values are stringified for objects. It can be a
+                        function or an array of strings.
+
+            space       an optional parameter that specifies the indentation
+                        of nested structures. If it is omitted, the text will
+                        be packed without extra whitespace. If it is a number,
+                        it will specify the number of spaces to indent at each
+                        level. If it is a string (such as '\t' or '&nbsp;'),
+                        it contains the characters used to indent at each level.
+
+            This method produces a JSON text from a JavaScript value.
+
+            When an object value is found, if the object contains a toJSON
+            method, its toJSON method will be called and the result will be
+            stringified. A toJSON method does not serialize: it returns the
+            value represented by the name/value pair that should be serialized,
+            or undefined if nothing should be serialized. The toJSON method
+            will be passed the key associated with the value, and this will be
+            bound to the value
+
+            For example, this would serialize Dates as ISO strings.
+
+                Date.prototype.toJSON = function (key) {
+                    function f(n) {
+                        // Format integers to have at least two digits.
+                        return n < 10 ? '0' + n : n;
+                    }
+
+                    return this.getUTCFullYear()   + '-' +
+                         f(this.getUTCMonth() + 1) + '-' +
+                         f(this.getUTCDate())      + 'T' +
+                         f(this.getUTCHours())     + ':' +
+                         f(this.getUTCMinutes())   + ':' +
+                         f(this.getUTCSeconds())   + 'Z';
+                };
+
+            You can provide an optional replacer method. It will be passed the
+            key and value of each member, with this bound to the containing
+            object. The value that is returned from your method will be
+            serialized. If your method returns undefined, then the member will
+            be excluded from the serialization.
+
+            If the replacer parameter is an array of strings, then it will be
+            used to select the members to be serialized. It filters the results
+            such that only members with keys listed in the replacer array are
+            stringified.
+
+            Values that do not have JSON representations, such as undefined or
+            functions, will not be serialized. Such values in objects will be
+            dropped; in arrays they will be replaced with null. You can use
+            a replacer function to replace those with JSON values.
+            JSON.stringify(undefined) returns undefined.
+
+            The optional space parameter produces a stringification of the
+            value that is filled with line breaks and indentation to make it
+            easier to read.
+
+            If the space parameter is a non-empty string, then that string will
+            be used for indentation. If the space parameter is a number, then
+            the indentation will be that many spaces.
+
+            Example:
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}]);
+            // text is '["e",{"pluribus":"unum"}]'
+
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
+            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+            text = JSON.stringify([new Date()], function (key, value) {
+                return this[key] instanceof Date ?
+                    'Date(' + this[key] + ')' : value;
+            });
+            // text is '["Date(---current time---)"]'
+
+
+        JSON.parse(text, reviver)
+            This method parses a JSON text to produce an object or array.
+            It can throw a SyntaxError exception.
+
+            The optional reviver parameter is a function that can filter and
+            transform the results. It receives each of the keys and values,
+            and its return value is used instead of the original value.
+            If it returns what it received, then the structure is not modified.
+            If it returns undefined then the member is deleted.
+
+            Example:
+
+            // Parse the text. Values that look like ISO date strings will
+            // be converted to Date objects.
+
+            myData = JSON.parse(text, function (key, value) {
+                var a;
+                if (typeof value === 'string') {
+                    a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+                    if (a) {
+                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+                            +a[5], +a[6]));
+                    }
+                }
+                return value;
+            });
+
+            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+                var d;
+                if (typeof value === 'string' &&
+                        value.slice(0, 5) === 'Date(' &&
+                        value.slice(-1) === ')') {
+                    d = new Date(value.slice(5, -1));
+                    if (d) {
+                        return d;
+                    }
+                }
+                return value;
+            });
+
+
+    This is a reference implementation. You are free to copy, modify, or
+    redistribute.
+*/
+
+/*jslint evil: true, strict: false, regexp: false */
+
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
+    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+if (!this.JSON) {
+    this.JSON = {};
+}
+
+(function () {
+    "use strict";
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10 ? '0' + n : n;
+    }
+
+    if (typeof Date.prototype.toJSON !== 'function') {
+
+        Date.prototype.toJSON = function (key) {
+
+            return isFinite(this.valueOf()) ?
+                   this.getUTCFullYear()   + '-' +
+                 f(this.getUTCMonth() + 1) + '-' +
+                 f(this.getUTCDate())      + 'T' +
+                 f(this.getUTCHours())     + ':' +
+                 f(this.getUTCMinutes())   + ':' +
+                 f(this.getUTCSeconds())   + 'Z' : null;
+        };
+
+        String.prototype.toJSON =
+        Number.prototype.toJSON =
+        Boolean.prototype.toJSON = function (key) {
+            return this.valueOf();
+        };
+    }
+
+    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        gap,
+        indent,
+        meta = {    // table of character substitutions
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '\\': '\\\\'
+        },
+        rep;
+
+
+    function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+        escapable.lastIndex = 0;
+        return escapable.test(string) ?
+            '"' + string.replace(escapable, function (a) {
+                var c = meta[a];
+                return typeof c === 'string' ? c :
+                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+            }) + '"' :
+            '"' + string + '"';
+    }
+
+
+    function str(key, holder) {
+
+// Produce a string from holder[key].
+
+        var i,          // The loop counter.
+            k,          // The member key.
+            v,          // The member value.
+            length,
+            mind = gap,
+            partial,
+            value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+        if (value && typeof value === 'object' &&
+                typeof value.toJSON === 'function') {
+            value = value.toJSON(key);
+        }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+        if (typeof rep === 'function') {
+            value = rep.call(holder, key, value);
+        }
+
+// What happens next depends on the value's type.
+
+        switch (typeof value) {
+        case 'string':
+            return quote(value);
+
+        case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+            return isFinite(value) ? String(value) : 'null';
+
+        case 'boolean':
+        case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+            return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+        case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+            if (!value) {
+                return 'null';
+            }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+            gap += indent;
+            partial = [];
+
+// Is the value an array?
+
+            if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+                v = partial.length === 0 ? '[]' :
+                    gap ? '[\n' + gap +
+                            partial.join(',\n' + gap) + '\n' +
+                                mind + ']' :
+                          '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    k = rep[i];
+                    if (typeof k === 'string') {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+                for (k in value) {
+                    if (Object.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+            v = partial.length === 0 ? '{}' :
+                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+                        mind + '}' : '{' + partial.join(',') + '}';
+            gap = mind;
+            return v;
+        }
+    }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+    if (typeof JSON.stringify !== 'function') {
+        JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+            var i;
+            gap = '';
+            indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+            if (typeof space === 'number') {
+                for (i = 0; i < space; i += 1) {
+                    indent += ' ';
+                }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+            } else if (typeof space === 'string') {
+                indent = space;
+            }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+            rep = replacer;
+            if (replacer && typeof replacer !== 'function' &&
+                    (typeof replacer !== 'object' ||
+                     typeof replacer.length !== 'number')) {
+                throw new Error('JSON.stringify');
+            }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+            return str('', {'': value});
+        };
+    }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+    if (typeof JSON.parse !== 'function') {
+        JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+            var j;
+
+            function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+                var k, v, value = holder[key];
+                if (value && typeof value === 'object') {
+                    for (k in value) {
+                        if (Object.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            text = String(text);
+            cx.lastIndex = 0;
+            if (cx.test(text)) {
+                text = text.replace(cx, function (a) {
+                    return '\\u' +
+                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+            if (/^[\],:{}\s]*$/
+.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
+.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
+.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+                j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+                return typeof reviver === 'function' ?
+                    walk({'': j}, '') : j;
+            }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+            throw new SyntaxError('JSON.parse');
+        };
+    }
+}());
+var assert = this.assert = {};
+var types = {};
+var core = {};
+var nodeunit = {};
+var reporter = {};
+/*global setTimeout: false, console: false */
+(function () {
+
+    var async = {};
+
+    // global on the server, window in the browser
+    var root = this,
+        previous_async = root.async;
+
+    if (typeof module !== 'undefined' && module.exports) {
+        module.exports = async;
+    }
+    else {
+        root.async = async;
+    }
+
+    async.noConflict = function () {
+        root.async = previous_async;
+        return async;
+    };
+
+    //// cross-browser compatiblity functions ////
+
+    var _forEach = function (arr, iterator) {
+        if (arr.forEach) {
+            return arr.forEach(iterator);
+        }
+        for (var i = 0; i < arr.length; i += 1) {
+            iterator(arr[i], i, arr);
+        }
+    };
+
+    var _map = function (arr, iterator) {
+        if (arr.map) {
+            return arr.map(iterator);
+        }
+        var results = [];
+        _forEach(arr, function (x, i, a) {
+            results.push(iterator(x, i, a));
+        });
+        return results;
+    };
+
+    var _reduce = function (arr, iterator, memo) {
+        if (arr.reduce) {
+            return arr.reduce(iterator, memo);
+        }
+        _forEach(arr, function (x, i, a) {
+            memo = iterator(memo, x, i, a);
+        });
+        return memo;
+    };
+
+    var _keys = function (obj) {
+        if (Object.keys) {
+            return Object.keys(obj);
+        }
+        var keys = [];
+        for (var k in obj) {
+            if (obj.hasOwnProperty(k)) {
+                keys.push(k);
+            }
+        }
+        return keys;
+    };
+
+    var _indexOf = function (arr, item) {
+        if (arr.indexOf) {
+            return arr.indexOf(item);
+        }
+        for (var i = 0; i < arr.length; i += 1) {
+            if (arr[i] === item) {
+                return i;
+            }
+        }
+        return -1;
+    };
+
+    //// exported async module functions ////
+
+    //// nextTick implementation with browser-compatible fallback ////
+    async.nextTick = function (fn) {
+        if (typeof process === 'undefined' || !(process.nextTick)) {
+            setTimeout(fn, 0);
+        }
+        else {
+            process.nextTick(fn);
+        }
+    };
+
+    async.forEach = function (arr, iterator, callback) {
+        if (!arr.length) {
+            return callback();
+        }
+        var completed = 0;
+        _forEach(arr, function (x) {
+            iterator(x, function (err) {
+                if (err) {
+                    callback(err);
+                    callback = function () {};
+                }
+                else {
+                    completed += 1;
+                    if (completed === arr.length) {
+                        callback();
+                    }
+                }
+            });
+        });
+    };
+
+    async.forEachSeries = function (arr, iterator, callback) {
+        if (!arr.length) {
+            return callback();
+        }
+        var completed = 0;
+        var iterate = function () {
+            iterator(arr[completed], function (err) {
+                if (err) {
+                    callback(err);
+                    callback = function () {};
+                }
+                else {
+                    completed += 1;
+                    if (completed === arr.length) {
+                        callback();
+                    }
+                    else {
+                        iterate();
+                    }
+                }
+            });
+        };
+        iterate();
+    };
+
+
+    var doParallel = function (fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [async.forEach].concat(args));
+        };
+    };
+    var doSeries = function (fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [async.forEachSeries].concat(args));
+        };
+    };
+
+
+    var _asyncMap = function (eachfn, arr, iterator, callback) {
+        var results = [];
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        eachfn(arr, function (x, callback) {
+            iterator(x.value, function (err, v) {
+                results[x.index] = v;
+                callback(err);
+            });
+        }, function (err) {
+            callback(err, results);
+        });
+    };
+    async.map = doParallel(_asyncMap);
+    async.mapSeries = doSeries(_asyncMap);
+
+
+    // reduce only has a series version, as doing reduce in parallel won't
+    // work in many situations.
+    async.reduce = function (arr, memo, iterator, callback) {
+        async.forEachSeries(arr, function (x, callback) {
+            iterator(memo, x, function (err, v) {
+                memo = v;
+                callback(err);
+            });
+        }, function (err) {
+            callback(err, memo);
+        });
+    };
+    // inject alias
+    async.inject = async.reduce;
+    // foldl alias
+    async.foldl = async.reduce;
+
+    async.reduceRight = function (arr, memo, iterator, callback) {
+        var reversed = _map(arr, function (x) {
+            return x;
+        }).reverse();
+        async.reduce(reversed, memo, iterator, callback);
+    };
+    // foldr alias
+    async.foldr = async.reduceRight;
+
+    var _filter = function (eachfn, arr, iterator, callback) {
+        var results = [];
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        eachfn(arr, function (x, callback) {
+            iterator(x.value, function (v) {
+                if (v) {
+                    results.push(x);
+                }
+                callback();
+            });
+        }, function (err) {
+            callback(_map(results.sort(function (a, b) {
+                return a.index - b.index;
+            }), function (x) {
+                return x.value;
+            }));
+        });
+    };
+    async.filter = doParallel(_filter);
+    async.filterSeries = doSeries(_filter);
+    // select alias
+    async.select = async.filter;
+    async.selectSeries = async.filterSeries;
+
+    var _reject = function (eachfn, arr, iterator, callback) {
+        var results = [];
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        eachfn(arr, function (x, callback) {
+            iterator(x.value, function (v) {
+                if (!v) {
+                    results.push(x);
+                }
+                callback();
+            });
+        }, function (err) {
+            callback(_map(results.sort(function (a, b) {
+                return a.index - b.index;
+            }), function (x) {
+                return x.value;
+            }));
+        });
+    };
+    async.reject = doParallel(_reject);
+    async.rejectSeries = doSeries(_reject);
+
+    var _detect = function (eachfn, arr, iterator, main_callback) {
+        eachfn(arr, function (x, callback) {
+            iterator(x, function (result) {
+                if (result) {
+                    main_callback(x);
+                }
+                else {
+                    callback();
+                }
+            });
+        }, function (err) {
+            main_callback();
+        });
+    };
+    async.detect = doParallel(_detect);
+    async.detectSeries = doSeries(_detect);
+
+    async.some = function (arr, iterator, main_callback) {
+        async.forEach(arr, function (x, callback) {
+            iterator(x, function (v) {
+                if (v) {
+                    main_callback(true);
+                    main_callback = function () {};
+                }
+                callback();
+            });
+        }, function (err) {
+            main_callback(false);
+        });
+    };
+    // any alias
+    async.any = async.some;
+
+    async.every = function (arr, iterator, main_callback) {
+        async.forEach(arr, function (x, callback) {
+            iterator(x, function (v) {
+                if (!v) {
+                    main_callback(false);
+                    main_callback = function () {};
+                }
+                callback();
+            });
+        }, function (err) {
+            main_callback(true);
+        });
+    };
+    // all alias
+    async.all = async.every;
+
+    async.sortBy = function (arr, iterator, callback) {
+        async.map(arr, function (x, callback) {
+            iterator(x, function (err, criteria) {
+                if (err) {
+                    callback(err);
+                }
+                else {
+                    callback(null, {value: x, criteria: criteria});
+                }
+            });
+        }, function (err, results) {
+            if (err) {
+                return callback(err);
+            }
+            else {
+                var fn = function (left, right) {
+                    var a = left.criteria, b = right.criteria;
+                    return a < b ? -1 : a > b ? 1 : 0;
+                };
+                callback(null, _map(results.sort(fn), function (x) {
+                    return x.value;
+                }));
+            }
+        });
+    };
+
+    async.auto = function (tasks, callback) {
+        callback = callback || function () {};
+        var keys = _keys(tasks);
+        if (!keys.length) {
+            return callback(null);
+        }
+
+        var completed = [];
+
+        var listeners = [];
+        var addListener = function (fn) {
+            listeners.unshift(fn);
+        };
+        var removeListener = function (fn) {
+            for (var i = 0; i < listeners.length; i += 1) {
+                if (listeners[i] === fn) {
+                    listeners.splice(i, 1);
+                    return;
+                }
+            }
+        };
+        var taskComplete = function () {
+            _forEach(listeners, function (fn) {
+                fn();
+            });
+        };
+
+        addListener(function () {
+            if (completed.length === keys.length) {
+                callback(null);
+            }
+        });
+
+        _forEach(keys, function (k) {
+            var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
+            var taskCallback = function (err) {
+                if (err) {
+                    callback(err);
+                    // stop subsequent errors hitting callback multiple times
+                    callback = function () {};
+                }
+                else {
+                    completed.push(k);
+                    taskComplete();
+                }
+            };
+            var requires = task.slice(0, Math.abs(task.length - 1)) || [];
+            var ready = function () {
+                return _reduce(requires, function (a, x) {
+                    return (a && _indexOf(completed, x) !== -1);
+                }, true);
+            };
+            if (ready()) {
+                task[task.length - 1](taskCallback);
+            }
+            else {
+                var listener = function () {
+                    if (ready()) {
+                        removeListener(listener);
+                        task[task.length - 1](taskCallback);
+                    }
+                };
+                addListener(listener);
+            }
+        });
+    };
+
+    async.waterfall = function (tasks, callback) {
+        if (!tasks.length) {
+            return callback();
+        }
+        callback = callback || function () {};
+        var wrapIterator = function (iterator) {
+            return function (err) {
+                if (err) {
+                    callback(err);
+                    callback = function () {};
+                }
+                else {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    var next = iterator.next();
+                    if (next) {
+                        args.push(wrapIterator(next));
+                    }
+                    else {
+                        args.push(callback);
+                    }
+                    async.nextTick(function () {
+                        iterator.apply(null, args);
+                    });
+                }
+            };
+        };
+        wrapIterator(async.iterator(tasks))();
+    };
+
+    async.parallel = function (tasks, callback) {
+        callback = callback || function () {};
+        if (tasks.constructor === Array) {
+            async.map(tasks, function (fn, callback) {
+                if (fn) {
+                    fn(function (err) {
+                        var args = Array.prototype.slice.call(arguments, 1);
+                        if (args.length <= 1) {
+                            args = args[0];
+                        }
+                        callback.call(null, err, args || null);
+                    });
+                }
+            }, callback);
+        }
+        else {
+            var results = {};
+            async.forEach(_keys(tasks), function (k, callback) {
+                tasks[k](function (err) {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    if (args.length <= 1) {
+                        args = args[0];
+                    }
+                    results[k] = args;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+
+    async.series = function (tasks, callback) {
+        callback = callback || function () {};
+        if (tasks.constructor === Array) {
+            async.mapSeries(tasks, function (fn, callback) {
+                if (fn) {
+                    fn(function (err) {
+                        var args = Array.prototype.slice.call(arguments, 1);
+                        if (args.length <= 1) {
+                            args = args[0];
+                        }
+                        callback.call(null, err, args || null);
+                    });
+                }
+            }, callback);
+        }
+        else {
+            var results = {};
+            async.forEachSeries(_keys(tasks), function (k, callback) {
+                tasks[k](function (err) {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    if (args.length <= 1) {
+                        args = args[0];
+                    }
+                    results[k] = args;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+
+    async.iterator = function (tasks) {
+        var makeCallback = function (index) {
+            var fn = function () {
+                if (tasks.length) {
+                    tasks[index].apply(null, arguments);
+                }
+                return fn.next();
+            };
+            fn.next = function () {
+                return (index < tasks.length - 1) ? makeCallback(index + 1): null;
+            };
+            return fn;
+        };
+        return makeCallback(0);
+    };
+
+    async.apply = function (fn) {
+        var args = Array.prototype.slice.call(arguments, 1);
+        return function () {
+            return fn.apply(
+                null, args.concat(Array.prototype.slice.call(arguments))
+            );
+        };
+    };
+
+    var _concat = function (eachfn, arr, fn, callback) {
+        var r = [];
+        eachfn(arr, function (x, cb) {
+            fn(x, function (err, y) {
+                r = r.concat(y || []);
+                cb(err);
+            });
+        }, function (err) {
+            callback(err, r);
+        });
+    };
+    async.concat = doParallel(_concat);
+    async.concatSeries = doSeries(_concat);
+
+    async.whilst = function (test, iterator, callback) {
+        if (test()) {
+            iterator(function (err) {
+                if (err) {
+                    return callback(err);
+                }
+                async.whilst(test, iterator, callback);
+            });
+        }
+        else {
+            callback();
+        }
+    };
+
+    async.until = function (test, iterator, callback) {
+        if (!test()) {
+            iterator(function (err) {
+                if (err) {
+                    return callback(err);
+                }
+                async.until(test, iterator, callback);
+            });
+        }
+        else {
+            callback();
+        }
+    };
+
+    async.queue = function (worker, concurrency) {
+        var workers = 0;
+        var tasks = [];
+        var q = {
+            concurrency: concurrency,
+            push: function (data, callback) {
+                tasks.push({data: data, callback: callback});
+                async.nextTick(q.process);
+            },
+            process: function () {
+                if (workers < q.concurrency && tasks.length) {
+                    var task = tasks.splice(0, 1)[0];
+                    workers += 1;
+                    worker(task.data, function () {
+                        workers -= 1;
+                        if (task.callback) {
+                            task.callback.apply(task, arguments);
+                        }
+                        q.process();
+                    });
+                }
+            },
+            length: function () {
+                return tasks.length;
+            }
+        };
+        return q;
+    };
+
+    var _console_fn = function (name) {
+        return function (fn) {
+            var args = Array.prototype.slice.call(arguments, 1);
+            fn.apply(null, args.concat([function (err) {
+                var args = Array.prototype.slice.call(arguments, 1);
+                if (typeof console !== 'undefined') {
+                    if (err) {
+                        if (console.error) {
+                            console.error(err);
+                        }
+                    }
+                    else if (console[name]) {
+                        _forEach(args, function (x) {
+                            console[name](x);
+                        });
+                    }
+                }
+            }]));
+        };
+    };
+    async.log = _console_fn('log');
+    async.dir = _console_fn('dir');
+    /*async.info = _console_fn('info');
+    async.warn = _console_fn('warn');
+    async.error = _console_fn('error');*/
+
+}());
+(function(exports){
+/**
+ * This file is based on the node.js assert module, but with some small
+ * changes for browser-compatibility
+ * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!
+ */
+
+
+/**
+ * Added for browser compatibility
+ */
+
+var _keys = function(obj){
+    if(Object.keys) return Object.keys(obj);
+    var keys = [];
+    for(var k in obj){
+        if(obj.hasOwnProperty(k)) keys.push(k);
+    }
+    return keys;
+};
+
+
+
+// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
+//
+// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
+//
+// Originally from narwhal.js (http://narwhaljs.org)
+// Copyright (c) 2009 Thomas Robinson <280north.com>
+//
+// 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 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.
+
+
+var pSlice = Array.prototype.slice;
+
+// 1. The assert module provides functions that throw
+// AssertionError's when particular conditions are not met. The
+// assert module must conform to the following interface.
+
+var assert = exports;
+
+// 2. The AssertionError is defined in assert.
+// new assert.AssertionError({message: message, actual: actual, expected: expected})
+
+assert.AssertionError = function AssertionError (options) {
+  this.name = "AssertionError";
+  this.message = options.message;
+  this.actual = options.actual;
+  this.expected = options.expected;
+  this.operator = options.operator;
+  var stackStartFunction = options.stackStartFunction || fail;
+
+  if (Error.captureStackTrace) {
+    Error.captureStackTrace(this, stackStartFunction);
+  }
+};
+// code from util.inherits in node
+assert.AssertionError.super_ = Error;
+
+
+// EDITED FOR BROWSER COMPATIBILITY: replaced Object.create call
+// TODO: test what effect this may have
+var ctor = function () { this.constructor = assert.AssertionError; };
+ctor.prototype = Error.prototype;
+assert.AssertionError.prototype = new ctor();
+
+
+assert.AssertionError.prototype.toString = function() {
+  if (this.message) {
+    return [this.name+":", this.message].join(' ');
+  } else {
+    return [ this.name+":"
+           , JSON.stringify(this.expected )
+           , this.operator
+           , JSON.stringify(this.actual)
+           ].join(" ");
+  }
+};
+
+// assert.AssertionError instanceof Error
+
+assert.AssertionError.__proto__ = Error.prototype;
+
+// At present only the three keys mentioned above are used and
+// understood by the spec. Implementations or sub modules can pass
+// other keys to the AssertionError's constructor - they will be
+// ignored.
+
+// 3. All of the following functions must throw an AssertionError
+// when a corresponding condition is not met, with a message that
+// may be undefined if not provided.  All assertion methods provide
+// both the actual and expected values to the assertion error for
+// display purposes.
+
+function fail(actual, expected, message, operator, stackStartFunction) {
+  throw new assert.AssertionError({
+    message: message,
+    actual: actual,
+    expected: expected,
+    operator: operator,
+    stackStartFunction: stackStartFunction
+  });
+}
+
+// EXTENSION! allows for well behaved errors defined elsewhere.
+assert.fail = fail;
+
+// 4. Pure assertion tests whether a value is truthy, as determined
+// by !!guard.
+// assert.ok(guard, message_opt);
+// This statement is equivalent to assert.equal(true, guard,
+// message_opt);. To test strictly for the value true, use
+// assert.strictEqual(true, guard, message_opt);.
+
+assert.ok = function ok(value, message) {
+  if (!!!value) fail(value, true, message, "==", assert.ok);
+};
+
+// 5. The equality assertion tests shallow, coercive equality with
+// ==.
+// assert.equal(actual, expected, message_opt);
+
+assert.equal = function equal(actual, expected, message) {
+  if (actual != expected) fail(actual, expected, message, "==", assert.equal);
+};
+
+// 6. The non-equality assertion tests for whether two objects are not equal
+// with != assert.notEqual(actual, expected, message_opt);
+
+assert.notEqual = function notEqual(actual, expected, message) {
+  if (actual == expected) {
+    fail(actual, expected, message, "!=", assert.notEqual);
+  }
+};
+
+// 7. The equivalence assertion tests a deep equality relation.
+// assert.deepEqual(actual, expected, message_opt);
+
+assert.deepEqual = function deepEqual(actual, expected, message) {
+  if (!_deepEqual(actual, expected)) {
+    fail(actual, expected, message, "deepEqual", assert.deepEqual);
+  }
+};
+
+function _deepEqual(actual, expected) {
+  // 7.1. All identical values are equivalent, as determined by ===.
+  if (actual === expected) {
+    return true;
+  // 7.2. If the expected value is a Date object, the actual value is
+  // equivalent if it is also a Date object that refers to the same time.
+  } else if (actual instanceof Date && expected instanceof Date) {
+    return actual.getTime() === expected.getTime();
+
+  // 7.3. Other pairs that do not both pass typeof value == "object",
+  // equivalence is determined by ==.
+  } else if (typeof actual != 'object' && typeof expected != 'object') {
+    return actual == expected;
+
+  // 7.4. For all other Object pairs, including Array objects, equivalence is
+  // determined by having the same number of owned properties (as verified
+  // with Object.prototype.hasOwnProperty.call), the same set of keys
+  // (although not necessarily the same order), equivalent values for every
+  // corresponding key, and an identical "prototype" property. Note: this
+  // accounts for both named and indexed properties on Arrays.
+  } else {
+    return objEquiv(actual, expected);
+  }
+}
+
+function isUndefinedOrNull (value) {
+  return value === null || value === undefined;
+}
+
+function isArguments (object) {
+  return Object.prototype.toString.call(object) == '[object Arguments]';
+}
+
+function objEquiv (a, b) {
+  if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
+    return false;
+  // an identical "prototype" property.
+  if (a.prototype !== b.prototype) return false;
+  //~~~I've managed to break Object.keys through screwy arguments passing.
+  //   Converting to array solves the problem.
+  if (isArguments(a)) {
+    if (!isArguments(b)) {
+      return false;
+    }
+    a = pSlice.call(a);
+    b = pSlice.call(b);
+    return _deepEqual(a, b);
+  }
+  try{
+    var ka = _keys(a),
+      kb = _keys(b),
+      key, i;
+  } catch (e) {//happens when one is a string literal and the other isn't
+    return false;
+  }
+  // having the same number of owned properties (keys incorporates hasOwnProperty)
+  if (ka.length != kb.length)
+    return false;
+  //the same set of keys (although not necessarily the same order),
+  ka.sort();
+  kb.sort();
+  //~~~cheap key test
+  for (i = ka.length - 1; i >= 0; i--) {
+    if (ka[i] != kb[i])
+      return false;
+  }
+  //equivalent values for every corresponding key, and
+  //~~~possibly expensive deep test
+  for (i = ka.length - 1; i >= 0; i--) {
+    key = ka[i];
+    if (!_deepEqual(a[key], b[key] ))
+       return false;
+  }
+  return true;
+}
+
+// 8. The non-equivalence assertion tests for any deep inequality.
+// assert.notDeepEqual(actual, expected, message_opt);
+
+assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
+  if (_deepEqual(actual, expected)) {
+    fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual);
+  }
+};
+
+// 9. The strict equality assertion tests strict equality, as determined by ===.
+// assert.strictEqual(actual, expected, message_opt);
+
+assert.strictEqual = function strictEqual(actual, expected, message) {
+  if (actual !== expected) {
+    fail(actual, expected, message, "===", assert.strictEqual);
+  }
+};
+
+// 10. The strict non-equality assertion tests for strict inequality, as determined by !==.
+// assert.notStrictEqual(actual, expected, message_opt);
+
+assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
+  if (actual === expected) {
+    fail(actual, expected, message, "!==", assert.notStrictEqual);
+  }
+};
+
+function _throws (shouldThrow, block, err, message) {
+  var exception = null,
+      threw = false,
+      typematters = true;
+
+  message = message || "";
+
+  //handle optional arguments
+  if (arguments.length == 3) {
+    if (typeof(err) == "string") {
+      message = err;
+      typematters = false;
+    }
+  } else if (arguments.length == 2) {
+    typematters = false;
+  }
+
+  try {
+    block();
+  } catch (e) {
+    threw = true;
+    exception = e;
+  }
+
+  if (shouldThrow && !threw) {
+    fail( "Missing expected exception"
+        + (err && err.name ? " ("+err.name+")." : '.')
+        + (message ? " " + message : "")
+        );
+  }
+  if (!shouldThrow && threw && typematters && exception instanceof err) {
+    fail( "Got unwanted exception"
+        + (err && err.name ? " ("+err.name+")." : '.')
+        + (message ? " " + message : "")
+        );
+  }
+  if ((shouldThrow && threw && typematters && !(exception instanceof err)) ||
+      (!shouldThrow && threw)) {
+    throw exception;
+  }
+};
+
+// 11. Expected to throw an error:
+// assert.throws(block, Error_opt, message_opt);
+
+assert.throws = function(block, /*optional*/error, /*optional*/message) {
+  _throws.apply(this, [true].concat(pSlice.call(arguments)));
+};
+
+// EXTENSION! This is annoying to write outside this module.
+assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
+  _throws.apply(this, [false].concat(pSlice.call(arguments)));
+};
+
+assert.ifError = function (err) { if (err) {throw err;}};
+})(assert);
+(function(exports){
+/*!
+ * Nodeunit
+ * Copyright (c) 2010 Caolan McMahon
+ * MIT Licensed
+ *
+ * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!
+ * Only code on that line will be removed, its mostly to avoid requiring code
+ * that is node specific
+ */
+
+/**
+ * Module dependencies
+ */
+
+
+
+/**
+ * Creates assertion objects representing the result of an assert call.
+ * Accepts an object or AssertionError as its argument.
+ *
+ * @param {object} obj
+ * @api public
+ */
+
+exports.assertion = function (obj) {
+    return {
+        method: obj.method || '',
+        message: obj.message || (obj.error && obj.error.message) || '',
+        error: obj.error,
+        passed: function () {
+            return !this.error;
+        },
+        failed: function () {
+            return Boolean(this.error);
+        }
+    };
+};
+
+/**
+ * Creates an assertion list object representing a group of assertions.
+ * Accepts an array of assertion objects.
+ *
+ * @param {Array} arr
+ * @param {Number} duration
+ * @api public
+ */
+
+exports.assertionList = function (arr, duration) {
+    var that = arr || [];
+    that.failures = function () {
+        var failures = 0;
+        for (var i=0; i<this.length; i++) {
+            if (this[i].failed()) failures++;
+        }
+        return failures;
+    };
+    that.passes = function () {
+        return that.length - that.failures();
+    };
+    that.duration = duration || 0;
+    return that;
+};
+
+/**
+ * Create a wrapper function for assert module methods. Executes a callback
+ * after the it's complete with an assertion object representing the result.
+ *
+ * @param {Function} callback
+ * @api private
+ */
+
+var assertWrapper = function (callback) {
+    return function (new_method, assert_method, arity) {
+        return function () {
+            var message = arguments[arity-1];
+            var a = exports.assertion({method: new_method, message: message});
+            try {
+                assert[assert_method].apply(null, arguments);
+            }
+            catch (e) {
+                a.error = e;
+            }
+            callback(a);
+        };
+    };
+};
+
+/**
+ * Creates the 'test' object that gets passed to every test function.
+ * Accepts the name of the test function as its first argument, followed by
+ * the start time in ms, the options object and a callback function.
+ *
+ * @param {String} name
+ * @param {Number} start
+ * @param {Object} options
+ * @param {Function} callback
+ * @api public
+ */
+
+exports.test = function (name, start, options, callback) {
+    var expecting;
+    var a_list = [];
+
+    var wrapAssert = assertWrapper(function (a) {
+        a_list.push(a);
+        if (options.log) {
+            async.nextTick(function () {
+                options.log(a);
+            });
+        }
+    });
+
+    var test = {
+        done: function (err) {
+            if (expecting !== undefined && expecting !== a_list.length) {
+                var e = new Error(
+                    'Expected ' + expecting + ' assertions, ' +
+                    a_list.length + ' ran'
+                );
+                var a1 = exports.assertion({method: 'expect', error: e});
+                a_list.push(a1);
+                if (options.log) {
+                    async.nextTick(function () {
+                        options.log(a1);
+                    });
+                }
+            }
+            if (err) {
+                var a2 = exports.assertion({error: err});
+                a_list.push(a2);
+                if (options.log) {
+                    async.nextTick(function () {
+                        options.log(a2);
+                    });
+                }
+            }
+            var end = new Date().getTime();
+            async.nextTick(function () {
+                var assertion_list = exports.assertionList(a_list, end - start);
+                options.testDone(name, assertion_list);
+                callback(null, a_list);
+            });
+        },
+        ok: wrapAssert('ok', 'ok', 2),
+        same: wrapAssert('same', 'deepEqual', 3),
+        equals: wrapAssert('equals', 'equal', 3),
+        expect: function (num) {
+            expecting = num;
+        },
+        _assertion_list: a_list
+    };
+    // add all functions from the assert module
+    for (var k in assert) {
+        if (assert.hasOwnProperty(k)) {
+            test[k] = wrapAssert(k, k, assert[k].length);
+        }
+    }
+    return test;
+};
+
+/**
+ * Ensures an options object has all callbacks, adding empty callback functions
+ * if any are missing.
+ *
+ * @param {Object} opt
+ * @return {Object}
+ * @api public
+ */
+
+exports.options = function (opt) {
+    var optionalCallback = function (name) {
+        opt[name] = opt[name] || function () {};
+    };
+
+    optionalCallback('moduleStart');
+    optionalCallback('moduleDone');
+    optionalCallback('testStart');
+    optionalCallback('testDone');
+    //optionalCallback('log');
+
+    // 'done' callback is not optional.
+
+    return opt;
+};
+})(types);
+(function(exports){
+/*!
+ * Nodeunit
+ * Copyright (c) 2010 Caolan McMahon
+ * MIT Licensed
+ *
+ * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!
+ * Only code on that line will be removed, its mostly to avoid requiring code
+ * that is node specific
+ */
+
+/**
+ * Module dependencies
+ */
+
+
+
+/**
+ * Added for browser compatibility
+ */
+
+var _keys = function(obj){
+    if(Object.keys) return Object.keys(obj);
+    var keys = [];
+    for(var k in obj){
+        if(obj.hasOwnProperty(k)) keys.push(k);
+    }
+    return keys;
+};
+
+
+/**
+ * Runs a test function (fn) from a loaded module. After the test function
+ * calls test.done(), the callback is executed with an assertionList as its
+ * second argument.
+ *
+ * @param {String} name
+ * @param {Function} fn
+ * @param {Object} opt
+ * @param {Function} callback
+ * @api public
+ */
+
+exports.runTest = function (name, fn, opt, callback) {
+    var options = types.options(opt);
+
+    options.testStart(name);
+    var start = new Date().getTime();
+    var test = types.test(name, start, options, callback);
+
+    try {
+        fn(test);
+    }
+    catch (e) {
+        test.done(e);
+    }
+};
+
+/**
+ * Takes an object containing test functions or other test suites as properties
+ * and runs each in series. After all tests have completed, the callback is
+ * called with a list of all assertions as the second argument.
+ *
+ * If a name is passed to this function it is prepended to all test and suite
+ * names that run within it.
+ *
+ * @param {String} name
+ * @param {Object} suite
+ * @param {Object} opt
+ * @param {Function} callback
+ * @api public
+ */
+
+exports.runSuite = function (name, suite, opt, callback) {
+    var keys = _keys(suite);
+
+    async.concatSeries(keys, function (k, cb) {
+        var prop = suite[k], _name;
+
+        _name = name ? [].concat(name, k) : [k];
+
+        _name.toString = function () {
+            // fallback for old one
+            return this.join(' - ');
+        };
+
+        if (typeof prop === 'function') {
+            exports.runTest(_name, suite[k], opt, cb);
+        }
+        else {
+            exports.runSuite(_name, suite[k], opt, cb);
+        }
+    }, callback);
+};
+
+/**
+ * Run each exported test function or test suite from a loaded module.
+ *
+ * @param {String} name
+ * @param {Object} mod
+ * @param {Object} opt
+ * @param {Function} callback
+ * @api public
+ */
+
+exports.runModule = function (name, mod, opt, callback) {
+    var options = types.options(opt);
+
+    options.moduleStart(name);
+    var start = new Date().getTime();
+
+    exports.runSuite(null, mod, opt, function (err, a_list) {
+        var end = new Date().getTime();
+        var assertion_list = types.assertionList(a_list, end - start);
+        options.moduleDone(name, assertion_list);
+        callback(null, a_list);
+    });
+};
+
+/**
+ * Treats an object literal as a list of modules keyed by name. Runs each
+ * module and finished with calling 'done'. You can think of this as a browser
+ * safe alternative to runFiles in the nodeunit module.
+ *
+ * @param {Object} modules
+ * @param {Object} opt
+ * @api public
+ */
+
+// TODO: add proper unit tests for this function
+exports.runModules = function (modules, opt) {
+    var all_assertions = [];
+    var options = types.options(opt);
+    var start = new Date().getTime();
+
+    async.concatSeries(_keys(modules), function (k, cb) {
+        exports.runModule(k, modules[k], options, cb);
+    },
+    function (err, all_assertions) {
+        var end = new Date().getTime();
+        options.done(types.assertionList(all_assertions, end - start));
+    });
+};
+
+
+/**
+ * Wraps a test function with setUp and tearDown functions.
+ * Used by testCase.
+ *
+ * @param {Function} setUp
+ * @param {Function} tearDown
+ * @param {Function} fn
+ * @api private
+ */
+
+var wrapTest = function (setUp, tearDown, fn) {
+    return function (test) {
+        var context = {};
+        if (tearDown) {
+            var done = test.done;
+            test.done = function (err) {
+                try {
+                    tearDown.call(context, function (err2) {
+                        if (err && err2) {
+                            test._assertion_list.push(
+                                types.assertion({error: err})
+                            );
+                            return done(err2);
+                        }
+                        done(err || err2);
+                    });
+                }
+                catch (e) {
+                    done(e);
+                }
+            };
+        }
+        if (setUp) {
+            setUp.call(context, function (err) {
+                if (err) {
+                    return test.done(err);
+                }
+                fn.call(context, test);
+            });
+        }
+        else {
+            fn.call(context, test);
+        }
+    }
+};
+
+
+/**
+ * Wraps a group of tests with setUp and tearDown functions.
+ * Used by testCase.
+ *
+ * @param {Function} setUp
+ * @param {Function} tearDown
+ * @param {Object} group
+ * @api private
+ */
+
+var wrapGroup = function (setUp, tearDown, group) {
+    var tests = {};
+    var keys = _keys(group);
+    for (var i=0; i<keys.length; i++) {
+        var k = keys[i];
+        if (typeof group[k] === 'function') {
+            tests[k] = wrapTest(setUp, tearDown, group[k]);
+        }
+        else if (typeof group[k] === 'object') {
+            tests[k] = wrapGroup(setUp, tearDown, group[k]);
+        }
+    }
+    return tests;
+}
+
+
+/**
+ * Utility for wrapping a suite of test functions with setUp and tearDown
+ * functions.
+ *
+ * @param {Object} suite
+ * @return {Object}
+ * @api public
+ */
+
+exports.testCase = function (suite) {
+    var setUp = suite.setUp;
+    var tearDown = suite.tearDown;
+    delete suite.setUp;
+    delete suite.tearDown;
+    return wrapGroup(setUp, tearDown, suite);
+};
+})(core);
+(function(exports){
+/*!
+ * Nodeunit
+ * Copyright (c) 2010 Caolan McMahon
+ * MIT Licensed
+ *
+ * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!
+ * Only code on that line will be removed, its mostly to avoid requiring code
+ * that is node specific
+ */
+
+
+/**
+ * NOTE: this test runner is not listed in index.js because it cannot be
+ * used with the command-line tool, only inside the browser.
+ */
+
+
+/**
+ * Reporter info string
+ */
+
+exports.info = "Browser-based test reporter";
+
+
+/**
+ * Run all tests within each module, reporting the results
+ *
+ * @param {Array} files
+ * @api public
+ */
+
+exports.run = function (modules, options) {
+    var start = new Date().getTime();
+
+    function setText(el, txt) {
+        if ('innerText' in el) {
+            el.innerText = txt;
+        }
+        else if ('textContent' in el){
+            el.textContent = txt;
+        }
+    }
+
+    function getOrCreate(tag, id) {
+        var el = document.getElementById(id);
+        if (!el) {
+            el = document.createElement(tag);
+            el.id = id;
+            document.body.appendChild(el);
+        }
+        return el;
+    };
+
+    var header = getOrCreate('h1', 'nodeunit-header');
+    var banner = getOrCreate('h2', 'nodeunit-banner');
+    var userAgent = getOrCreate('h2', 'nodeunit-userAgent');
+    var tests = getOrCreate('ol', 'nodeunit-tests');
+    var result = getOrCreate('p', 'nodeunit-testresult');
+
+    setText(userAgent, navigator.userAgent);
+
+    nodeunit.runModules(modules, {
+        moduleStart: function (name) {
+            /*var mheading = document.createElement('h2');
+            mheading.innerText = name;
+            results.appendChild(mheading);
+            module = document.createElement('ol');
+            results.appendChild(module);*/
+        },
+        testDone: function (name, assertions) {
+            var test = document.createElement('li');
+            var strong = document.createElement('strong');
+            strong.innerHTML = name + ' <b style="color: black;">(' +
+                '<b class="fail">' + assertions.failures() + '</b>, ' +
+                '<b class="pass">' + assertions.passes() + '</b>, ' +
+                assertions.length +
+            ')</b>';
+            test.className = assertions.failures() ? 'fail': 'pass';
+            test.appendChild(strong);
+
+            var aList = document.createElement('ol');
+            aList.style.display = 'none';
+            test.onclick = function () {
+                var d = aList.style.display;
+                aList.style.display = (d == 'none') ? 'block': 'none';
+            };
+            for (var i=0; i<assertions.length; i++) {
+                var li = document.createElement('li');
+                var a = assertions[i];
+                if (a.failed()) {
+                    li.innerHTML = (a.message || a.method || 'no message') +
+                        '<pre>' + (a.error.stack || a.error) + '</pre>';
+                    li.className = 'fail';
+                }
+                else {
+                    li.innerHTML = a.message || a.method || 'no message';
+                    li.className = 'pass';
+                }
+                aList.appendChild(li);
+            }
+            test.appendChild(aList);
+            tests.appendChild(test);
+        },
+        done: function (assertions) {
+            var end = new Date().getTime();
+            var duration = end - start;
+
+            var failures = assertions.failures();
+            banner.className = failures ? 'fail': 'pass';
+
+            result.innerHTML = 'Tests completed in ' + duration +
+                ' milliseconds.<br/><span class="passed">' +
+                assertions.passes() + '</span> assertions of ' +
+                '<span class="all">' + assertions.length + '<span> passed, ' +
+                assertions.failures() + ' failed.';
+        }
+    });
+};
+})(reporter);
+nodeunit = core;
+nodeunit.assert = assert;
+nodeunit.reporter = reporter;
+nodeunit.run = reporter.run;
+return nodeunit; })();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/dist/async.min.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/dist/async.min.js
new file mode 100644 (file)
index 0000000..f89741e
--- /dev/null
@@ -0,0 +1 @@
+/*global setTimeout: false, console: false */(function(){var a={};var b=this,c=b.async;typeof module!=="undefined"&&module.exports?module.exports=a:b.async=a,a.noConflict=function(){b.async=c;return a};var d=function(a,b){if(a.forEach)return a.forEach(b);for(var c=0;c<a.length;c+=1)b(a[c],c,a)};var e=function(a,b){if(a.map)return a.map(b);var c=[];d(a,function(a,d,e){c.push(b(a,d,e))});return c};var f=function(a,b,c){if(a.reduce)return a.reduce(b,c);d(a,function(a,d,e){c=b(c,a,d,e)});return c};var g=function(a){if(Object.keys)return Object.keys(a);var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b};var h=function(a,b){if(a.indexOf)return a.indexOf(b);for(var c=0;c<a.length;c+=1)if(a[c]===b)return c;return-1};typeof process==="undefined"||!process.nextTick?a.nextTick=function(a){setTimeout(a,0)}:a.nextTick=process.nextTick,a.forEach=function(a,b,c){if(!a.length)return c();var e=0;d(a,function(d){b(d,function(b){b?(c(b),c=function(){}):(e+=1,e===a.length&&c())})})},a.forEachSeries=function(a,b,c){if(!a.length)return c();var d=0;var e=function(){b(a[d],function(b){b?(c(b),c=function(){}):(d+=1,d===a.length?c():e())})};e()};var i=function(b){return function(){var c=Array.prototype.slice.call(arguments);return b.apply(null,[a.forEach].concat(c))}};var j=function(b){return function(){var c=Array.prototype.slice.call(arguments);return b.apply(null,[a.forEachSeries].concat(c))}};var k=function(a,b,c,d){var f=[];b=e(b,function(a,b){return{index:b,value:a}}),a(b,function(a,b){c(a.value,function(c,d){f[a.index]=d,b(c)})},function(a){d(a,f)})};a.map=i(k),a.mapSeries=j(k),a.reduce=function(b,c,d,e){a.forEachSeries(b,function(a,b){d(c,a,function(a,d){c=d,b(a)})},function(a){e(a,c)})},a.inject=a.reduce,a.foldl=a.reduce,a.reduceRight=function(b,c,d,f){var g=e(b,function(a){return a}).reverse();a.reduce(g,c,d,f)},a.foldr=a.reduceRight;var l=function(a,b,c,d){var f=[];b=e(b,function(a,b){return{index:b,value:a}}),a(b,function(a,b){c(a.value,function(c){c&&f.push(a),b()})},function(a){d(e(f.sort(function(a,b){return a.index-b.index}),function(a){return a.value}))})};a.filter=i(l),a.filterSeries=j(l),a.select=a.filter,a.selectSeries=a.filterSeries;var m=function(a,b,c,d){var f=[];b=e(b,function(a,b){return{index:b,value:a}}),a(b,function(a,b){c(a.value,function(c){c||f.push(a),b()})},function(a){d(e(f.sort(function(a,b){return a.index-b.index}),function(a){return a.value}))})};a.reject=i(m),a.rejectSeries=j(m);var n=function(a,b,c,d){a(b,function(a,b){c(a,function(c){c?d(a):b()})},function(a){d()})};a.detect=i(n),a.detectSeries=j(n),a.some=function(b,c,d){a.forEach(b,function(a,b){c(a,function(a){a&&(d(true),d=function(){}),b()})},function(a){d(false)})},a.any=a.some,a.every=function(b,c,d){a.forEach(b,function(a,b){c(a,function(a){a||(d(false),d=function(){}),b()})},function(a){d(true)})},a.all=a.every,a.sortBy=function(b,c,d){a.map(b,function(a,b){c(a,function(c,d){c?b(c):b(null,{value:a,criteria:d})})},function(a,b){if(a)return d(a);var c=function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0};d(null,e(b.sort(c),function(a){return a.value}))})},a.auto=function(a,b){b=b||function(){};var c=g(a);if(!c.length)return b(null);var e=[];var i=[];var j=function(a){i.unshift(a)};var k=function(a){for(var b=0;b<i.length;b+=1)if(i[b]===a){i.splice(b,1);return}};var l=function(){d(i,function(a){a()})};j(function(){e.length===c.length&&b(null)}),d(c,function(c){var d=a[c]instanceof Function?[a[c]]:a[c];var g=function(a){a?(b(a),b=function(){}):(e.push(c),l())};var i=d.slice(0,Math.abs(d.length-1))||[];var m=function(){return f(i,function(a,b){return a&&h(e,b)!==-1},true)};if(m())d[d.length-1](g);else{var n=function(){m()&&(k(n),d[d.length-1](g))};j(n)}})},a.waterfall=function(b,c){if(!b.length)return c();c=c||function(){};var d=function(b){return function(e){if(e)c(e),c=function(){};else{var f=Array.prototype.slice.call(arguments,1);var g=b.next();g?f.push(d(g)):f.push(c),a.nextTick(function(){b.apply(null,f)})}}};d(a.iterator(b))()},a.parallel=function(b,c){c=c||function(){};if(b.constructor===Array)a.map(b,function(a,b){a&&a(function(a){var c=Array.prototype.slice.call(arguments,1);c.length<=1&&(c=c[0]),b.call(null,a,c)})},c);else{var d={};a.forEach(g(b),function(a,c){b[a](function(b){var e=Array.prototype.slice.call(arguments,1);e.length<=1&&(e=e[0]),d[a]=e,c(b)})},function(a){c(a,d)})}},a.series=function(b,c){c=c||function(){};if(b.constructor===Array)a.mapSeries(b,function(a,b){a&&a(function(a){var c=Array.prototype.slice.call(arguments,1);c.length<=1&&(c=c[0]),b.call(null,a,c)})},c);else{var d={};a.forEachSeries(g(b),function(a,c){b[a](function(b){var e=Array.prototype.slice.call(arguments,1);e.length<=1&&(e=e[0]),d[a]=e,c(b)})},function(a){c(a,d)})}},a.iterator=function(a){var b=function(c){var d=function(){a.length&&a[c].apply(null,arguments);return d.next()};d.next=function(){return c<a.length-1?b(c+1):null};return d};return b(0)},a.apply=function(a){var b=Array.prototype.slice.call(arguments,1);return function(){return a.apply(null,b.concat(Array.prototype.slice.call(arguments)))}};var o=function(a,b,c,d){var e=[];a(b,function(a,b){c(a,function(a,c){e=e.concat(c||[]),b(a)})},function(a){d(a,e)})};a.concat=i(o),a.concatSeries=j(o),a.whilst=function(b,c,d){b()?c(function(e){if(e)return d(e);a.whilst(b,c,d)}):d()},a.until=function(b,c,d){b()?d():c(function(e){if(e)return d(e);a.until(b,c,d)})},a.queue=function(b,c){var d=0;var e=[];var f={concurrency:c,saturated:null,empty:null,drain:null,push:function(b,d){e.push({data:b,callback:d}),f.saturated&&e.length==c&&f.saturated(),a.nextTick(f.process)},process:function(){if(d<f.concurrency&&e.length){var a=e.splice(0,1)[0];f.empty&&e.length==0&&f.empty(),d+=1,b(a.data,function(){d-=1,a.callback&&a.callback.apply(a,arguments),f.drain&&e.length+d==0&&f.drain(),f.process()})}},length:function(){return e.length},running:function(){return d}};return f};var p=function(a){return function(b){var c=Array.prototype.slice.call(arguments,1);b.apply(null,c.concat([function(b){var c=Array.prototype.slice.call(arguments,1);typeof console!=="undefined"&&(b?console.error&&console.error(b):console[a]&&d(c,function(b){console[a](b)}))}]))}};a.log=p("log"),a.dir=p("dir"),a.memoize=function(a,b){var c={};b=b||function(a){return a};return function(){var d=Array.prototype.slice.call(arguments);var e=d.pop();var f=b.apply(null,d);f in c?e.apply(null,c[f]):a.apply(null,d.concat([function(){c[f]=arguments,e.apply(null,arguments)}]))}}})()
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/index.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/index.js
new file mode 100644 (file)
index 0000000..8e23845
--- /dev/null
@@ -0,0 +1,3 @@
+// This file is just added for convenience so this repository can be
+// directly checked out into a project's deps folder
+module.exports = require('./lib/async');
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/lib/async.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/lib/async.js
new file mode 100644 (file)
index 0000000..8c863ac
--- /dev/null
@@ -0,0 +1,632 @@
+/*global setTimeout: false, console: false */
+(function () {
+
+    var async = {};
+
+    // global on the server, window in the browser
+    var root = this,
+        previous_async = root.async;
+
+    if (typeof module !== 'undefined' && module.exports) {
+        module.exports = async;
+    }
+    else {
+        root.async = async;
+    }
+
+    async.noConflict = function () {
+        root.async = previous_async;
+        return async;
+    };
+
+    //// cross-browser compatiblity functions ////
+
+    var _forEach = function (arr, iterator) {
+        if (arr.forEach) {
+            return arr.forEach(iterator);
+        }
+        for (var i = 0; i < arr.length; i += 1) {
+            iterator(arr[i], i, arr);
+        }
+    };
+
+    var _map = function (arr, iterator) {
+        if (arr.map) {
+            return arr.map(iterator);
+        }
+        var results = [];
+        _forEach(arr, function (x, i, a) {
+            results.push(iterator(x, i, a));
+        });
+        return results;
+    };
+
+    var _reduce = function (arr, iterator, memo) {
+        if (arr.reduce) {
+            return arr.reduce(iterator, memo);
+        }
+        _forEach(arr, function (x, i, a) {
+            memo = iterator(memo, x, i, a);
+        });
+        return memo;
+    };
+
+    var _keys = function (obj) {
+        if (Object.keys) {
+            return Object.keys(obj);
+        }
+        var keys = [];
+        for (var k in obj) {
+            if (obj.hasOwnProperty(k)) {
+                keys.push(k);
+            }
+        }
+        return keys;
+    };
+
+    var _indexOf = function (arr, item) {
+        if (arr.indexOf) {
+            return arr.indexOf(item);
+        }
+        for (var i = 0; i < arr.length; i += 1) {
+            if (arr[i] === item) {
+                return i;
+            }
+        }
+        return -1;
+    };
+
+    //// exported async module functions ////
+
+    //// nextTick implementation with browser-compatible fallback ////
+    if (typeof process === 'undefined' || !(process.nextTick)) {
+        async.nextTick = function (fn) {
+            setTimeout(fn, 0);
+        };
+    }
+    else {
+        async.nextTick = process.nextTick;
+    }
+
+    async.forEach = function (arr, iterator, callback) {
+        if (!arr.length) {
+            return callback();
+        }
+        var completed = 0;
+        _forEach(arr, function (x) {
+            iterator(x, function (err) {
+                if (err) {
+                    callback(err);
+                    callback = function () {};
+                }
+                else {
+                    completed += 1;
+                    if (completed === arr.length) {
+                        callback();
+                    }
+                }
+            });
+        });
+    };
+
+    async.forEachSeries = function (arr, iterator, callback) {
+        if (!arr.length) {
+            return callback();
+        }
+        var completed = 0;
+        var iterate = function () {
+            iterator(arr[completed], function (err) {
+                if (err) {
+                    callback(err);
+                    callback = function () {};
+                }
+                else {
+                    completed += 1;
+                    if (completed === arr.length) {
+                        callback();
+                    }
+                    else {
+                        iterate();
+                    }
+                }
+            });
+        };
+        iterate();
+    };
+
+
+    var doParallel = function (fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [async.forEach].concat(args));
+        };
+    };
+    var doSeries = function (fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [async.forEachSeries].concat(args));
+        };
+    };
+
+
+    var _asyncMap = function (eachfn, arr, iterator, callback) {
+        var results = [];
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        eachfn(arr, function (x, callback) {
+            iterator(x.value, function (err, v) {
+                results[x.index] = v;
+                callback(err);
+            });
+        }, function (err) {
+            callback(err, results);
+        });
+    };
+    async.map = doParallel(_asyncMap);
+    async.mapSeries = doSeries(_asyncMap);
+
+
+    // reduce only has a series version, as doing reduce in parallel won't
+    // work in many situations.
+    async.reduce = function (arr, memo, iterator, callback) {
+        async.forEachSeries(arr, function (x, callback) {
+            iterator(memo, x, function (err, v) {
+                memo = v;
+                callback(err);
+            });
+        }, function (err) {
+            callback(err, memo);
+        });
+    };
+    // inject alias
+    async.inject = async.reduce;
+    // foldl alias
+    async.foldl = async.reduce;
+
+    async.reduceRight = function (arr, memo, iterator, callback) {
+        var reversed = _map(arr, function (x) {
+            return x;
+        }).reverse();
+        async.reduce(reversed, memo, iterator, callback);
+    };
+    // foldr alias
+    async.foldr = async.reduceRight;
+
+    var _filter = function (eachfn, arr, iterator, callback) {
+        var results = [];
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        eachfn(arr, function (x, callback) {
+            iterator(x.value, function (v) {
+                if (v) {
+                    results.push(x);
+                }
+                callback();
+            });
+        }, function (err) {
+            callback(_map(results.sort(function (a, b) {
+                return a.index - b.index;
+            }), function (x) {
+                return x.value;
+            }));
+        });
+    };
+    async.filter = doParallel(_filter);
+    async.filterSeries = doSeries(_filter);
+    // select alias
+    async.select = async.filter;
+    async.selectSeries = async.filterSeries;
+
+    var _reject = function (eachfn, arr, iterator, callback) {
+        var results = [];
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        eachfn(arr, function (x, callback) {
+            iterator(x.value, function (v) {
+                if (!v) {
+                    results.push(x);
+                }
+                callback();
+            });
+        }, function (err) {
+            callback(_map(results.sort(function (a, b) {
+                return a.index - b.index;
+            }), function (x) {
+                return x.value;
+            }));
+        });
+    };
+    async.reject = doParallel(_reject);
+    async.rejectSeries = doSeries(_reject);
+
+    var _detect = function (eachfn, arr, iterator, main_callback) {
+        eachfn(arr, function (x, callback) {
+            iterator(x, function (result) {
+                if (result) {
+                    main_callback(x);
+                }
+                else {
+                    callback();
+                }
+            });
+        }, function (err) {
+            main_callback();
+        });
+    };
+    async.detect = doParallel(_detect);
+    async.detectSeries = doSeries(_detect);
+
+    async.some = function (arr, iterator, main_callback) {
+        async.forEach(arr, function (x, callback) {
+            iterator(x, function (v) {
+                if (v) {
+                    main_callback(true);
+                    main_callback = function () {};
+                }
+                callback();
+            });
+        }, function (err) {
+            main_callback(false);
+        });
+    };
+    // any alias
+    async.any = async.some;
+
+    async.every = function (arr, iterator, main_callback) {
+        async.forEach(arr, function (x, callback) {
+            iterator(x, function (v) {
+                if (!v) {
+                    main_callback(false);
+                    main_callback = function () {};
+                }
+                callback();
+            });
+        }, function (err) {
+            main_callback(true);
+        });
+    };
+    // all alias
+    async.all = async.every;
+
+    async.sortBy = function (arr, iterator, callback) {
+        async.map(arr, function (x, callback) {
+            iterator(x, function (err, criteria) {
+                if (err) {
+                    callback(err);
+                }
+                else {
+                    callback(null, {value: x, criteria: criteria});
+                }
+            });
+        }, function (err, results) {
+            if (err) {
+                return callback(err);
+            }
+            else {
+                var fn = function (left, right) {
+                    var a = left.criteria, b = right.criteria;
+                    return a < b ? -1 : a > b ? 1 : 0;
+                };
+                callback(null, _map(results.sort(fn), function (x) {
+                    return x.value;
+                }));
+            }
+        });
+    };
+
+    async.auto = function (tasks, callback) {
+        callback = callback || function () {};
+        var keys = _keys(tasks);
+        if (!keys.length) {
+            return callback(null);
+        }
+
+        var completed = [];
+
+        var listeners = [];
+        var addListener = function (fn) {
+            listeners.unshift(fn);
+        };
+        var removeListener = function (fn) {
+            for (var i = 0; i < listeners.length; i += 1) {
+                if (listeners[i] === fn) {
+                    listeners.splice(i, 1);
+                    return;
+                }
+            }
+        };
+        var taskComplete = function () {
+            _forEach(listeners, function (fn) {
+                fn();
+            });
+        };
+
+        addListener(function () {
+            if (completed.length === keys.length) {
+                callback(null);
+            }
+        });
+
+        _forEach(keys, function (k) {
+            var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
+            var taskCallback = function (err) {
+                if (err) {
+                    callback(err);
+                    // stop subsequent errors hitting callback multiple times
+                    callback = function () {};
+                }
+                else {
+                    completed.push(k);
+                    taskComplete();
+                }
+            };
+            var requires = task.slice(0, Math.abs(task.length - 1)) || [];
+            var ready = function () {
+                return _reduce(requires, function (a, x) {
+                    return (a && _indexOf(completed, x) !== -1);
+                }, true);
+            };
+            if (ready()) {
+                task[task.length - 1](taskCallback);
+            }
+            else {
+                var listener = function () {
+                    if (ready()) {
+                        removeListener(listener);
+                        task[task.length - 1](taskCallback);
+                    }
+                };
+                addListener(listener);
+            }
+        });
+    };
+
+    async.waterfall = function (tasks, callback) {
+        if (!tasks.length) {
+            return callback();
+        }
+        callback = callback || function () {};
+        var wrapIterator = function (iterator) {
+            return function (err) {
+                if (err) {
+                    callback(err);
+                    callback = function () {};
+                }
+                else {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    var next = iterator.next();
+                    if (next) {
+                        args.push(wrapIterator(next));
+                    }
+                    else {
+                        args.push(callback);
+                    }
+                    async.nextTick(function () {
+                        iterator.apply(null, args);
+                    });
+                }
+            };
+        };
+        wrapIterator(async.iterator(tasks))();
+    };
+
+    async.parallel = function (tasks, callback) {
+        callback = callback || function () {};
+        if (tasks.constructor === Array) {
+            async.map(tasks, function (fn, callback) {
+                if (fn) {
+                    fn(function (err) {
+                        var args = Array.prototype.slice.call(arguments, 1);
+                        if (args.length <= 1) {
+                            args = args[0];
+                        }
+                        callback.call(null, err, args);
+                    });
+                }
+            }, callback);
+        }
+        else {
+            var results = {};
+            async.forEach(_keys(tasks), function (k, callback) {
+                tasks[k](function (err) {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    if (args.length <= 1) {
+                        args = args[0];
+                    }
+                    results[k] = args;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+
+    async.series = function (tasks, callback) {
+        callback = callback || function () {};
+        if (tasks.constructor === Array) {
+            async.mapSeries(tasks, function (fn, callback) {
+                if (fn) {
+                    fn(function (err) {
+                        var args = Array.prototype.slice.call(arguments, 1);
+                        if (args.length <= 1) {
+                            args = args[0];
+                        }
+                        callback.call(null, err, args);
+                    });
+                }
+            }, callback);
+        }
+        else {
+            var results = {};
+            async.forEachSeries(_keys(tasks), function (k, callback) {
+                tasks[k](function (err) {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    if (args.length <= 1) {
+                        args = args[0];
+                    }
+                    results[k] = args;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+
+    async.iterator = function (tasks) {
+        var makeCallback = function (index) {
+            var fn = function () {
+                if (tasks.length) {
+                    tasks[index].apply(null, arguments);
+                }
+                return fn.next();
+            };
+            fn.next = function () {
+                return (index < tasks.length - 1) ? makeCallback(index + 1): null;
+            };
+            return fn;
+        };
+        return makeCallback(0);
+    };
+
+    async.apply = function (fn) {
+        var args = Array.prototype.slice.call(arguments, 1);
+        return function () {
+            return fn.apply(
+                null, args.concat(Array.prototype.slice.call(arguments))
+            );
+        };
+    };
+
+    var _concat = function (eachfn, arr, fn, callback) {
+        var r = [];
+        eachfn(arr, function (x, cb) {
+            fn(x, function (err, y) {
+                r = r.concat(y || []);
+                cb(err);
+            });
+        }, function (err) {
+            callback(err, r);
+        });
+    };
+    async.concat = doParallel(_concat);
+    async.concatSeries = doSeries(_concat);
+
+    async.whilst = function (test, iterator, callback) {
+        if (test()) {
+            iterator(function (err) {
+                if (err) {
+                    return callback(err);
+                }
+                async.whilst(test, iterator, callback);
+            });
+        }
+        else {
+            callback();
+        }
+    };
+
+    async.until = function (test, iterator, callback) {
+        if (!test()) {
+            iterator(function (err) {
+                if (err) {
+                    return callback(err);
+                }
+                async.until(test, iterator, callback);
+            });
+        }
+        else {
+            callback();
+        }
+    };
+
+    async.queue = function (worker, concurrency) {
+        var workers = 0;
+        var tasks = [];
+        var q = {
+            concurrency: concurrency,
+            saturated: null,
+            empty: null,
+            drain: null,
+            push: function (data, callback) {
+                tasks.push({data: data, callback: callback});
+                if(q.saturated && tasks.length == concurrency) q.saturated();
+                async.nextTick(q.process);
+            },
+            process: function () {
+                if (workers < q.concurrency && tasks.length) {
+                    var task = tasks.splice(0, 1)[0];
+                    if(q.empty && tasks.length == 0) q.empty();
+                    workers += 1;
+                    worker(task.data, function () {
+                        workers -= 1;
+                        if (task.callback) {
+                            task.callback.apply(task, arguments);
+                        }
+                        if(q.drain && tasks.length + workers == 0) q.drain();
+                        q.process();
+                    });
+                }
+            },
+            length: function () {
+                return tasks.length;
+            },
+            running: function () {
+                return workers;
+            }
+        };
+        return q;
+    };
+
+    var _console_fn = function (name) {
+        return function (fn) {
+            var args = Array.prototype.slice.call(arguments, 1);
+            fn.apply(null, args.concat([function (err) {
+                var args = Array.prototype.slice.call(arguments, 1);
+                if (typeof console !== 'undefined') {
+                    if (err) {
+                        if (console.error) {
+                            console.error(err);
+                        }
+                    }
+                    else if (console[name]) {
+                        _forEach(args, function (x) {
+                            console[name](x);
+                        });
+                    }
+                }
+            }]));
+        };
+    };
+    async.log = _console_fn('log');
+    async.dir = _console_fn('dir');
+    /*async.info = _console_fn('info');
+    async.warn = _console_fn('warn');
+    async.error = _console_fn('error');*/
+
+    async.memoize = function (fn, hasher) {
+        var memo = {};
+        hasher = hasher || function (x) {
+            return x;
+        };
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            var callback = args.pop();
+            var key = hasher.apply(null, args);
+            if (key in memo) {
+                callback.apply(null, memo[key]);
+            }
+            else {
+                fn.apply(null, args.concat([function () {
+                    memo[key] = arguments;
+                    callback.apply(null, arguments);
+                }]));
+            }
+        };
+    };
+
+}());
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/nodelint.cfg b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/nodelint.cfg
new file mode 100644 (file)
index 0000000..457a967
--- /dev/null
@@ -0,0 +1,4 @@
+var options = {
+    indent: 4,
+    onevar: false
+};
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/package.json b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/package.json
new file mode 100644 (file)
index 0000000..e5646d7
--- /dev/null
@@ -0,0 +1,41 @@
+{
+  "name": "async",
+  "description": "Higher-order functions and common patterns for asynchronous code",
+  "main": "./index",
+  "author": {
+    "name": "Caolan McMahon"
+  },
+  "version": "0.1.9",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/caolan/async.git"
+  },
+  "bugs": {
+    "url": "http://github.com/caolan/async/issues"
+  },
+  "licenses": [
+    {
+      "type": "MIT",
+      "url": "http://github.com/caolan/async/raw/master/LICENSE"
+    }
+  ],
+  "_npmUser": {
+    "name": "mikeal",
+    "email": "mikeal.rogers@gmail.com"
+  },
+  "_id": "async@0.1.9",
+  "dependencies": {},
+  "devDependencies": {},
+  "optionalDependencies": {},
+  "engines": {
+    "node": "*"
+  },
+  "_engineSupported": true,
+  "_npmVersion": "1.1.24",
+  "_nodeVersion": "v0.8.1",
+  "_defaultsLoaded": true,
+  "dist": {
+    "shasum": "fd9b6aca66495fd0f7e97f86e71c7706ca9ae754"
+  },
+  "_from": "async@0.1.9"
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/test/test-async.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/test/test-async.js
new file mode 100644 (file)
index 0000000..8c2cebd
--- /dev/null
@@ -0,0 +1,1367 @@
+var async = require('../lib/async');
+
+
+exports['auto'] = function(test){
+    var callOrder = [];
+    var testdata = [{test: 'test'}];
+    async.auto({
+        task1: ['task2', function(callback){
+            setTimeout(function(){
+                callOrder.push('task1');
+                callback();
+            }, 25);
+        }],
+        task2: function(callback){
+            setTimeout(function(){
+                callOrder.push('task2');
+                callback();
+            }, 50);
+        },
+        task3: ['task2', function(callback){
+            callOrder.push('task3');
+            callback();
+        }],
+        task4: ['task1', 'task2', function(callback){
+            callOrder.push('task4');
+            callback();
+        }]
+    },
+    function(err){
+        test.same(callOrder, ['task2','task3','task1','task4']);
+        test.done();
+    });
+};
+
+exports['auto empty object'] = function(test){
+    async.auto({}, function(err){
+        test.done();
+    });
+};
+
+exports['auto error'] = function(test){
+    test.expect(1);
+    async.auto({
+        task1: function(callback){
+            callback('testerror');
+        },
+        task2: ['task1', function(callback){
+            test.ok(false, 'task2 should not be called');
+            callback();
+        }],
+        task3: function(callback){
+            callback('testerror2');
+        }
+    },
+    function(err){
+        test.equals(err, 'testerror');
+    });
+    setTimeout(test.done, 100);
+};
+
+exports['auto no callback'] = function(test){
+    async.auto({
+        task1: function(callback){callback();},
+        task2: ['task1', function(callback){callback(); test.done();}]
+    });
+};
+
+exports['waterfall'] = function(test){
+    test.expect(6);
+    var call_order = [];
+    async.waterfall([
+        function(callback){
+            call_order.push('fn1');
+            setTimeout(function(){callback(null, 'one', 'two');}, 0);
+        },
+        function(arg1, arg2, callback){
+            call_order.push('fn2');
+            test.equals(arg1, 'one');
+            test.equals(arg2, 'two');
+            setTimeout(function(){callback(null, arg1, arg2, 'three');}, 25);
+        },
+        function(arg1, arg2, arg3, callback){
+            call_order.push('fn3');
+            test.equals(arg1, 'one');
+            test.equals(arg2, 'two');
+            test.equals(arg3, 'three');
+            callback(null, 'four');
+        },
+        function(arg4, callback){
+            call_order.push('fn4');
+            test.same(call_order, ['fn1','fn2','fn3','fn4']);
+            callback(null, 'test');
+        }
+    ], function(err){
+        test.done();
+    });
+};
+
+exports['waterfall empty array'] = function(test){
+    async.waterfall([], function(err){
+        test.done();
+    });
+};
+
+exports['waterfall no callback'] = function(test){
+    async.waterfall([
+        function(callback){callback();},
+        function(callback){callback(); test.done();}
+    ]);
+};
+
+exports['waterfall async'] = function(test){
+    var call_order = [];
+    async.waterfall([
+        function(callback){
+            call_order.push(1);
+            callback();
+            call_order.push(2);
+        },
+        function(callback){
+            call_order.push(3);
+            callback();
+        },
+        function(){
+            test.same(call_order, [1,2,3]);
+            test.done();
+        }
+    ]);
+};
+
+exports['waterfall error'] = function(test){
+    test.expect(1);
+    async.waterfall([
+        function(callback){
+            callback('error');
+        },
+        function(callback){
+            test.ok(false, 'next function should not be called');
+            callback();
+        }
+    ], function(err){
+        test.equals(err, 'error');
+    });
+    setTimeout(test.done, 50);
+};
+
+exports['waterfall multiple callback calls'] = function(test){
+    var call_order = [];
+    var arr = [
+        function(callback){
+            call_order.push(1);
+            // call the callback twice. this should call function 2 twice
+            callback(null, 'one', 'two');
+            callback(null, 'one', 'two');
+        },
+        function(arg1, arg2, callback){
+            call_order.push(2);
+            callback(null, arg1, arg2, 'three');
+        },
+        function(arg1, arg2, arg3, callback){
+            call_order.push(3);
+            callback(null, 'four');
+        },
+        function(arg4){
+            call_order.push(4);
+            arr[3] = function(){
+                call_order.push(4);
+                test.same(call_order, [1,2,2,3,3,4,4]);
+                test.done();
+            };
+        }
+    ];
+    async.waterfall(arr);
+};
+
+
+exports['parallel'] = function(test){
+    var call_order = [];
+    async.parallel([
+        function(callback){
+            setTimeout(function(){
+                call_order.push(1);
+                callback(null, 1);
+            }, 25);
+        },
+        function(callback){
+            setTimeout(function(){
+                call_order.push(2);
+                callback(null, 2);
+            }, 50);
+        },
+        function(callback){
+            setTimeout(function(){
+                call_order.push(3);
+                callback(null, 3,3);
+            }, 15);
+        }
+    ],
+    function(err, results){
+        test.equals(err, null);
+        test.same(call_order, [3,1,2]);
+        test.same(results, [1,2,[3,3]]);
+        test.done();
+    });
+};
+
+exports['parallel empty array'] = function(test){
+    async.parallel([], function(err, results){
+        test.equals(err, null);
+        test.same(results, []);
+        test.done();
+    });
+};
+
+exports['parallel error'] = function(test){
+    async.parallel([
+        function(callback){
+            callback('error', 1);
+        },
+        function(callback){
+            callback('error2', 2);
+        }
+    ],
+    function(err, results){
+        test.equals(err, 'error');
+    });
+    setTimeout(test.done, 100);
+};
+
+exports['parallel no callback'] = function(test){
+    async.parallel([
+        function(callback){callback();},
+        function(callback){callback(); test.done();},
+    ]);
+};
+
+exports['parallel object'] = function(test){
+    var call_order = [];
+    async.parallel({
+        one: function(callback){
+            setTimeout(function(){
+                call_order.push(1);
+                callback(null, 1);
+            }, 25);
+        },
+        two: function(callback){
+            setTimeout(function(){
+                call_order.push(2);
+                callback(null, 2);
+            }, 50);
+        },
+        three: function(callback){
+            setTimeout(function(){
+                call_order.push(3);
+                callback(null, 3,3);
+            }, 15);
+        }
+    },
+    function(err, results){
+        test.equals(err, null);
+        test.same(call_order, [3,1,2]);
+        test.same(results, {
+            one: 1,
+            two: 2,
+            three: [3,3]
+        });
+        test.done();
+    });
+};
+
+exports['series'] = function(test){
+    var call_order = [];
+    async.series([
+        function(callback){
+            setTimeout(function(){
+                call_order.push(1);
+                callback(null, 1);
+            }, 25);
+        },
+        function(callback){
+            setTimeout(function(){
+                call_order.push(2);
+                callback(null, 2);
+            }, 50);
+        },
+        function(callback){
+            setTimeout(function(){
+                call_order.push(3);
+                callback(null, 3,3);
+            }, 15);
+        }
+    ],
+    function(err, results){
+        test.equals(err, null);
+        test.same(results, [1,2,[3,3]]);
+        test.same(call_order, [1,2,3]);
+        test.done();
+    });
+};
+
+exports['series empty array'] = function(test){
+    async.series([], function(err, results){
+        test.equals(err, null);
+        test.same(results, []);
+        test.done();
+    });
+};
+
+exports['series error'] = function(test){
+    test.expect(1);
+    async.series([
+        function(callback){
+            callback('error', 1);
+        },
+        function(callback){
+            test.ok(false, 'should not be called');
+            callback('error2', 2);
+        }
+    ],
+    function(err, results){
+        test.equals(err, 'error');
+    });
+    setTimeout(test.done, 100);
+};
+
+exports['series no callback'] = function(test){
+    async.series([
+        function(callback){callback();},
+        function(callback){callback(); test.done();},
+    ]);
+};
+
+exports['series object'] = function(test){
+    var call_order = [];
+    async.series({
+        one: function(callback){
+            setTimeout(function(){
+                call_order.push(1);
+                callback(null, 1);
+            }, 25);
+        },
+        two: function(callback){
+            setTimeout(function(){
+                call_order.push(2);
+                callback(null, 2);
+            }, 50);
+        },
+        three: function(callback){
+            setTimeout(function(){
+                call_order.push(3);
+                callback(null, 3,3);
+            }, 15);
+        }
+    },
+    function(err, results){
+        test.equals(err, null);
+        test.same(results, {
+            one: 1,
+            two: 2,
+            three: [3,3]
+        });
+        test.same(call_order, [1,2,3]);
+        test.done();
+    });
+};
+
+exports['iterator'] = function(test){
+    var call_order = [];
+    var iterator = async.iterator([
+        function(){call_order.push(1);},
+        function(arg1){
+            test.equals(arg1, 'arg1');
+            call_order.push(2);
+        },
+        function(arg1, arg2){
+            test.equals(arg1, 'arg1');
+            test.equals(arg2, 'arg2');
+            call_order.push(3);
+        }
+    ]);
+    iterator();
+    test.same(call_order, [1]);
+    var iterator2 = iterator();
+    test.same(call_order, [1,1]);
+    var iterator3 = iterator2('arg1');
+    test.same(call_order, [1,1,2]);
+    var iterator4 = iterator3('arg1', 'arg2');
+    test.same(call_order, [1,1,2,3]);
+    test.equals(iterator4, undefined);
+    test.done();
+};
+
+exports['iterator empty array'] = function(test){
+    var iterator = async.iterator([]);
+    test.equals(iterator(), undefined);
+    test.equals(iterator.next(), undefined);
+    test.done();
+};
+
+exports['iterator.next'] = function(test){
+    var call_order = [];
+    var iterator = async.iterator([
+        function(){call_order.push(1);},
+        function(arg1){
+            test.equals(arg1, 'arg1');
+            call_order.push(2);
+        },
+        function(arg1, arg2){
+            test.equals(arg1, 'arg1');
+            test.equals(arg2, 'arg2');
+            call_order.push(3);
+        }
+    ]);
+    var fn = iterator.next();
+    var iterator2 = fn('arg1');
+    test.same(call_order, [2]);
+    iterator2('arg1','arg2');
+    test.same(call_order, [2,3]);
+    test.equals(iterator2.next(), undefined);
+    test.done();
+};
+
+exports['forEach'] = function(test){
+    var args = [];
+    async.forEach([1,3,2], function(x, callback){
+        setTimeout(function(){
+            args.push(x);
+            callback();
+        }, x*25);
+    }, function(err){
+        test.same(args, [1,2,3]);
+        test.done();
+    });
+};
+
+exports['forEach empty array'] = function(test){
+    test.expect(1);
+    async.forEach([], function(x, callback){
+        test.ok(false, 'iterator should not be called');
+        callback();
+    }, function(err){
+        test.ok(true, 'should call callback');
+    });
+    setTimeout(test.done, 25);
+};
+
+exports['forEach error'] = function(test){
+    test.expect(1);
+    async.forEach([1,2,3], function(x, callback){
+        callback('error');
+    }, function(err){
+        test.equals(err, 'error');
+    });
+    setTimeout(test.done, 50);
+};
+
+exports['forEachSeries'] = function(test){
+    var args = [];
+    async.forEachSeries([1,3,2], function(x, callback){
+        setTimeout(function(){
+            args.push(x);
+            callback();
+        }, x*25);
+    }, function(err){
+        test.same(args, [1,3,2]);
+        test.done();
+    });
+};
+
+exports['forEachSeries empty array'] = function(test){
+    test.expect(1);
+    async.forEachSeries([], function(x, callback){
+        test.ok(false, 'iterator should not be called');
+        callback();
+    }, function(err){
+        test.ok(true, 'should call callback');
+    });
+    setTimeout(test.done, 25);
+};
+
+exports['forEachSeries error'] = function(test){
+    test.expect(2);
+    var call_order = [];
+    async.forEachSeries([1,2,3], function(x, callback){
+        call_order.push(x);
+        callback('error');
+    }, function(err){
+        test.same(call_order, [1]);
+        test.equals(err, 'error');
+    });
+    setTimeout(test.done, 50);
+};
+
+exports['map'] = function(test){
+    var call_order = [];
+    async.map([1,3,2], function(x, callback){
+        setTimeout(function(){
+            call_order.push(x);
+            callback(null, x*2);
+        }, x*25);
+    }, function(err, results){
+        test.same(call_order, [1,2,3]);
+        test.same(results, [2,6,4]);
+        test.done();
+    });
+};
+
+exports['map original untouched'] = function(test){
+    var a = [1,2,3];
+    async.map(a, function(x, callback){
+        callback(null, x*2);
+    }, function(err, results){
+        test.same(results, [2,4,6]);
+        test.same(a, [1,2,3]);
+        test.done();
+    });
+};
+
+exports['map error'] = function(test){
+    test.expect(1);
+    async.map([1,2,3], function(x, callback){
+        callback('error');
+    }, function(err, results){
+        test.equals(err, 'error');
+    });
+    setTimeout(test.done, 50);
+};
+
+exports['mapSeries'] = function(test){
+    var call_order = [];
+    async.mapSeries([1,3,2], function(x, callback){
+        setTimeout(function(){
+            call_order.push(x);
+            callback(null, x*2);
+        }, x*25);
+    }, function(err, results){
+        test.same(call_order, [1,3,2]);
+        test.same(results, [2,6,4]);
+        test.done();
+    });
+};
+
+exports['mapSeries error'] = function(test){
+    test.expect(1);
+    async.mapSeries([1,2,3], function(x, callback){
+        callback('error');
+    }, function(err, results){
+        test.equals(err, 'error');
+    });
+    setTimeout(test.done, 50);
+};
+
+exports['reduce'] = function(test){
+    var call_order = [];
+    async.reduce([1,2,3], 0, function(a, x, callback){
+        call_order.push(x);
+        callback(null, a + x);
+    }, function(err, result){
+        test.equals(result, 6);
+        test.same(call_order, [1,2,3]);
+        test.done();
+    });
+};
+
+exports['reduce async with non-reference memo'] = function(test){
+    async.reduce([1,3,2], 0, function(a, x, callback){
+        setTimeout(function(){callback(null, a + x)}, Math.random()*100);
+    }, function(err, result){
+        test.equals(result, 6);
+        test.done();
+    });
+};
+
+exports['reduce error'] = function(test){
+    test.expect(1);
+    async.reduce([1,2,3], 0, function(a, x, callback){
+        callback('error');
+    }, function(err, result){
+        test.equals(err, 'error');
+    });
+    setTimeout(test.done, 50);
+};
+
+exports['inject alias'] = function(test){
+    test.equals(async.inject, async.reduce);
+    test.done();
+};
+
+exports['foldl alias'] = function(test){
+    test.equals(async.foldl, async.reduce);
+    test.done();
+};
+
+exports['reduceRight'] = function(test){
+    var call_order = [];
+    var a = [1,2,3];
+    async.reduceRight(a, 0, function(a, x, callback){
+        call_order.push(x);
+        callback(null, a + x);
+    }, function(err, result){
+        test.equals(result, 6);
+        test.same(call_order, [3,2,1]);
+        test.same(a, [1,2,3]);
+        test.done();
+    });
+};
+
+exports['foldr alias'] = function(test){
+    test.equals(async.foldr, async.reduceRight);
+    test.done();
+};
+
+exports['filter'] = function(test){
+    async.filter([3,1,2], function(x, callback){
+        setTimeout(function(){callback(x % 2);}, x*25);
+    }, function(results){
+        test.same(results, [3,1]);
+        test.done();
+    });
+};
+
+exports['filter original untouched'] = function(test){
+    var a = [3,1,2];
+    async.filter(a, function(x, callback){
+        callback(x % 2);
+    }, function(results){
+        test.same(results, [3,1]);
+        test.same(a, [3,1,2]);
+        test.done();
+    });
+};
+
+exports['filterSeries'] = function(test){
+    async.filterSeries([3,1,2], function(x, callback){
+        setTimeout(function(){callback(x % 2);}, x*25);
+    }, function(results){
+        test.same(results, [3,1]);
+        test.done();
+    });
+};
+
+exports['select alias'] = function(test){
+    test.equals(async.select, async.filter);
+    test.done();
+};
+
+exports['selectSeries alias'] = function(test){
+    test.equals(async.selectSeries, async.filterSeries);
+    test.done();
+};
+
+exports['reject'] = function(test){
+    async.reject([3,1,2], function(x, callback){
+        setTimeout(function(){callback(x % 2);}, x*25);
+    }, function(results){
+        test.same(results, [2]);
+        test.done();
+    });
+};
+
+exports['reject original untouched'] = function(test){
+    var a = [3,1,2];
+    async.reject(a, function(x, callback){
+        callback(x % 2);
+    }, function(results){
+        test.same(results, [2]);
+        test.same(a, [3,1,2]);
+        test.done();
+    });
+};
+
+exports['rejectSeries'] = function(test){
+    async.rejectSeries([3,1,2], function(x, callback){
+        setTimeout(function(){callback(x % 2);}, x*25);
+    }, function(results){
+        test.same(results, [2]);
+        test.done();
+    });
+};
+
+exports['some true'] = function(test){
+    async.some([3,1,2], function(x, callback){
+        setTimeout(function(){callback(x === 1);}, 0);
+    }, function(result){
+        test.equals(result, true);
+        test.done();
+    });
+};
+
+exports['some false'] = function(test){
+    async.some([3,1,2], function(x, callback){
+        setTimeout(function(){callback(x === 10);}, 0);
+    }, function(result){
+        test.equals(result, false);
+        test.done();
+    });
+};
+
+exports['some early return'] = function(test){
+    var call_order = [];
+    async.some([1,2,3], function(x, callback){
+        setTimeout(function(){
+            call_order.push(x);
+            callback(x === 1);
+        }, x*25);
+    }, function(result){
+        call_order.push('callback');
+    });
+    setTimeout(function(){
+        test.same(call_order, [1,'callback',2,3]);
+        test.done();
+    }, 100);
+};
+
+exports['any alias'] = function(test){
+    test.equals(async.any, async.some);
+    test.done();
+};
+
+exports['every true'] = function(test){
+    async.every([1,2,3], function(x, callback){
+        setTimeout(function(){callback(true);}, 0);
+    }, function(result){
+        test.equals(result, true);
+        test.done();
+    });
+};
+
+exports['every false'] = function(test){
+    async.every([1,2,3], function(x, callback){
+        setTimeout(function(){callback(x % 2);}, 0);
+    }, function(result){
+        test.equals(result, false);
+        test.done();
+    });
+};
+
+exports['every early return'] = function(test){
+    var call_order = [];
+    async.every([1,2,3], function(x, callback){
+        setTimeout(function(){
+            call_order.push(x);
+            callback(x === 1);
+        }, x*25);
+    }, function(result){
+        call_order.push('callback');
+    });
+    setTimeout(function(){
+        test.same(call_order, [1,2,'callback',3]);
+        test.done();
+    }, 100);
+};
+
+exports['all alias'] = function(test){
+    test.equals(async.all, async.every);
+    test.done();
+};
+
+exports['detect'] = function(test){
+    var call_order = [];
+    async.detect([3,2,1], function(x, callback){
+        setTimeout(function(){
+            call_order.push(x);
+            callback(x == 2);
+        }, x*25);
+    }, function(result){
+        call_order.push('callback');
+        test.equals(result, 2);
+    });
+    setTimeout(function(){
+        test.same(call_order, [1,2,'callback',3]);
+        test.done();
+    }, 100);
+};
+
+exports['detectSeries'] = function(test){
+    var call_order = [];
+    async.detectSeries([3,2,1], function(x, callback){
+        setTimeout(function(){
+            call_order.push(x);
+            callback(x == 2);
+        }, x*25);
+    }, function(result){
+        call_order.push('callback');
+        test.equals(result, 2);
+    });
+    setTimeout(function(){
+        test.same(call_order, [3,2,'callback']);
+        test.done();
+    }, 200);
+};
+
+exports['sortBy'] = function(test){
+    async.sortBy([{a:1},{a:15},{a:6}], function(x, callback){
+        setTimeout(function(){callback(null, x.a);}, 0);
+    }, function(err, result){
+        test.same(result, [{a:1},{a:6},{a:15}]);
+        test.done();
+    });
+};
+
+exports['apply'] = function(test){
+    test.expect(6);
+    var fn = function(){
+        test.same(Array.prototype.slice.call(arguments), [1,2,3,4])
+    };
+    async.apply(fn, 1, 2, 3, 4)();
+    async.apply(fn, 1, 2, 3)(4);
+    async.apply(fn, 1, 2)(3, 4);
+    async.apply(fn, 1)(2, 3, 4);
+    async.apply(fn)(1, 2, 3, 4);
+    test.equals(
+        async.apply(function(name){return 'hello ' + name}, 'world')(),
+        'hello world'
+    );
+    test.done();
+};
+
+
+// generates tests for console functions such as async.log
+var console_fn_tests = function(name){
+
+    if (typeof console !== 'undefined') {
+        exports[name] = function(test){
+            test.expect(5);
+            var fn = function(arg1, callback){
+                test.equals(arg1, 'one');
+                setTimeout(function(){callback(null, 'test');}, 0);
+            };
+            var fn_err = function(arg1, callback){
+                test.equals(arg1, 'one');
+                setTimeout(function(){callback('error');}, 0);
+            };
+            var _console_fn = console[name];
+            var _error = console.error;
+            console[name] = function(val){
+                test.equals(val, 'test');
+                test.equals(arguments.length, 1);
+                console.error = function(val){
+                    test.equals(val, 'error');
+                    console[name] = _console_fn;
+                    console.error = _error;
+                    test.done();
+                };
+                async[name](fn_err, 'one');
+            };
+            async[name](fn, 'one');
+        };
+
+        exports[name + ' with multiple result params'] = function(test){
+            var fn = function(callback){callback(null,'one','two','three');};
+            var _console_fn = console[name];
+            var called_with = [];
+            console[name] = function(x){
+                called_with.push(x);
+            };
+            async[name](fn);
+            test.same(called_with, ['one','two','three']);
+            console[name] = _console_fn;
+            test.done();
+        };
+    }
+
+    // browser-only test
+    exports[name + ' without console.' + name] = function(test){
+        if (typeof window !== 'undefined') {
+            var _console = window.console;
+            window.console = undefined;
+            var fn = function(callback){callback(null, 'val');};
+            var fn_err = function(callback){callback('error');};
+            async[name](fn);
+            async[name](fn_err);
+            window.console = _console;
+        }
+        test.done();
+    };
+
+};
+
+console_fn_tests('log');
+console_fn_tests('dir');
+/*console_fn_tests('info');
+console_fn_tests('warn');
+console_fn_tests('error');*/
+
+exports['nextTick'] = function(test){
+    var call_order = [];
+    async.nextTick(function(){call_order.push('two');});
+    call_order.push('one');
+    setTimeout(function(){
+        test.same(call_order, ['one','two']);
+        test.done();
+    }, 50);
+};
+
+exports['nextTick in the browser'] = function(test){
+    if (typeof process !== 'undefined') {
+        // skip this test in node
+        return test.done();
+    }
+    test.expect(1);
+
+    var call_order = [];
+    async.nextTick(function(){call_order.push('two');});
+
+    call_order.push('one');
+    setTimeout(function(){
+        if (typeof process !== 'undefined') {
+            process.nextTick = _nextTick;
+        }
+        test.same(call_order, ['one','two']);
+    }, 50);
+    setTimeout(test.done, 100);
+};
+
+exports['noConflict - node only'] = function(test){
+    if (typeof process !== 'undefined') {
+        // node only test
+        test.expect(3);
+        var fs = require('fs');
+        var filename = __dirname + '/../lib/async.js';
+        fs.readFile(filename, function(err, content){
+            if(err) return test.done();
+            var Script = process.binding('evals').Script;
+
+            var s = new Script(content, filename);
+            var s2 = new Script(
+                content + 'this.async2 = this.async.noConflict();',
+                filename
+            );
+
+            var sandbox1 = {async: 'oldvalue'};
+            s.runInNewContext(sandbox1);
+            test.ok(sandbox1.async);
+
+            var sandbox2 = {async: 'oldvalue'};
+            s2.runInNewContext(sandbox2);
+            test.equals(sandbox2.async, 'oldvalue');
+            test.ok(sandbox2.async2);
+
+            test.done();
+        });
+    }
+    else test.done();
+};
+
+exports['concat'] = function(test){
+    var call_order = [];
+    var iterator = function (x, cb) {
+        setTimeout(function(){
+            call_order.push(x);
+            var r = [];
+            while (x > 0) {
+                r.push(x);
+                x--;
+            }
+            cb(null, r);
+        }, x*25);
+    };
+    async.concat([1,3,2], iterator, function(err, results){
+        test.same(results, [1,2,1,3,2,1]);
+        test.same(call_order, [1,2,3]);
+        test.ok(!err);
+        test.done();
+    });
+};
+
+exports['concat error'] = function(test){
+    var iterator = function (x, cb) {
+        cb(new Error('test error'));
+    };
+    async.concat([1,2,3], iterator, function(err, results){
+        test.ok(err);
+        test.done();
+    });
+};
+
+exports['concatSeries'] = function(test){
+    var call_order = [];
+    var iterator = function (x, cb) {
+        setTimeout(function(){
+            call_order.push(x);
+            var r = [];
+            while (x > 0) {
+                r.push(x);
+                x--;
+            }
+            cb(null, r);
+        }, x*25);
+    };
+    async.concatSeries([1,3,2], iterator, function(err, results){
+        test.same(results, [1,3,2,1,2,1]);
+        test.same(call_order, [1,3,2]);
+        test.ok(!err);
+        test.done();
+    });
+};
+
+exports['until'] = function (test) {
+    var call_order = [];
+
+    var count = 0;
+    async.until(
+        function () {
+            call_order.push(['test', count]);
+            return (count == 5);
+        },
+        function (cb) {
+            call_order.push(['iterator', count]);
+            count++;
+            cb();
+        },
+        function (err) {
+            test.same(call_order, [
+                ['test', 0],
+                ['iterator', 0], ['test', 1],
+                ['iterator', 1], ['test', 2],
+                ['iterator', 2], ['test', 3],
+                ['iterator', 3], ['test', 4],
+                ['iterator', 4], ['test', 5],
+            ]);
+            test.equals(count, 5);
+            test.done();
+        }
+    );
+};
+
+exports['whilst'] = function (test) {
+    var call_order = [];
+
+    var count = 0;
+    async.whilst(
+        function () {
+            call_order.push(['test', count]);
+            return (count < 5);
+        },
+        function (cb) {
+            call_order.push(['iterator', count]);
+            count++;
+            cb();
+        },
+        function (err) {
+            test.same(call_order, [
+                ['test', 0],
+                ['iterator', 0], ['test', 1],
+                ['iterator', 1], ['test', 2],
+                ['iterator', 2], ['test', 3],
+                ['iterator', 3], ['test', 4],
+                ['iterator', 4], ['test', 5],
+            ]);
+            test.equals(count, 5);
+            test.done();
+        }
+    );
+};
+
+exports['queue'] = function (test) {
+    var call_order = [],
+        delays = [40,20,60,20];
+
+    // worker1: --1-4
+    // worker2: -2---3
+    // order of completion: 2,1,4,3
+
+    var q = async.queue(function (task, callback) {
+        setTimeout(function () {
+            call_order.push('process ' + task);
+            callback('error', 'arg');
+        }, delays.splice(0,1)[0]);
+    }, 2);
+
+    q.push(1, function (err, arg) {
+        test.equal(err, 'error');
+        test.equal(arg, 'arg');
+        test.equal(q.length(), 1);
+        call_order.push('callback ' + 1);
+    });
+    q.push(2, function (err, arg) {
+        test.equal(err, 'error');
+        test.equal(arg, 'arg');
+        test.equal(q.length(), 2);
+        call_order.push('callback ' + 2);
+    });
+    q.push(3, function (err, arg) {
+        test.equal(err, 'error');
+        test.equal(arg, 'arg');
+        test.equal(q.length(), 0);
+        call_order.push('callback ' + 3);
+    });
+    q.push(4, function (err, arg) {
+        test.equal(err, 'error');
+        test.equal(arg, 'arg');
+        test.equal(q.length(), 0);
+        call_order.push('callback ' + 4);
+    });
+    test.equal(q.length(), 4);
+    test.equal(q.concurrency, 2);
+
+    setTimeout(function () {
+        test.same(call_order, [
+            'process 2', 'callback 2',
+            'process 1', 'callback 1',
+            'process 4', 'callback 4',
+            'process 3', 'callback 3'
+        ]);
+        test.equal(q.concurrency, 2);
+        test.equal(q.length(), 0);
+        test.done();
+    }, 200);
+};
+
+exports['queue changing concurrency'] = function (test) {
+    var call_order = [],
+        delays = [40,20,60,20];
+
+    // worker1: --1-2---3-4
+    // order of completion: 1,2,3,4
+
+    var q = async.queue(function (task, callback) {
+        setTimeout(function () {
+            call_order.push('process ' + task);
+            callback('error', 'arg');
+        }, delays.splice(0,1)[0]);
+    }, 2);
+
+    q.push(1, function (err, arg) {
+        test.equal(err, 'error');
+        test.equal(arg, 'arg');
+        test.equal(q.length(), 3);
+        call_order.push('callback ' + 1);
+    });
+    q.push(2, function (err, arg) {
+        test.equal(err, 'error');
+        test.equal(arg, 'arg');
+        test.equal(q.length(), 2);
+        call_order.push('callback ' + 2);
+    });
+    q.push(3, function (err, arg) {
+        test.equal(err, 'error');
+        test.equal(arg, 'arg');
+        test.equal(q.length(), 1);
+        call_order.push('callback ' + 3);
+    });
+    q.push(4, function (err, arg) {
+        test.equal(err, 'error');
+        test.equal(arg, 'arg');
+        test.equal(q.length(), 0);
+        call_order.push('callback ' + 4);
+    });
+    test.equal(q.length(), 4);
+    test.equal(q.concurrency, 2);
+    q.concurrency = 1;
+
+    setTimeout(function () {
+        test.same(call_order, [
+            'process 1', 'callback 1',
+            'process 2', 'callback 2',
+            'process 3', 'callback 3',
+            'process 4', 'callback 4'
+        ]);
+        test.equal(q.concurrency, 1);
+        test.equal(q.length(), 0);
+        test.done();
+    }, 250);
+};
+
+exports['queue push without callback'] = function (test) {
+    var call_order = [],
+        delays = [40,20,60,20];
+
+    // worker1: --1-4
+    // worker2: -2---3
+    // order of completion: 2,1,4,3
+
+    var q = async.queue(function (task, callback) {
+        setTimeout(function () {
+            call_order.push('process ' + task);
+            callback('error', 'arg');
+        }, delays.splice(0,1)[0]);
+    }, 2);
+
+    q.push(1);
+    q.push(2);
+    q.push(3);
+    q.push(4);
+
+    setTimeout(function () {
+        test.same(call_order, [
+            'process 2',
+            'process 1',
+            'process 4',
+            'process 3'
+        ]);
+        test.done();
+    }, 200);
+};
+
+exports['memoize'] = function (test) {
+    test.expect(4);
+    var call_order = [];
+
+    var fn = function (arg1, arg2, callback) {
+        call_order.push(['fn', arg1, arg2]);
+        callback(null, arg1 + arg2);
+    };
+
+    var fn2 = async.memoize(fn);
+    fn2(1, 2, function (err, result) {
+        test.equal(result, 3);
+    });
+    fn2(1, 2, function (err, result) {
+        test.equal(result, 3);
+    });
+    fn2(2, 2, function (err, result) {
+        test.equal(result, 4);
+    });
+
+    test.same(call_order, [['fn',1,2], ['fn',2,2]]);
+    test.done();
+};
+
+exports['memoize error'] = function (test) {
+    test.expect(1);
+    var testerr = new Error('test');
+    var fn = function (arg1, arg2, callback) {
+        callback(testerr, arg1 + arg2);
+    };
+    async.memoize(fn)(1, 2, function (err, result) {
+        test.equal(err, testerr);
+    });
+    test.done();
+};
+
+exports['memoize custom hash function'] = function (test) {
+    test.expect(2);
+    var testerr = new Error('test');
+
+    var fn = function (arg1, arg2, callback) {
+        callback(testerr, arg1 + arg2);
+    };
+    var fn2 = async.memoize(fn, function () {
+        return 'custom hash';
+    });
+    fn2(1, 2, function (err, result) {
+        test.equal(result, 3);
+    });
+    fn2(2, 2, function (err, result) {
+        test.equal(result, 3);
+    });
+    test.done();
+};
+
+// Issue 10 on github: https://github.com/caolan/async/issues#issue/10
+exports['falsy return values in series'] = function (test) {
+    function taskFalse(callback) {
+        async.nextTick(function() {
+            callback(null, false);
+        });
+    };
+    function taskUndefined(callback) {
+        async.nextTick(function() {
+            callback(null, undefined);
+        });
+    };
+    function taskEmpty(callback) {
+        async.nextTick(function() {
+            callback(null);
+        });
+    };
+    function taskNull(callback) {
+        async.nextTick(function() {
+            callback(null, null);
+        });
+    };
+    async.series(
+        [taskFalse, taskUndefined, taskEmpty, taskNull],
+        function(err, results) {
+            test.same(results, [false, undefined, undefined, null]);
+            test.strictEqual(results[0], false);
+            test.strictEqual(results[1], undefined);
+            test.strictEqual(results[2], undefined);
+            test.strictEqual(results[3], null);
+            test.done();
+        }
+    );
+};
+
+// Issue 10 on github: https://github.com/caolan/async/issues#issue/10
+exports['falsy return values in parallel'] = function (test) {
+    function taskFalse(callback) {
+        async.nextTick(function() {
+            callback(null, false);
+        });
+    };
+    function taskUndefined(callback) {
+        async.nextTick(function() {
+            callback(null, undefined);
+        });
+    };
+    function taskEmpty(callback) {
+        async.nextTick(function() {
+            callback(null);
+        });
+    };
+    function taskNull(callback) {
+        async.nextTick(function() {
+            callback(null, null);
+        });
+    };
+    async.parallel(
+        [taskFalse, taskUndefined, taskEmpty, taskNull],
+        function(err, results) {
+            test.same(results, [false, undefined, undefined, null]);
+            test.strictEqual(results[0], false);
+            test.strictEqual(results[1], undefined);
+            test.strictEqual(results[2], undefined);
+            test.strictEqual(results[3], null);
+            test.done();
+        }
+    );
+};
+
+exports['queue events'] = function(test) {
+    var calls = [];
+    var q = async.queue(function(task, cb) {
+        // nop
+        calls.push('process ' + task);
+        cb();
+    }, 3);
+
+    q.saturated = function() {
+        test.ok(q.length() == 3, 'queue should be saturated now');
+        calls.push('saturated');
+    };
+    q.empty = function() {
+        test.ok(q.length() == 0, 'queue should be empty now');
+        calls.push('empty');
+    };
+    q.drain = function() {
+        test.ok(
+            q.length() == 0 && q.running() == 0,
+            'queue should be empty now and no more workers should be running'
+        );
+        calls.push('drain');
+        test.same(calls, [
+            'saturated',
+            'process foo',
+            'foo cb',
+            'process bar',
+            'bar cb',
+            'process zoo',
+            'zoo cb',
+            'process poo',
+            'poo cb',
+            'empty',
+            'process moo',
+            'moo cb',
+            'drain',
+        ]);
+        test.done();
+    };
+    q.push('foo', function () {calls.push('foo cb');});
+    q.push('bar', function () {calls.push('bar cb');});
+    q.push('zoo', function () {calls.push('zoo cb');});
+    q.push('poo', function () {calls.push('poo cb');});
+    q.push('moo', function () {calls.push('moo cb');});
+};
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/test/test.html b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/async/test/test.html
new file mode 100644 (file)
index 0000000..2450e2d
--- /dev/null
@@ -0,0 +1,24 @@
+<html>
+  <head>
+    <title>Async.js Test Suite</title>
+    <!--
+      async must be included after nodeunit because nodeunit already uses
+      the async lib internally and will overwrite the version we want to test
+    -->
+    <script src="../deps/nodeunit.js"></script>
+    <script src="../lib/async.js"></script>
+    <link rel="stylesheet" href="../deps/nodeunit.css" type="text/css" media="screen" />
+    <script>
+      var _async = this.async;
+      this.require = function () { return _async; };
+      this.exports = {};
+    </script>
+    <script src="test-async.js"></script>
+  </head>
+  <body>
+    <h1 id="nodeunit-header">Async.js Test Suite</h1>
+    <script>
+      nodeunit.run({'test-async': exports});
+    </script>
+  </body>
+</html>
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/.npmignore b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/.npmignore
new file mode 100644 (file)
index 0000000..aba34f0
--- /dev/null
@@ -0,0 +1,3 @@
+*.un~
+/node_modules
+/test/tmp
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/License b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/License
new file mode 100644 (file)
index 0000000..4804b7a
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2011 Debuggable Limited <felix@debuggable.com>
+
+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.
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/Makefile b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/Makefile
new file mode 100644 (file)
index 0000000..b4ff85a
--- /dev/null
@@ -0,0 +1,7 @@
+SHELL := /bin/bash
+
+test:
+       @./test/run.js
+
+.PHONY: test
+
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md
new file mode 100644 (file)
index 0000000..1a9999e
--- /dev/null
@@ -0,0 +1,132 @@
+# combined-stream
+
+A stream that emits multiple other streams one after another.
+
+## Installation
+
+``` bash
+npm install combined-stream
+```
+
+## Usage
+
+Here is a simple example that shows how you can use combined-stream to combine
+two files into one:
+
+``` javascript
+var CombinedStream = require('combined-stream');
+var fs = require('fs');
+
+var combinedStream = CombinedStream.create();
+combinedStream.append(fs.createReadStream('file1.txt'));
+combinedStream.append(fs.createReadStream('file2.txt'));
+
+combinedStream.pipe(fs.createWriteStream('combined.txt'));
+```
+
+While the example above works great, it will pause all source streams until
+they are needed. If you don't want that to happen, you can set `pauseStreams`
+to `false`:
+
+``` javascript
+var CombinedStream = require('combined-stream');
+var fs = require('fs');
+
+var combinedStream = CombinedStream.create({pauseStreams: false});
+combinedStream.append(fs.createReadStream('file1.txt'));
+combinedStream.append(fs.createReadStream('file2.txt'));
+
+combinedStream.pipe(fs.createWriteStream('combined.txt'));
+```
+
+However, what if you don't have all the source streams yet, or you don't want
+to allocate the resources (file descriptors, memory, etc.) for them right away?
+Well, in that case you can simply provide a callback that supplies the stream
+by calling a `next()` function:
+
+``` javascript
+var CombinedStream = require('combined-stream');
+var fs = require('fs');
+
+var combinedStream = CombinedStream.create();
+combinedStream.append(function(next) {
+  next(fs.createReadStream('file1.txt'));
+});
+combinedStream.append(function(next) {
+  next(fs.createReadStream('file2.txt'));
+});
+
+combinedStream.pipe(fs.createWriteStream('combined.txt'));
+```
+
+## API
+
+### CombinedStream.create([options])
+
+Returns a new combined stream object. Available options are:
+
+* `maxDataSize`
+* `pauseStreams`
+
+The effect of those options is described below.
+
+### combinedStream.pauseStreams = true
+
+Whether to apply back pressure to the underlaying streams. If set to `false`,
+the underlaying streams will never be paused. If set to `true`, the
+underlaying streams will be paused right after being appended, as well as when
+`delayedStream.pipe()` wants to throttle.
+
+### combinedStream.maxDataSize = 2 * 1024 * 1024
+
+The maximum amount of bytes (or characters) to buffer for all source streams.
+If this value is exceeded, `combinedStream` emits an `'error'` event.
+
+### combinedStream.dataSize = 0
+
+The amount of bytes (or characters) currently buffered by `combinedStream`.
+
+### combinedStream.append(stream)
+
+Appends the given `stream` to the combinedStream object. If `pauseStreams` is
+set to `true, this stream will also be paused right away.
+
+`streams` can also be a function that takes one parameter called `next`. `next`
+is a function that must be invoked in order to provide the `next` stream, see
+example above.
+
+Regardless of how the `stream` is appended, combined-stream always attaches an
+`'error'` listener to it, so you don't have to do that manually.
+
+Special case: `stream` can also be a String or Buffer.
+
+### combinedStream.write(data)
+
+You should not call this, `combinedStream` takes care of piping the appended
+streams into itself for you.
+
+### combinedStream.resume()
+
+Causes `combinedStream` to start drain the streams it manages. The function is
+idempotent, and also emits a `'resume'` event each time which usually goes to
+the stream that is currently being drained.
+
+### combinedStream.pause();
+
+If `combinedStream.pauseStreams` is set to `false`, this does nothing.
+Otherwise a `'pause'` event is emitted, this goes to the stream that is
+currently being drained, so you can use it to apply back pressure.
+
+### combinedStream.end();
+
+Sets `combinedStream.writable` to false, emits an `'end'` event, and removes
+all streams from the queue.
+
+### combinedStream.destroy();
+
+Same as `combinedStream.end()`, except it emits a `'close'` event instead of
+`'end'`.
+
+## License
+
+combined-stream is licensed under the MIT license.
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js
new file mode 100644 (file)
index 0000000..03754e6
--- /dev/null
@@ -0,0 +1,183 @@
+var util = require('util');
+var Stream = require('stream').Stream;
+var DelayedStream = require('delayed-stream');
+
+module.exports = CombinedStream;
+function CombinedStream() {
+  this.writable = false;
+  this.readable = true;
+  this.dataSize = 0;
+  this.maxDataSize = 2 * 1024 * 1024;
+  this.pauseStreams = true;
+
+  this._released = false;
+  this._streams = [];
+  this._currentStream = null;
+}
+util.inherits(CombinedStream, Stream);
+
+CombinedStream.create = function(options) {
+  var combinedStream = new this();
+
+  options = options || {};
+  for (var option in options) {
+    combinedStream[option] = options[option];
+  }
+
+  return combinedStream;
+};
+
+CombinedStream.isStreamLike = function(stream) {
+  return (typeof stream !== 'function')
+    && (typeof stream !== 'string')
+    && (!Buffer.isBuffer(stream));
+};
+
+CombinedStream.prototype.append = function(stream) {
+  var isStreamLike = CombinedStream.isStreamLike(stream);
+
+  if (isStreamLike) {
+    if (!(stream instanceof DelayedStream)) {
+      stream.on('data', this._checkDataSize.bind(this));
+
+      stream = DelayedStream.create(stream, {
+        maxDataSize: Infinity,
+        pauseStream: this.pauseStreams,
+      });
+    }
+
+    this._handleErrors(stream);
+
+    if (this.pauseStreams) {
+      stream.pause();
+    }
+  }
+
+  this._streams.push(stream);
+  return this;
+};
+
+CombinedStream.prototype.pipe = function(dest, options) {
+  Stream.prototype.pipe.call(this, dest, options);
+  this.resume();
+};
+
+CombinedStream.prototype._getNext = function() {
+  this._currentStream = null;
+  var stream = this._streams.shift();
+
+
+  if (!stream) {
+    this.end();
+    return;
+  }
+
+  if (typeof stream !== 'function') {
+    this._pipeNext(stream);
+    return;
+  }
+
+  var getStream = stream;
+  getStream(function(stream) {
+    var isStreamLike = CombinedStream.isStreamLike(stream);
+    if (isStreamLike) {
+      stream.on('data', this._checkDataSize.bind(this));
+      this._handleErrors(stream);
+    }
+
+    this._pipeNext(stream);
+  }.bind(this));
+};
+
+CombinedStream.prototype._pipeNext = function(stream) {
+  this._currentStream = stream;
+
+  var isStreamLike = CombinedStream.isStreamLike(stream);
+  if (isStreamLike) {
+    stream.on('end', this._getNext.bind(this))
+    stream.pipe(this, {end: false});
+    return;
+  }
+
+  var value = stream;
+  this.write(value);
+  this._getNext();
+};
+
+CombinedStream.prototype._handleErrors = function(stream) {
+  var self = this;
+  stream.on('error', function(err) {
+    self._emitError(err);
+  });
+};
+
+CombinedStream.prototype.write = function(data) {
+  this.emit('data', data);
+};
+
+CombinedStream.prototype.pause = function() {
+  if (!this.pauseStreams) {
+    return;
+  }
+
+  this.emit('pause');
+};
+
+CombinedStream.prototype.resume = function() {
+  if (!this._released) {
+    this._released = true;
+    this.writable = true;
+    this._getNext();
+  }
+
+  this.emit('resume');
+};
+
+CombinedStream.prototype.end = function() {
+  this._reset();
+  this.emit('end');
+};
+
+CombinedStream.prototype.destroy = function() {
+  this._reset();
+  this.emit('close');
+};
+
+CombinedStream.prototype._reset = function() {
+  this.writable = false;
+  this._streams = [];
+  this._currentStream = null;
+};
+
+CombinedStream.prototype._checkDataSize = function() {
+  this._updateDataSize();
+  if (this.dataSize <= this.maxDataSize) {
+    return;
+  }
+
+  var message =
+    'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'
+  this._emitError(new Error(message));
+};
+
+CombinedStream.prototype._updateDataSize = function() {
+  this.dataSize = 0;
+
+  var self = this;
+  this._streams.forEach(function(stream) {
+    if (!stream.dataSize) {
+      return;
+    }
+
+    self.dataSize += stream.dataSize;
+  });
+
+  if (this._currentStream && this._currentStream.dataSize) {
+    this.dataSize += this._currentStream.dataSize;
+  }
+};
+
+CombinedStream.prototype._emitError = function(err) {
+  this._reset();
+  this.emit('error', err);
+};
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore
new file mode 100644 (file)
index 0000000..2fedb26
--- /dev/null
@@ -0,0 +1,2 @@
+*.un~
+/node_modules/*
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License
new file mode 100644 (file)
index 0000000..4804b7a
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2011 Debuggable Limited <felix@debuggable.com>
+
+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.
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile
new file mode 100644 (file)
index 0000000..b4ff85a
--- /dev/null
@@ -0,0 +1,7 @@
+SHELL := /bin/bash
+
+test:
+       @./test/run.js
+
+.PHONY: test
+
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md
new file mode 100644 (file)
index 0000000..5cb5b35
--- /dev/null
@@ -0,0 +1,154 @@
+# delayed-stream
+
+Buffers events from a stream until you are ready to handle them.
+
+## Installation
+
+``` bash
+npm install delayed-stream
+```
+
+## Usage
+
+The following example shows how to write a http echo server that delays its
+response by 1000 ms.
+
+``` javascript
+var DelayedStream = require('delayed-stream');
+var http = require('http');
+
+http.createServer(function(req, res) {
+  var delayed = DelayedStream.create(req);
+
+  setTimeout(function() {
+    res.writeHead(200);
+    delayed.pipe(res);
+  }, 1000);
+});
+```
+
+If you are not using `Stream#pipe`, you can also manually release the buffered
+events by calling `delayedStream.resume()`:
+
+``` javascript
+var delayed = DelayedStream.create(req);
+
+setTimeout(function() {
+  // Emit all buffered events and resume underlaying source
+  delayed.resume();
+}, 1000);
+```
+
+## Implementation
+
+In order to use this meta stream properly, here are a few things you should
+know about the implementation.
+
+### Event Buffering / Proxying
+
+All events of the `source` stream are hijacked by overwriting the `source.emit`
+method. Until node implements a catch-all event listener, this is the only way.
+
+However, delayed-stream still continues to emit all events it captures on the
+`source`, regardless of whether you have released the delayed stream yet or
+not.
+
+Upon creation, delayed-stream captures all `source` events and stores them in
+an internal event buffer. Once `delayedStream.release()` is called, all
+buffered events are emitted on the `delayedStream`, and the event buffer is
+cleared. After that, delayed-stream merely acts as a proxy for the underlaying
+source.
+
+### Error handling
+
+Error events on `source` are buffered / proxied just like any other events.
+However, `delayedStream.create` attaches a no-op `'error'` listener to the
+`source`. This way you only have to handle errors on the `delayedStream`
+object, rather than in two places.
+
+### Buffer limits
+
+delayed-stream provides a `maxDataSize` property that can be used to limit
+the amount of data being buffered. In order to protect you from bad `source`
+streams that don't react to `source.pause()`, this feature is enabled by
+default.
+
+## API
+
+### DelayedStream.create(source, [options])
+
+Returns a new `delayedStream`. Available options are:
+
+* `pauseStream`
+* `maxDataSize`
+
+The description for those properties can be found below.
+
+### delayedStream.source
+
+The `source` stream managed by this object. This is useful if you are
+passing your `delayedStream` around, and you still want to access properties
+on the `source` object.
+
+### delayedStream.pauseStream = true
+
+Whether to pause the underlaying `source` when calling
+`DelayedStream.create()`. Modifying this property afterwards has no effect.
+
+### delayedStream.maxDataSize = 1024 * 1024
+
+The amount of data to buffer before emitting an `error`.
+
+If the underlaying source is emitting `Buffer` objects, the `maxDataSize`
+refers to bytes.
+
+If the underlaying source is emitting JavaScript strings, the size refers to
+characters.
+
+If you know what you are doing, you can set this property to `Infinity` to
+disable this feature. You can also modify this property during runtime.
+
+### delayedStream.maxDataSize = 1024 * 1024
+
+The amount of data to buffer before emitting an `error`.
+
+If the underlaying source is emitting `Buffer` objects, the `maxDataSize`
+refers to bytes.
+
+If the underlaying source is emitting JavaScript strings, the size refers to
+characters.
+
+If you know what you are doing, you can set this property to `Infinity` to
+disable this feature.
+
+### delayedStream.dataSize = 0
+
+The amount of data buffered so far.
+
+### delayedStream.readable
+
+An ECMA5 getter that returns the value of `source.readable`.
+
+### delayedStream.resume()
+
+If the `delayedStream` has not been released so far, `delayedStream.release()`
+is called.
+
+In either case, `source.resume()` is called.
+
+### delayedStream.pause()
+
+Calls `source.pause()`.
+
+### delayedStream.pipe(dest)
+
+Calls `delayedStream.resume()` and then proxies the arguments to `source.pipe`.
+
+### delayedStream.release()
+
+Emits and clears all events that have been buffered up so far. This does not
+resume the underlaying source, use `delayedStream.resume()` instead.
+
+## License
+
+delayed-stream is licensed under the MIT license.
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js
new file mode 100644 (file)
index 0000000..7c10d48
--- /dev/null
@@ -0,0 +1,99 @@
+var Stream = require('stream').Stream;
+var util = require('util');
+
+module.exports = DelayedStream;
+function DelayedStream() {
+  this.source = null;
+  this.dataSize = 0;
+  this.maxDataSize = 1024 * 1024;
+  this.pauseStream = true;
+
+  this._maxDataSizeExceeded = false;
+  this._released = false;
+  this._bufferedEvents = [];
+}
+util.inherits(DelayedStream, Stream);
+
+DelayedStream.create = function(source, options) {
+  var delayedStream = new this();
+
+  options = options || {};
+  for (var option in options) {
+    delayedStream[option] = options[option];
+  }
+
+  delayedStream.source = source;
+
+  var realEmit = source.emit;
+  source.emit = function() {
+    delayedStream._handleEmit(arguments);
+    return realEmit.apply(source, arguments);
+  };
+
+  source.on('error', function() {});
+  if (delayedStream.pauseStream) {
+    source.pause();
+  }
+
+  return delayedStream;
+};
+
+DelayedStream.prototype.__defineGetter__('readable', function() {
+  return this.source.readable;
+});
+
+DelayedStream.prototype.resume = function() {
+  if (!this._released) {
+    this.release();
+  }
+
+  this.source.resume();
+};
+
+DelayedStream.prototype.pause = function() {
+  this.source.pause();
+};
+
+DelayedStream.prototype.release = function() {
+  this._released = true;
+
+  this._bufferedEvents.forEach(function(args) {
+    this.emit.apply(this, args);
+  }.bind(this));
+  this._bufferedEvents = [];
+};
+
+DelayedStream.prototype.pipe = function() {
+  var r = Stream.prototype.pipe.apply(this, arguments);
+  this.resume();
+  return r;
+};
+
+DelayedStream.prototype._handleEmit = function(args) {
+  if (this._released) {
+    this.emit.apply(this, args);
+    return;
+  }
+
+  if (args[0] === 'data') {
+    this.dataSize += args[1].length;
+    this._checkIfMaxDataSizeExceeded();
+  }
+
+  this._bufferedEvents.push(args);
+};
+
+DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() {
+  if (this._maxDataSizeExceeded) {
+    return;
+  }
+
+  if (this.dataSize <= this.maxDataSize) {
+    return;
+  }
+
+  this._maxDataSizeExceeded = true;
+  var message =
+    'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'
+  this.emit('error', new Error(message));
+};
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json
new file mode 100644 (file)
index 0000000..d394b92
--- /dev/null
@@ -0,0 +1,38 @@
+{
+  "author": {
+    "name": "Felix Geisendörfer",
+    "email": "felix@debuggable.com",
+    "url": "http://debuggable.com/"
+  },
+  "name": "delayed-stream",
+  "description": "Buffers events from a stream until you are ready to handle them.",
+  "version": "0.0.5",
+  "homepage": "https://github.com/felixge/node-delayed-stream",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/felixge/node-delayed-stream.git"
+  },
+  "main": "./lib/delayed_stream",
+  "engines": {
+    "node": ">=0.4.0"
+  },
+  "dependencies": {},
+  "devDependencies": {
+    "fake": "0.2.0",
+    "far": "0.0.1"
+  },
+  "_npmUser": {
+    "name": "mikeal",
+    "email": "mikeal.rogers@gmail.com"
+  },
+  "_id": "delayed-stream@0.0.5",
+  "optionalDependencies": {},
+  "_engineSupported": true,
+  "_npmVersion": "1.1.24",
+  "_nodeVersion": "v0.8.1",
+  "_defaultsLoaded": true,
+  "dist": {
+    "shasum": "56f46a53506f656e1a549c63d8794c6cf8b6e1fc"
+  },
+  "_from": "delayed-stream@0.0.5"
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/common.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/common.js
new file mode 100644 (file)
index 0000000..4d71b8a
--- /dev/null
@@ -0,0 +1,6 @@
+var common = module.exports;
+
+common.DelayedStream = require('..');
+common.assert = require('assert');
+common.fake = require('fake');
+common.PORT = 49252;
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-http-upload.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-http-upload.js
new file mode 100644 (file)
index 0000000..9ecad5b
--- /dev/null
@@ -0,0 +1,38 @@
+var common = require('../common');
+var assert = common.assert;
+var DelayedStream = common.DelayedStream;
+var http = require('http');
+
+var UPLOAD = new Buffer(10 * 1024 * 1024);
+
+var server = http.createServer(function(req, res) {
+  var delayed = DelayedStream.create(req, {maxDataSize: UPLOAD.length});
+
+  setTimeout(function() {
+    res.writeHead(200);
+    delayed.pipe(res);
+  }, 10);
+});
+server.listen(common.PORT, function() {
+  var request = http.request({
+    method: 'POST',
+    port: common.PORT,
+  });
+
+  request.write(UPLOAD);
+  request.end();
+
+  request.on('response', function(res) {
+    var received = 0;
+    res
+      .on('data', function(chunk) {
+        received += chunk.length;
+      })
+      .on('end', function() {
+        assert.equal(received, UPLOAD.length);
+        server.close();
+      });
+  });
+});
+
+
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-auto-pause.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-auto-pause.js
new file mode 100644 (file)
index 0000000..6f417f3
--- /dev/null
@@ -0,0 +1,21 @@
+var common = require('../common');
+var assert = common.assert;
+var fake = common.fake.create();
+var DelayedStream = common.DelayedStream;
+var Stream = require('stream').Stream;
+
+(function testAutoPause() {
+  var source = new Stream();
+
+  fake.expect(source, 'pause', 1);
+  var delayedStream = DelayedStream.create(source);
+  fake.verify();
+})();
+
+(function testDisableAutoPause() {
+  var source = new Stream();
+  fake.expect(source, 'pause', 0);
+
+  var delayedStream = DelayedStream.create(source, {pauseStream: false});
+  fake.verify();
+})();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-pause.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-pause.js
new file mode 100644 (file)
index 0000000..b50c397
--- /dev/null
@@ -0,0 +1,14 @@
+var common = require('../common');
+var assert = common.assert;
+var fake = common.fake.create();
+var DelayedStream = common.DelayedStream;
+var Stream = require('stream').Stream;
+
+(function testDelayEventsUntilResume() {
+  var source = new Stream();
+  var delayedStream = DelayedStream.create(source, {pauseStream: false});
+
+  fake.expect(source, 'pause');
+  delayedStream.pause();
+  fake.verify();
+})();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream.js
new file mode 100644 (file)
index 0000000..fc4047e
--- /dev/null
@@ -0,0 +1,48 @@
+var common = require('../common');
+var assert = common.assert;
+var fake = common.fake.create();
+var DelayedStream = common.DelayedStream;
+var Stream = require('stream').Stream;
+
+(function testDelayEventsUntilResume() {
+  var source = new Stream();
+  var delayedStream = DelayedStream.create(source, {pauseStream: false});
+
+  // delayedStream must not emit until we resume
+  fake.expect(delayedStream, 'emit', 0);
+
+  // but our original source must emit
+  var params = [];
+  source.on('foo', function(param) {
+    params.push(param);
+  });
+
+  source.emit('foo', 1);
+  source.emit('foo', 2);
+
+  // Make sure delayedStream did not emit, and source did
+  assert.deepEqual(params, [1, 2]);
+  fake.verify();
+
+  // After resume, delayedStream must playback all events
+  fake
+    .stub(delayedStream, 'emit')
+    .times(Infinity)
+    .withArg(1, 'newListener');
+  fake.expect(delayedStream, 'emit', ['foo', 1]);
+  fake.expect(delayedStream, 'emit', ['foo', 2]);
+  fake.expect(source, 'resume');
+
+  delayedStream.resume();
+  fake.verify();
+
+  // Calling resume again will delegate to source
+  fake.expect(source, 'resume');
+  delayedStream.resume();
+  fake.verify();
+
+  // Emitting more events directly leads to them being emitted
+  fake.expect(delayedStream, 'emit', ['foo', 3]);
+  source.emit('foo', 3);
+  fake.verify();
+})();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-handle-source-errors.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-handle-source-errors.js
new file mode 100644 (file)
index 0000000..a9d35e7
--- /dev/null
@@ -0,0 +1,15 @@
+var common = require('../common');
+var assert = common.assert;
+var fake = common.fake.create();
+var DelayedStream = common.DelayedStream;
+var Stream = require('stream').Stream;
+
+(function testHandleSourceErrors() {
+  var source = new Stream();
+  var delayedStream = DelayedStream.create(source, {pauseStream: false});
+
+  // We deal with this by attaching a no-op listener to 'error' on the source
+  // when creating a new DelayedStream. This way error events on the source
+  // won't throw.
+  source.emit('error', new Error('something went wrong'));
+})();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-max-data-size.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-max-data-size.js
new file mode 100644 (file)
index 0000000..7638a2b
--- /dev/null
@@ -0,0 +1,18 @@
+var common = require('../common');
+var assert = common.assert;
+var fake = common.fake.create();
+var DelayedStream = common.DelayedStream;
+var Stream = require('stream').Stream;
+
+(function testMaxDataSize() {
+  var source = new Stream();
+  var delayedStream = DelayedStream.create(source, {maxDataSize: 1024, pauseStream: false});
+
+  source.emit('data', new Buffer(1024));
+
+  fake
+    .expect(delayedStream, 'emit')
+    .withArg(1, 'error');
+  source.emit('data', new Buffer(1));
+  fake.verify();
+})();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-pipe-resumes.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-pipe-resumes.js
new file mode 100644 (file)
index 0000000..7d312ab
--- /dev/null
@@ -0,0 +1,13 @@
+var common = require('../common');
+var assert = common.assert;
+var fake = common.fake.create();
+var DelayedStream = common.DelayedStream;
+var Stream = require('stream').Stream;
+
+(function testPipeReleases() {
+  var source = new Stream();
+  var delayedStream = DelayedStream.create(source, {pauseStream: false});
+
+  fake.expect(delayedStream, 'resume');
+  delayedStream.pipe(new Stream());
+})();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-proxy-readable.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-proxy-readable.js
new file mode 100644 (file)
index 0000000..d436163
--- /dev/null
@@ -0,0 +1,13 @@
+var common = require('../common');
+var assert = common.assert;
+var fake = common.fake.create();
+var DelayedStream = common.DelayedStream;
+var Stream = require('stream').Stream;
+
+(function testProxyReadableProperty() {
+  var source = new Stream();
+  var delayedStream = DelayedStream.create(source, {pauseStream: false});
+
+  source.readable = fake.value('source.readable');
+  assert.strictEqual(delayedStream.readable, source.readable);
+})();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/run.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/run.js
new file mode 100755 (executable)
index 0000000..0bb8e82
--- /dev/null
@@ -0,0 +1,7 @@
+#!/usr/bin/env node
+var far = require('far').create();
+
+far.add(__dirname);
+far.include(/test-.*\.js$/);
+
+far.execute();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json
new file mode 100644 (file)
index 0000000..7bb0fcf
--- /dev/null
@@ -0,0 +1,39 @@
+{
+  "author": {
+    "name": "Felix Geisendörfer",
+    "email": "felix@debuggable.com",
+    "url": "http://debuggable.com/"
+  },
+  "name": "combined-stream",
+  "description": "A stream that emits multiple other streams one after another.",
+  "version": "0.0.3",
+  "homepage": "https://github.com/felixge/node-combined-stream",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/felixge/node-combined-stream.git"
+  },
+  "main": "./lib/combined_stream",
+  "engines": {
+    "node": "*"
+  },
+  "dependencies": {
+    "delayed-stream": "0.0.5"
+  },
+  "devDependencies": {
+    "far": "0.0.1"
+  },
+  "_npmUser": {
+    "name": "mikeal",
+    "email": "mikeal.rogers@gmail.com"
+  },
+  "_id": "combined-stream@0.0.3",
+  "optionalDependencies": {},
+  "_engineSupported": true,
+  "_npmVersion": "1.1.24",
+  "_nodeVersion": "v0.8.1",
+  "_defaultsLoaded": true,
+  "dist": {
+    "shasum": "c41c9899277b587901bb6ce4bf458b94693afafa"
+  },
+  "_from": "combined-stream@0.0.3"
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/common.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/common.js
new file mode 100644 (file)
index 0000000..aa9ab3a
--- /dev/null
@@ -0,0 +1,12 @@
+var common = module.exports;
+
+var path = require('path');
+var root = path.join(__dirname, '..');
+
+common.dir = {
+  fixture: root + '/test/fixture',
+  tmp: root + '/test/tmp',
+};
+
+common.CombinedStream = require(root);
+common.assert = require('assert');
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file1.txt b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file1.txt
new file mode 100644 (file)
index 0000000..50e0218
--- /dev/null
@@ -0,0 +1,256 @@
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
+10101010101010101010101010101010101010101010101010101010101010101010101010101010
+01010101010101010101010101010101010101010101010101010101010101010101010101010101
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file2.txt b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file2.txt
new file mode 100644 (file)
index 0000000..da1d821
--- /dev/null
@@ -0,0 +1,256 @@
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
+20202020202020202020202020202020202020202020202020202020202020202020202020202020
+02020202020202020202020202020202020202020202020202020202020202020202020202020202
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-callback-streams.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-callback-streams.js
new file mode 100644 (file)
index 0000000..44ecaba
--- /dev/null
@@ -0,0 +1,27 @@
+var common = require('../common');
+var assert = common.assert;
+var CombinedStream = common.CombinedStream;
+var fs = require('fs');
+
+var FILE1 = common.dir.fixture + '/file1.txt';
+var FILE2 = common.dir.fixture + '/file2.txt';
+var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2);
+
+(function testDelayedStreams() {
+  var combinedStream = CombinedStream.create();
+  combinedStream.append(function(next) {
+    next(fs.createReadStream(FILE1));
+  });
+  combinedStream.append(function(next) {
+    next(fs.createReadStream(FILE2));
+  });
+
+  var tmpFile = common.dir.tmp + '/combined.txt';
+  var dest = fs.createWriteStream(tmpFile);
+  combinedStream.pipe(dest);
+
+  dest.on('end', function() {
+    var written = fs.readFileSync(tmpFile, 'utf8');
+    assert.strictEqual(written, EXPECTED);
+  });
+})();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-data-size.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-data-size.js
new file mode 100644 (file)
index 0000000..e3fbd18
--- /dev/null
@@ -0,0 +1,34 @@
+var common = require('../common');
+var assert = common.assert;
+var CombinedStream = common.CombinedStream;
+
+(function testDataSizeGetter() {
+  var combinedStream = CombinedStream.create();
+
+  assert.strictEqual(combinedStream.dataSize, 0);
+
+  // Test one stream
+  combinedStream._streams.push({dataSize: 10});
+  combinedStream._updateDataSize();
+  assert.strictEqual(combinedStream.dataSize, 10);
+
+  // Test two streams
+  combinedStream._streams.push({dataSize: 23});
+  combinedStream._updateDataSize();
+  assert.strictEqual(combinedStream.dataSize, 33);
+
+  // Test currentStream
+  combinedStream._currentStream = {dataSize: 20};
+  combinedStream._updateDataSize();
+  assert.strictEqual(combinedStream.dataSize, 53);
+
+  // Test currentStream without dataSize
+  combinedStream._currentStream = {};
+  combinedStream._updateDataSize();
+  assert.strictEqual(combinedStream.dataSize, 33);
+
+  // Test stream function
+  combinedStream._streams.push(function() {});
+  combinedStream._updateDataSize();
+  assert.strictEqual(combinedStream.dataSize, 33);
+})();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams-and-buffers-and-strings.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams-and-buffers-and-strings.js
new file mode 100644 (file)
index 0000000..c678575
--- /dev/null
@@ -0,0 +1,38 @@
+var common = require('../common');
+var assert = common.assert;
+var CombinedStream = common.CombinedStream;
+var fs = require('fs');
+
+var FILE1 = common.dir.fixture + '/file1.txt';
+var BUFFER = new Buffer('Bacon is delicious');
+var FILE2 = common.dir.fixture + '/file2.txt';
+var STRING = 'The € kicks the $\'s ass!';
+
+var EXPECTED =
+  fs.readFileSync(FILE1)
+  + BUFFER
+  + fs.readFileSync(FILE2)
+  + STRING;
+var GOT;
+
+(function testDelayedStreams() {
+  var combinedStream = CombinedStream.create();
+  combinedStream.append(fs.createReadStream(FILE1));
+  combinedStream.append(BUFFER);
+  combinedStream.append(fs.createReadStream(FILE2));
+  combinedStream.append(function(next) {
+    next(STRING);
+  });
+
+  var tmpFile = common.dir.tmp + '/combined-file1-buffer-file2-string.txt';
+  var dest = fs.createWriteStream(tmpFile);
+  combinedStream.pipe(dest);
+
+  dest.on('close', function() {
+    GOT = fs.readFileSync(tmpFile, 'utf8');
+  });
+})();
+
+process.on('exit', function() {
+  assert.strictEqual(GOT, EXPECTED);
+});
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams.js
new file mode 100644 (file)
index 0000000..263cfdf
--- /dev/null
@@ -0,0 +1,35 @@
+var common = require('../common');
+var assert = common.assert;
+var CombinedStream = common.CombinedStream;
+var fs = require('fs');
+
+var FILE1 = common.dir.fixture + '/file1.txt';
+var FILE2 = common.dir.fixture + '/file2.txt';
+var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2);
+var GOT;
+
+(function testDelayedStreams() {
+  var combinedStream = CombinedStream.create();
+  combinedStream.append(fs.createReadStream(FILE1));
+  combinedStream.append(fs.createReadStream(FILE2));
+
+  var stream1 = combinedStream._streams[0];
+  var stream2 = combinedStream._streams[1];
+
+  stream1.on('end', function() {
+    assert.equal(stream2.dataSize, 0);
+  });
+
+  var tmpFile = common.dir.tmp + '/combined.txt';
+  var dest = fs.createWriteStream(tmpFile);
+  combinedStream.pipe(dest);
+
+  dest.on('close', function() {
+    GOT = fs.readFileSync(tmpFile, 'utf8');
+  });
+})();
+
+process.on('exit', function() {
+  console.error(GOT.length, EXPECTED.length);
+  assert.strictEqual(GOT, EXPECTED);
+});
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-max-data-size.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-max-data-size.js
new file mode 100644 (file)
index 0000000..25f47a4
--- /dev/null
@@ -0,0 +1,24 @@
+var common = require('../common');
+var assert = common.assert;
+var CombinedStream = common.CombinedStream;
+var fs = require('fs');
+
+var FILE1 = common.dir.fixture + '/file1.txt';
+var FILE2 = common.dir.fixture + '/file2.txt';
+var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2);
+
+(function testDelayedStreams() {
+  var combinedStream = CombinedStream.create({pauseStreams: false, maxDataSize: 20736});
+  combinedStream.append(fs.createReadStream(FILE1));
+  combinedStream.append(fs.createReadStream(FILE2));
+
+  var gotErr = null;
+  combinedStream.on('error', function(err) {
+    gotErr = err;
+  });
+
+  process.on('exit', function() {
+    assert.ok(gotErr);
+    assert.ok(gotErr.message.match(/bytes/));
+  });
+})();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-unpaused-streams.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-unpaused-streams.js
new file mode 100644 (file)
index 0000000..30a3a6f
--- /dev/null
@@ -0,0 +1,30 @@
+var common = require('../common');
+var assert = common.assert;
+var CombinedStream = common.CombinedStream;
+var fs = require('fs');
+
+var FILE1 = common.dir.fixture + '/file1.txt';
+var FILE2 = common.dir.fixture + '/file2.txt';
+var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2);
+
+(function testDelayedStreams() {
+  var combinedStream = CombinedStream.create({pauseStreams: false});
+  combinedStream.append(fs.createReadStream(FILE1));
+  combinedStream.append(fs.createReadStream(FILE2));
+
+  var stream1 = combinedStream._streams[0];
+  var stream2 = combinedStream._streams[1];
+
+  stream1.on('end', function() {
+    assert.ok(stream2.dataSize > 0);
+  });
+
+  var tmpFile = common.dir.tmp + '/combined.txt';
+  var dest = fs.createWriteStream(tmpFile);
+  combinedStream.pipe(dest);
+
+  dest.on('end', function() {
+    var written = fs.readFileSync(tmpFile, 'utf8');
+    assert.strictEqual(written, EXPECTED);
+  });
+})();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/run.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/run.js
new file mode 100755 (executable)
index 0000000..0bb8e82
--- /dev/null
@@ -0,0 +1,7 @@
+#!/usr/bin/env node
+var far = require('far').create();
+
+far.add(__dirname);
+far.include(/test-.*\.js$/);
+
+far.execute();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/package.json b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/package.json
new file mode 100644 (file)
index 0000000..1948a5e
--- /dev/null
@@ -0,0 +1,43 @@
+{
+  "author": {
+    "name": "Felix Geisendörfer",
+    "email": "felix@debuggable.com",
+    "url": "http://debuggable.com/"
+  },
+  "name": "form-data",
+  "description": "A module to create readable `\"multipart/form-data\"` streams.  Can be used to submit forms and file uploads to other web applications.",
+  "version": "0.0.3",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/felixge/node-form-data.git"
+  },
+  "main": "./lib/form_data",
+  "engines": {
+    "node": "*"
+  },
+  "dependencies": {
+    "combined-stream": "0.0.3",
+    "mime": "~1.2.2",
+    "async": "~0.1.9"
+  },
+  "devDependencies": {
+    "fake": "0.2.1",
+    "far": "0.0.1",
+    "formidable": "1.0.2",
+    "request": "~2.9.203"
+  },
+  "_npmUser": {
+    "name": "mikeal",
+    "email": "mikeal.rogers@gmail.com"
+  },
+  "_id": "form-data@0.0.3",
+  "optionalDependencies": {},
+  "_engineSupported": true,
+  "_npmVersion": "1.1.24",
+  "_nodeVersion": "v0.8.1",
+  "_defaultsLoaded": true,
+  "dist": {
+    "shasum": "6eea17b45790b42d779a1d581d1b3600fe0c7c0d"
+  },
+  "_from": "form-data"
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/common.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/common.js
new file mode 100644 (file)
index 0000000..8a26482
--- /dev/null
@@ -0,0 +1,14 @@
+var common = module.exports;
+var path = require('path');
+
+var rootDir = path.join(__dirname, '..');
+common.dir = {
+  lib: rootDir + '/lib',
+  fixture: rootDir + '/test/fixture',
+  tmp: rootDir + '/test/tmp',
+};
+
+common.assert = require('assert');
+common.fake = require('fake');
+
+common.port = 8432;
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/fixture/bacon.txt b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/fixture/bacon.txt
new file mode 100644 (file)
index 0000000..9804bbd
--- /dev/null
@@ -0,0 +1 @@
+Bacon is delicious.
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg
new file mode 100644 (file)
index 0000000..7cea4dd
Binary files /dev/null and b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg differ
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js
new file mode 100644 (file)
index 0000000..44d3b4d
--- /dev/null
@@ -0,0 +1,93 @@
+var common = require('../common');
+var assert = common.assert;
+var FormData = require(common.dir.lib + '/form_data');
+var fake = require('fake').create();
+var fs = require('fs');
+
+(function testEmptyForm() {
+  var form = new FormData();
+  var callback = fake.callback(arguments.callee.name + '-getLength');
+  var calls = fake.expectAnytime(callback, [null, 0]).calls;
+
+  form.getLength(callback);
+
+  // Make sure our response is async
+  assert.strictEqual(calls.length, 0);
+})();
+
+(function testUtf8String() {
+  var FIELD = 'my_field';
+  var VALUE = 'May the € be with you';
+
+  var form = new FormData();
+  form.append(FIELD, VALUE);
+  var callback = fake.callback(arguments.callee.name + '-getLength');
+
+  var expectedLength =
+    form._overheadLength +
+    Buffer.byteLength(VALUE) +
+    form._lastBoundary().length;
+
+  fake.expectAnytime(callback, [null, expectedLength]);
+  form.getLength(callback);
+})();
+
+(function testBuffer() {
+  var FIELD = 'my_field';
+  var VALUE = new Buffer(23);
+
+  var form = new FormData();
+  form.append(FIELD, VALUE);
+  var callback = fake.callback(arguments.callee.name + '-getLength');
+
+  var expectedLength =
+    form._overheadLength +
+    VALUE.length +
+    form._lastBoundary().length;
+
+  fake.expectAnytime(callback, [null, expectedLength]);
+  form.getLength(callback);
+})();
+
+
+(function testStringFileBufferFile() {
+  var fields = [
+    {
+      name: 'my_field',
+      value: 'Test 123',
+    },
+    {
+      name: 'my_image',
+      value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg'),
+    },
+    {
+      name: 'my_buffer',
+      value: new Buffer('123'),
+    },
+    {
+      name: 'my_txt',
+      value: fs.createReadStream(common.dir.fixture + '/bacon.txt'),
+    },
+  ];
+
+  var form = new FormData();
+  var expectedLength = 0;
+
+  fields.forEach(function(field) {
+    form.append(field.name, field.value);
+    if (field.value.path) {
+      var stat = fs.statSync(field.value.path);
+      expectedLength += stat.size;
+    } else {
+      expectedLength += field.value.length;
+    }
+  });
+
+  expectedLength += form._overheadLength + form._lastBoundary().length;
+
+  var callback = fake.callback(arguments.callee.name + '-getLength');
+  fake.expectAnytime(callback, [null, expectedLength]);
+  form.getLength(callback);
+})();
+
+
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js
new file mode 100644 (file)
index 0000000..6dc2fb2
--- /dev/null
@@ -0,0 +1,18 @@
+var common = require('../common');
+var assert = common.assert;
+
+var FormData = require(common.dir.lib + '/form_data');
+
+(function testOneBoundaryPerForm() {
+  var form = new FormData();
+  var boundary = form.getBoundary();
+
+  assert.equal(boundary, form.getBoundary());
+  assert.equal(boundary.length, 50);
+})();
+
+(function testUniqueBoundaryPerForm() {
+  var formA = new FormData();
+  var formB = new FormData();
+  assert.notEqual(formA.getBoundary(), formB.getBoundary());
+})();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-http-response.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-http-response.js
new file mode 100644 (file)
index 0000000..8e183fe
--- /dev/null
@@ -0,0 +1,121 @@
+var common = require('../common');
+var assert = common.assert;
+var http = require('http');
+var path = require('path');
+var mime = require('mime');
+var request = require('request');
+var parseUrl = require('url').parse;
+var fs = require('fs');
+var FormData = require(common.dir.lib + '/form_data');
+var IncomingForm = require('formidable').IncomingForm;
+
+var remoteFile = 'http://nodejs.org/images/logo.png';
+
+var FIELDS;
+var server;
+
+var parsedUrl = parseUrl(remoteFile)
+  , options = {
+      method: 'get',
+      port: parsedUrl.port || 80,
+      path: parsedUrl.pathname,
+      host: parsedUrl.hostname
+    }
+  ;
+
+http.request(options, function(res) {
+
+  FIELDS = [
+    {name: 'my_field', value: 'my_value'},
+    {name: 'my_buffer', value: new Buffer([1, 2, 3])},
+    {name: 'remote_file', value: res }
+  ];
+
+  var form = new FormData();
+  FIELDS.forEach(function(field) {
+    form.append(field.name, field.value);
+  });
+
+  server.listen(common.port, function() {
+
+    form.submit('http://localhost:' + common.port + '/', function(err, res) {
+
+      if (err) {
+        throw err;
+      }
+
+      assert.strictEqual(res.statusCode, 200);
+      server.close();
+    });
+
+  });
+
+
+}).end();
+
+server = http.createServer(function(req, res) {
+
+  // formidable is broken so let's do it manual way
+  //
+  // var form = new IncomingForm();
+  // form.uploadDir = common.dir.tmp;
+  //  form.parse(req);
+  // form
+  //   .on('field', function(name, value) {
+  //     var field = FIELDS.shift();
+  //     assert.strictEqual(name, field.name);
+  //     assert.strictEqual(value, field.value+'');
+  //   })
+  //   .on('file', function(name, file) {
+  //     var field = FIELDS.shift();
+  //     assert.strictEqual(name, field.name);
+  //     assert.strictEqual(file.name, path.basename(field.value.path));
+  //     // mime.lookup file.NAME == 'my_file' ?
+  //     assert.strictEqual(file.type, mime.lookup(file.name));
+  //   })
+  //   .on('end', function() {
+  //     res.writeHead(200);
+  //     res.end('done');
+  //   });
+
+  // temp workaround
+  var data = '';
+  req.setEncoding('utf8');
+
+  req.on('data', function(d) {
+    data += d;
+  });
+
+  req.on('end', function() {
+
+    // check for the fields' traces
+
+    // 1st field : my_field
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf(field.value) != -1 );
+
+    // 2nd field : my_buffer
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf(field.value) != -1 );
+
+    // 3rd field : remote_file
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf('; filename="'+path.basename(remoteFile)+'"') != -1 );
+    // check for http://nodejs.org/images/logo.png traces
+    assert.ok( data.indexOf('ImageReady') != -1 );
+    assert.ok( data.indexOf('Content-Type: '+mime.lookup(remoteFile) ) != -1 );
+
+    res.writeHead(200);
+    res.end('done');
+
+  });
+
+});
+
+
+process.on('exit', function() {
+  assert.strictEqual(FIELDS.length, 0);
+});
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-pipe.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-pipe.js
new file mode 100644 (file)
index 0000000..acc39df
--- /dev/null
@@ -0,0 +1,111 @@
+var common = require('../common');
+var assert = common.assert;
+var http = require('http');
+var path = require('path');
+var mime = require('mime');
+var request = require('request');
+var fs = require('fs');
+var FormData = require(common.dir.lib + '/form_data');
+var IncomingForm = require('formidable').IncomingForm;
+
+var remoteFile = 'http://nodejs.org/images/logo.png';
+
+var FIELDS = [
+  {name: 'my_field', value: 'my_value'},
+  {name: 'my_buffer', value: new Buffer([1, 2, 3])},
+  {name: 'my_file', value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg')},
+  {name: 'remote_file', value: request(remoteFile) }
+];
+
+var server = http.createServer(function(req, res) {
+
+  // formidable is broken so let's do it manual way
+  //
+  // var form = new IncomingForm();
+  // form.uploadDir = common.dir.tmp;
+  // form.parse(req);
+  // form
+  //   .on('field', function(name, value) {
+  //     var field = FIELDS.shift();
+  //     assert.strictEqual(name, field.name);
+  //     assert.strictEqual(value, field.value+'');
+  //   })
+  //   .on('file', function(name, file) {
+  //     var field = FIELDS.shift();
+  //     assert.strictEqual(name, field.name);
+  //     assert.strictEqual(file.name, path.basename(field.value.path));
+  //     assert.strictEqual(file.type, mime.lookup(file.name));
+  //   })
+  //   .on('end', function() {
+  //     res.writeHead(200);
+  //     res.end('done');
+  //   });
+
+  // temp workaround
+  var data = '';
+  req.setEncoding('utf8');
+
+  req.on('data', function(d) {
+    data += d;
+  });
+
+  req.on('end', function() {
+    // check for the fields' traces
+
+    // 1st field : my_field
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf(field.value) != -1 );
+
+    // 2nd field : my_buffer
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf(field.value) != -1 );
+
+    // 3rd field : my_file
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
+    // check for unicycle.jpg traces
+    assert.ok( data.indexOf('2005:06:21 01:44:12') != -1 );
+    assert.ok( data.indexOf('Content-Type: '+mime.lookup(field.value.path) ) != -1 );
+
+    // 4th field : remote_file
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
+    // check for http://nodejs.org/images/logo.png traces
+    assert.ok( data.indexOf('ImageReady') != -1 );
+    assert.ok( data.indexOf('Content-Type: '+mime.lookup(remoteFile) ) != -1 );
+
+    res.writeHead(200);
+    res.end('done');
+
+  });
+
+
+});
+
+server.listen(common.port, function() {
+  var form = new FormData();
+  FIELDS.forEach(function(field) {
+    form.append(field.name, field.value);
+  });
+
+  var request = http.request({
+    method: 'post',
+    port: common.port,
+    path: '/upload',
+    headers: form.getHeaders()
+  });
+
+  form.pipe(request);
+
+  request.on('response', function(res) {
+    server.close();
+  });
+});
+
+process.on('exit', function() {
+  assert.strictEqual(FIELDS.length, 0);
+});
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-submit.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/integration/test-submit.js
new file mode 100644 (file)
index 0000000..c40e88f
--- /dev/null
@@ -0,0 +1,107 @@
+var common = require('../common');
+var assert = common.assert;
+var http = require('http');
+var path = require('path');
+var mime = require('mime');
+var request = require('request');
+var fs = require('fs');
+var FormData = require(common.dir.lib + '/form_data');
+var IncomingForm = require('formidable').IncomingForm;
+
+var remoteFile = 'http://nodejs.org/images/logo.png';
+
+var FIELDS = [
+  {name: 'my_field', value: 'my_value'},
+  {name: 'my_buffer', value: new Buffer([1, 2, 3])},
+  {name: 'my_file', value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg') },
+  {name: 'remote_file', value: request(remoteFile) }
+];
+
+var server = http.createServer(function(req, res) {
+
+  // formidable is broken so let's do it manual way
+  //
+  // var form = new IncomingForm();
+  // form.uploadDir = common.dir.tmp;
+  //  form.parse(req);
+  // form
+  //   .on('field', function(name, value) {
+  //     var field = FIELDS.shift();
+  //     assert.strictEqual(name, field.name);
+  //     assert.strictEqual(value, field.value+'');
+  //   })
+  //   .on('file', function(name, file) {
+  //     var field = FIELDS.shift();
+  //     assert.strictEqual(name, field.name);
+  //     assert.strictEqual(file.name, path.basename(field.value.path));
+  //     // mime.lookup file.NAME == 'my_file' ?
+  //     assert.strictEqual(file.type, mime.lookup(file.name));
+  //   })
+  //   .on('end', function() {
+  //     res.writeHead(200);
+  //     res.end('done');
+  //   });
+
+  // temp workaround
+  var data = '';
+  req.setEncoding('utf8');
+  req.on('data', function(d) {
+    data += d;
+  });
+  req.on('end', function() {
+    // check for the fields' traces
+
+    // 1st field : my_field
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf(field.value) != -1 );
+
+    // 2nd field : my_buffer
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf(field.value) != -1 );
+
+    // 3rd field : my_file
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
+    // check for unicycle.jpg traces
+    assert.ok( data.indexOf('2005:06:21 01:44:12') != -1 );
+    assert.ok( data.indexOf('Content-Type: '+mime.lookup(field.value.path) ) != -1 );
+
+    // 4th field : remote_file
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
+    // check for http://nodejs.org/images/logo.png traces
+    assert.ok( data.indexOf('ImageReady') != -1 );
+    assert.ok( data.indexOf('Content-Type: '+mime.lookup(remoteFile) ) != -1 );
+
+    res.writeHead(200);
+    res.end('done');
+
+  });
+
+});
+
+server.listen(common.port, function() {
+  var form = new FormData();
+  FIELDS.forEach(function(field) {
+    form.append(field.name, field.value);
+  });
+
+  form.submit('http://localhost:' + common.port + '/', function(err, res) {
+
+    if (err) {
+      throw err;
+    }
+
+    assert.strictEqual(res.statusCode, 200);
+    server.close();
+  });
+
+});
+
+process.on('exit', function() {
+  assert.strictEqual(FIELDS.length, 0);
+});
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/run.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/form-data/test/run.js
new file mode 100755 (executable)
index 0000000..0bb8e82
--- /dev/null
@@ -0,0 +1,7 @@
+#!/usr/bin/env node
+var far = require('far').create();
+
+far.add(__dirname);
+far.include(/test-.*\.js$/);
+
+far.execute();
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/LICENSE b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/LICENSE
new file mode 100644 (file)
index 0000000..451fc45
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2010 Benjamin Thomas, Robert Kieffer
+
+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.
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/README.md b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/README.md
new file mode 100644 (file)
index 0000000..b90552a
--- /dev/null
@@ -0,0 +1,63 @@
+# mime
+
+Comprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.
+
+## Install
+
+Install with [npm](http://github.com/isaacs/npm):
+
+    npm install mime
+
+## API - Queries
+
+### mime.lookup(path)
+Get the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.').  E.g.
+
+    var mime = require('mime');
+
+    mime.lookup('/path/to/file.txt');         // => 'text/plain'
+    mime.lookup('file.txt');                  // => 'text/plain'
+    mime.lookup('.TXT');                      // => 'text/plain'
+    mime.lookup('htm');                       // => 'text/html'
+
+### mime.extension(type)
+Get the default extension for `type`
+
+    mime.extension('text/html');                 // => 'html'
+    mime.extension('application/octet-stream');  // => 'bin'
+
+### mime.charsets.lookup()
+
+Map mime-type to charset
+
+    mime.charsets.lookup('text/plain');        // => 'UTF-8'
+
+(The logic for charset lookups is pretty rudimentary.  Feel free to suggest improvements.)
+
+## API - Defining Custom Types
+
+The following APIs allow you to add your own type mappings within your project.  If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types).
+
+### mime.define()
+
+Add custom mime/extension mappings
+
+    mime.define({
+        'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],
+        'application/x-my-type': ['x-mt', 'x-mtt'],
+        // etc ...
+    });
+
+    mime.lookup('x-sft');                 // => 'text/x-some-format'
+
+The first entry in the extensions array is returned by `mime.extension()`. E.g.
+
+    mime.extension('text/x-some-format'); // => 'x-sf'
+
+### mime.load(filepath)
+
+Load mappings from an Apache ".types" format file
+
+    mime.load('./my_project.types');
+
+The .types file format is simple -  See the `types` dir for examples.
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/mime.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/mime.js
new file mode 100644 (file)
index 0000000..1e00585
--- /dev/null
@@ -0,0 +1,104 @@
+var path = require('path');
+var fs = require('fs');
+
+function Mime() {
+  // Map of extension -> mime type
+  this.types = Object.create(null);
+
+  // Map of mime type -> extension
+  this.extensions = Object.create(null);
+}
+
+/**
+ * Define mimetype -> extension mappings.  Each key is a mime-type that maps
+ * to an array of extensions associated with the type.  The first extension is
+ * used as the default extension for the type.
+ *
+ * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
+ *
+ * @param map (Object) type definitions
+ */
+Mime.prototype.define = function (map) {
+  for (var type in map) {
+    var exts = map[type];
+
+    for (var i = 0; i < exts.length; i++) {
+      this.types[exts[i]] = type;
+    }
+
+    // Default extension is the first one we encounter
+    if (!this.extensions[type]) {
+      this.extensions[type] = exts[0];
+    }
+  }
+};
+
+/**
+ * Load an Apache2-style ".types" file
+ *
+ * This may be called multiple times (it's expected).  Where files declare
+ * overlapping types/extensions, the last file wins.
+ *
+ * @param file (String) path of file to load.
+ */
+Mime.prototype.load = function(file) {
+  // Read file and split into lines
+  var map = {},
+      content = fs.readFileSync(file, 'ascii'),
+      lines = content.split(/[\r\n]+/);
+
+  lines.forEach(function(line) {
+    // Clean up whitespace/comments, and split into fields
+    var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/);
+    map[fields.shift()] = fields;
+  });
+
+  this.define(map);
+};
+
+/**
+ * Lookup a mime type based on extension
+ */
+Mime.prototype.lookup = function(path, fallback) {
+  var ext = path.replace(/.*[\.\/]/, '').toLowerCase();
+
+  return this.types[ext] || fallback || this.default_type;
+};
+
+/**
+ * Return file extension associated with a mime type
+ */
+Mime.prototype.extension = function(mimeType) {
+  return this.extensions[mimeType];
+};
+
+// Default instance
+var mime = new Mime();
+
+// Load local copy of
+// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
+mime.load(path.join(__dirname, 'types/mime.types'));
+
+// Load additional types from node.js community
+mime.load(path.join(__dirname, 'types/node.types'));
+
+// Default type
+mime.default_type = mime.lookup('bin');
+
+//
+// Additional API specific to the default instance
+//
+
+mime.Mime = Mime;
+
+/**
+ * Lookup a charset based on mime type.
+ */
+mime.charsets = {
+  lookup: function(mimeType, fallback) {
+    // Assume text types are utf8
+    return (/^text\//).test(mimeType) ? 'UTF-8' : fallback;
+  }
+}
+
+module.exports = mime;
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/package.json b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/package.json
new file mode 100644 (file)
index 0000000..06e2ee5
--- /dev/null
@@ -0,0 +1,42 @@
+{
+  "author": {
+    "name": "Robert Kieffer",
+    "email": "robert@broofa.com",
+    "url": "http://github.com/broofa"
+  },
+  "contributors": [
+    {
+      "name": "Benjamin Thomas",
+      "email": "benjamin@benjaminthomas.org",
+      "url": "http://github.com/bentomas"
+    }
+  ],
+  "dependencies": {},
+  "description": "A comprehensive library for mime-type mapping",
+  "devDependencies": {},
+  "keywords": [
+    "util",
+    "mime"
+  ],
+  "main": "mime.js",
+  "name": "mime",
+  "repository": {
+    "url": "git://github.com/broofa/node-mime.git",
+    "type": "git"
+  },
+  "version": "1.2.7",
+  "_npmUser": {
+    "name": "mikeal",
+    "email": "mikeal.rogers@gmail.com"
+  },
+  "_id": "mime@1.2.7",
+  "optionalDependencies": {},
+  "engines": {
+    "node": "*"
+  },
+  "_engineSupported": true,
+  "_npmVersion": "1.1.24",
+  "_nodeVersion": "v0.8.1",
+  "_defaultsLoaded": true,
+  "_from": "mime"
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/test.js b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/test.js
new file mode 100644 (file)
index 0000000..cbad034
--- /dev/null
@@ -0,0 +1,55 @@
+/**
+ * Usage: node test.js
+ */
+
+var mime = require('./mime');
+var assert = require('assert');
+
+function eq(a, b) {
+  console.log('Test: ' + a + ' === ' + b);
+  assert.strictEqual.apply(null, arguments);
+}
+
+console.log(Object.keys(mime.extensions).length + ' types');
+console.log(Object.keys(mime.types).length + ' extensions\n');
+
+//
+// Test mime lookups
+//
+
+eq('text/plain', mime.lookup('text.txt'));
+eq('text/plain', mime.lookup('.text.txt'));
+eq('text/plain', mime.lookup('.txt'));
+eq('text/plain', mime.lookup('txt'));
+eq('application/octet-stream', mime.lookup('text.nope'));
+eq('fallback', mime.lookup('text.fallback', 'fallback'));
+eq('application/octet-stream', mime.lookup('constructor'));
+eq('text/plain', mime.lookup('TEXT.TXT'));
+eq('text/event-stream', mime.lookup('text/event-stream'));
+eq('application/x-web-app-manifest+json', mime.lookup('text.webapp'));
+
+//
+// Test extensions
+//
+
+eq('txt', mime.extension(mime.types.text));
+eq('html', mime.extension(mime.types.htm));
+eq('bin', mime.extension('application/octet-stream'));
+eq(undefined, mime.extension('constructor'));
+
+//
+// Test node types
+//
+
+eq('application/octet-stream', mime.lookup('file.buffer'));
+eq('audio/mp4', mime.lookup('file.m4a'));
+
+//
+// Test charsets
+//
+
+eq('UTF-8', mime.charsets.lookup('text/plain'));
+eq(undefined, mime.charsets.lookup(mime.types.js));
+eq('fallback', mime.charsets.lookup('application/octet-stream', 'fallback'));
+
+console.log('\nOK');
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/types/mime.types b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/types/mime.types
new file mode 100644 (file)
index 0000000..b90b165
--- /dev/null
@@ -0,0 +1,1588 @@
+# This file maps Internet media types to unique file extension(s).
+# Although created for httpd, this file is used by many software systems
+# and has been placed in the public domain for unlimited redisribution.
+#
+# The table below contains both registered and (common) unregistered types.
+# A type that has no unique extension can be ignored -- they are listed
+# here to guide configurations toward known types and to make it easier to
+# identify "new" types.  File extensions are also commonly used to indicate
+# content languages and encodings, so choose them carefully.
+#
+# Internet media types should be registered as described in RFC 4288.
+# The registry is at <http://www.iana.org/assignments/media-types/>.
+#
+# MIME type (lowercased)                       Extensions
+# ============================================ ==========
+# application/1d-interleaved-parityfec
+# application/3gpp-ims+xml
+# application/activemessage
+application/andrew-inset                       ez
+# application/applefile
+application/applixware                         aw
+application/atom+xml                           atom
+application/atomcat+xml                                atomcat
+# application/atomicmail
+application/atomsvc+xml                                atomsvc
+# application/auth-policy+xml
+# application/batch-smtp
+# application/beep+xml
+# application/calendar+xml
+# application/cals-1840
+# application/ccmp+xml
+application/ccxml+xml                          ccxml
+application/cdmi-capability                    cdmia
+application/cdmi-container                     cdmic
+application/cdmi-domain                                cdmid
+application/cdmi-object                                cdmio
+application/cdmi-queue                         cdmiq
+# application/cea-2018+xml
+# application/cellml+xml
+# application/cfw
+# application/cnrp+xml
+# application/commonground
+# application/conference-info+xml
+# application/cpl+xml
+# application/csta+xml
+# application/cstadata+xml
+application/cu-seeme                           cu
+# application/cybercash
+application/davmount+xml                       davmount
+# application/dca-rft
+# application/dec-dx
+# application/dialog-info+xml
+# application/dicom
+# application/dns
+application/docbook+xml                                dbk
+# application/dskpp+xml
+application/dssc+der                           dssc
+application/dssc+xml                           xdssc
+# application/dvcs
+application/ecmascript                         ecma
+# application/edi-consent
+# application/edi-x12
+# application/edifact
+application/emma+xml                           emma
+# application/epp+xml
+application/epub+zip                           epub
+# application/eshop
+# application/example
+application/exi                                        exi
+# application/fastinfoset
+# application/fastsoap
+# application/fits
+application/font-tdpfr                         pfr
+# application/framework-attributes+xml
+application/gml+xml                            gml
+application/gpx+xml                            gpx
+application/gxf                                        gxf
+# application/h224
+# application/held+xml
+# application/http
+application/hyperstudio                                stk
+# application/ibe-key-request+xml
+# application/ibe-pkg-reply+xml
+# application/ibe-pp-data
+# application/iges
+# application/im-iscomposing+xml
+# application/index
+# application/index.cmd
+# application/index.obj
+# application/index.response
+# application/index.vnd
+application/inkml+xml                          ink inkml
+# application/iotp
+application/ipfix                              ipfix
+# application/ipp
+# application/isup
+application/java-archive                       jar
+application/java-serialized-object             ser
+application/java-vm                            class
+application/javascript                         js
+application/json                               json
+application/jsonml+json                                jsonml
+# application/kpml-request+xml
+# application/kpml-response+xml
+application/lost+xml                           lostxml
+application/mac-binhex40                       hqx
+application/mac-compactpro                     cpt
+# application/macwriteii
+application/mads+xml                           mads
+application/marc                               mrc
+application/marcxml+xml                                mrcx
+application/mathematica                                ma nb mb
+# application/mathml-content+xml
+# application/mathml-presentation+xml
+application/mathml+xml                         mathml
+# application/mbms-associated-procedure-description+xml
+# application/mbms-deregister+xml
+# application/mbms-envelope+xml
+# application/mbms-msk+xml
+# application/mbms-msk-response+xml
+# application/mbms-protection-description+xml
+# application/mbms-reception-report+xml
+# application/mbms-register+xml
+# application/mbms-register-response+xml
+# application/mbms-user-service-description+xml
+application/mbox                               mbox
+# application/media_control+xml
+application/mediaservercontrol+xml             mscml
+application/metalink+xml                       metalink
+application/metalink4+xml                      meta4
+application/mets+xml                           mets
+# application/mikey
+application/mods+xml                           mods
+# application/moss-keys
+# application/moss-signature
+# application/mosskey-data
+# application/mosskey-request
+application/mp21                               m21 mp21
+application/mp4                                        mp4s
+# application/mpeg4-generic
+# application/mpeg4-iod
+# application/mpeg4-iod-xmt
+# application/msc-ivr+xml
+# application/msc-mixer+xml
+application/msword                             doc dot
+application/mxf                                        mxf
+# application/nasdata
+# application/news-checkgroups
+# application/news-groupinfo
+# application/news-transmission
+# application/nss
+# application/ocsp-request
+# application/ocsp-response
+application/octet-stream       bin dms lrf mar so dist distz pkg bpk dump elc deploy
+application/oda                                        oda
+application/oebps-package+xml                  opf
+application/ogg                                        ogx
+application/omdoc+xml                          omdoc
+application/onenote                            onetoc onetoc2 onetmp onepkg
+application/oxps                               oxps
+# application/parityfec
+application/patch-ops-error+xml                        xer
+application/pdf                                        pdf
+application/pgp-encrypted                      pgp
+# application/pgp-keys
+application/pgp-signature                      asc sig
+application/pics-rules                         prf
+# application/pidf+xml
+# application/pidf-diff+xml
+application/pkcs10                             p10
+application/pkcs7-mime                         p7m p7c
+application/pkcs7-signature                    p7s
+application/pkcs8                              p8
+application/pkix-attr-cert                     ac
+application/pkix-cert                          cer
+application/pkix-crl                           crl
+application/pkix-pkipath                       pkipath
+application/pkixcmp                            pki
+application/pls+xml                            pls
+# application/poc-settings+xml
+application/postscript                         ai eps ps
+# application/prs.alvestrand.titrax-sheet
+application/prs.cww                            cww
+# application/prs.nprend
+# application/prs.plucker
+# application/prs.rdf-xml-crypt
+# application/prs.xsf+xml
+application/pskc+xml                           pskcxml
+# application/qsig
+application/rdf+xml                            rdf
+application/reginfo+xml                                rif
+application/relax-ng-compact-syntax            rnc
+# application/remote-printing
+application/resource-lists+xml                 rl
+application/resource-lists-diff+xml            rld
+# application/riscos
+# application/rlmi+xml
+application/rls-services+xml                   rs
+application/rpki-ghostbusters                  gbr
+application/rpki-manifest                      mft
+application/rpki-roa                           roa
+# application/rpki-updown
+application/rsd+xml                            rsd
+application/rss+xml                            rss
+application/rtf                                        rtf
+# application/rtx
+# application/samlassertion+xml
+# application/samlmetadata+xml
+application/sbml+xml                           sbml
+application/scvp-cv-request                    scq
+application/scvp-cv-response                   scs
+application/scvp-vp-request                    spq
+application/scvp-vp-response                   spp
+application/sdp                                        sdp
+# application/set-payment
+application/set-payment-initiation             setpay
+# application/set-registration
+application/set-registration-initiation                setreg
+# application/sgml
+# application/sgml-open-catalog
+application/shf+xml                            shf
+# application/sieve
+# application/simple-filter+xml
+# application/simple-message-summary
+# application/simplesymbolcontainer
+# application/slate
+# application/smil
+application/smil+xml                           smi smil
+# application/soap+fastinfoset
+# application/soap+xml
+application/sparql-query                       rq
+application/sparql-results+xml                 srx
+# application/spirits-event+xml
+application/srgs                               gram
+application/srgs+xml                           grxml
+application/sru+xml                            sru
+application/ssdl+xml                           ssdl
+application/ssml+xml                           ssml
+# application/tamp-apex-update
+# application/tamp-apex-update-confirm
+# application/tamp-community-update
+# application/tamp-community-update-confirm
+# application/tamp-error
+# application/tamp-sequence-adjust
+# application/tamp-sequence-adjust-confirm
+# application/tamp-status-query
+# application/tamp-status-response
+# application/tamp-update
+# application/tamp-update-confirm
+application/tei+xml                            tei teicorpus
+application/thraud+xml                         tfi
+# application/timestamp-query
+# application/timestamp-reply
+application/timestamped-data                   tsd
+# application/tve-trigger
+# application/ulpfec
+# application/vcard+xml
+# application/vemmi
+# application/vividence.scriptfile
+# application/vnd.3gpp.bsf+xml
+application/vnd.3gpp.pic-bw-large              plb
+application/vnd.3gpp.pic-bw-small              psb
+application/vnd.3gpp.pic-bw-var                        pvb
+# application/vnd.3gpp.sms
+# application/vnd.3gpp2.bcmcsinfo+xml
+# application/vnd.3gpp2.sms
+application/vnd.3gpp2.tcap                     tcap
+application/vnd.3m.post-it-notes               pwn
+application/vnd.accpac.simply.aso              aso
+application/vnd.accpac.simply.imp              imp
+application/vnd.acucobol                       acu
+application/vnd.acucorp                                atc acutc
+application/vnd.adobe.air-application-installer-package+zip    air
+application/vnd.adobe.formscentral.fcdt                fcdt
+application/vnd.adobe.fxp                      fxp fxpl
+# application/vnd.adobe.partial-upload
+application/vnd.adobe.xdp+xml                  xdp
+application/vnd.adobe.xfdf                     xfdf
+# application/vnd.aether.imp
+# application/vnd.ah-barcode
+application/vnd.ahead.space                    ahead
+application/vnd.airzip.filesecure.azf          azf
+application/vnd.airzip.filesecure.azs          azs
+application/vnd.amazon.ebook                   azw
+application/vnd.americandynamics.acc           acc
+application/vnd.amiga.ami                      ami
+# application/vnd.amundsen.maze+xml
+application/vnd.android.package-archive                apk
+application/vnd.anser-web-certificate-issue-initiation cii
+application/vnd.anser-web-funds-transfer-initiation    fti
+application/vnd.antix.game-component           atx
+application/vnd.apple.installer+xml            mpkg
+application/vnd.apple.mpegurl                  m3u8
+# application/vnd.arastra.swi
+application/vnd.aristanetworks.swi             swi
+application/vnd.astraea-software.iota          iota
+application/vnd.audiograph                     aep
+# application/vnd.autopackage
+# application/vnd.avistar+xml
+application/vnd.blueice.multipass              mpm
+# application/vnd.bluetooth.ep.oob
+application/vnd.bmi                            bmi
+application/vnd.businessobjects                        rep
+# application/vnd.cab-jscript
+# application/vnd.canon-cpdl
+# application/vnd.canon-lips
+# application/vnd.cendio.thinlinc.clientconf
+application/vnd.chemdraw+xml                   cdxml
+application/vnd.chipnuts.karaoke-mmd           mmd
+application/vnd.cinderella                     cdy
+# application/vnd.cirpack.isdn-ext
+application/vnd.claymore                       cla
+application/vnd.cloanto.rp9                    rp9
+application/vnd.clonk.c4group                  c4g c4d c4f c4p c4u
+application/vnd.cluetrust.cartomobile-config           c11amc
+application/vnd.cluetrust.cartomobile-config-pkg       c11amz
+# application/vnd.collection+json
+# application/vnd.commerce-battelle
+application/vnd.commonspace                    csp
+application/vnd.contact.cmsg                   cdbcmsg
+application/vnd.cosmocaller                    cmc
+application/vnd.crick.clicker                  clkx
+application/vnd.crick.clicker.keyboard         clkk
+application/vnd.crick.clicker.palette          clkp
+application/vnd.crick.clicker.template         clkt
+application/vnd.crick.clicker.wordbank         clkw
+application/vnd.criticaltools.wbs+xml          wbs
+application/vnd.ctc-posml                      pml
+# application/vnd.ctct.ws+xml
+# application/vnd.cups-pdf
+# application/vnd.cups-postscript
+application/vnd.cups-ppd                       ppd
+# application/vnd.cups-raster
+# application/vnd.cups-raw
+# application/vnd.curl
+application/vnd.curl.car                       car
+application/vnd.curl.pcurl                     pcurl
+# application/vnd.cybank
+application/vnd.dart                           dart
+application/vnd.data-vision.rdz                        rdz
+application/vnd.dece.data                      uvf uvvf uvd uvvd
+application/vnd.dece.ttml+xml                  uvt uvvt
+application/vnd.dece.unspecified               uvx uvvx
+application/vnd.dece.zip                       uvz uvvz
+application/vnd.denovo.fcselayout-link         fe_launch
+# application/vnd.dir-bi.plate-dl-nosuffix
+application/vnd.dna                            dna
+application/vnd.dolby.mlp                      mlp
+# application/vnd.dolby.mobile.1
+# application/vnd.dolby.mobile.2
+application/vnd.dpgraph                                dpg
+application/vnd.dreamfactory                   dfac
+application/vnd.ds-keypoint                    kpxx
+application/vnd.dvb.ait                                ait
+# application/vnd.dvb.dvbj
+# application/vnd.dvb.esgcontainer
+# application/vnd.dvb.ipdcdftnotifaccess
+# application/vnd.dvb.ipdcesgaccess
+# application/vnd.dvb.ipdcesgaccess2
+# application/vnd.dvb.ipdcesgpdd
+# application/vnd.dvb.ipdcroaming
+# application/vnd.dvb.iptv.alfec-base
+# application/vnd.dvb.iptv.alfec-enhancement
+# application/vnd.dvb.notif-aggregate-root+xml
+# application/vnd.dvb.notif-container+xml
+# application/vnd.dvb.notif-generic+xml
+# application/vnd.dvb.notif-ia-msglist+xml
+# application/vnd.dvb.notif-ia-registration-request+xml
+# application/vnd.dvb.notif-ia-registration-response+xml
+# application/vnd.dvb.notif-init+xml
+# application/vnd.dvb.pfr
+application/vnd.dvb.service                    svc
+# application/vnd.dxr
+application/vnd.dynageo                                geo
+# application/vnd.easykaraoke.cdgdownload
+# application/vnd.ecdis-update
+application/vnd.ecowin.chart                   mag
+# application/vnd.ecowin.filerequest
+# application/vnd.ecowin.fileupdate
+# application/vnd.ecowin.series
+# application/vnd.ecowin.seriesrequest
+# application/vnd.ecowin.seriesupdate
+# application/vnd.emclient.accessrequest+xml
+application/vnd.enliven                                nml
+# application/vnd.eprints.data+xml
+application/vnd.epson.esf                      esf
+application/vnd.epson.msf                      msf
+application/vnd.epson.quickanime               qam
+application/vnd.epson.salt                     slt
+application/vnd.epson.ssf                      ssf
+# application/vnd.ericsson.quickcall
+application/vnd.eszigno3+xml                   es3 et3
+# application/vnd.etsi.aoc+xml
+# application/vnd.etsi.cug+xml
+# application/vnd.etsi.iptvcommand+xml
+# application/vnd.etsi.iptvdiscovery+xml
+# application/vnd.etsi.iptvprofile+xml
+# application/vnd.etsi.iptvsad-bc+xml
+# application/vnd.etsi.iptvsad-cod+xml
+# application/vnd.etsi.iptvsad-npvr+xml
+# application/vnd.etsi.iptvservice+xml
+# application/vnd.etsi.iptvsync+xml
+# application/vnd.etsi.iptvueprofile+xml
+# application/vnd.etsi.mcid+xml
+# application/vnd.etsi.overload-control-policy-dataset+xml
+# application/vnd.etsi.sci+xml
+# application/vnd.etsi.simservs+xml
+# application/vnd.etsi.tsl+xml
+# application/vnd.etsi.tsl.der
+# application/vnd.eudora.data
+application/vnd.ezpix-album                    ez2
+application/vnd.ezpix-package                  ez3
+# application/vnd.f-secure.mobile
+application/vnd.fdf                            fdf
+application/vnd.fdsn.mseed                     mseed
+application/vnd.fdsn.seed                      seed dataless
+# application/vnd.ffsns
+# application/vnd.fints
+application/vnd.flographit                     gph
+application/vnd.fluxtime.clip                  ftc
+# application/vnd.font-fontforge-sfd
+application/vnd.framemaker                     fm frame maker book
+application/vnd.frogans.fnc                    fnc
+application/vnd.frogans.ltf                    ltf
+application/vnd.fsc.weblaunch                  fsc
+application/vnd.fujitsu.oasys                  oas
+application/vnd.fujitsu.oasys2                 oa2
+application/vnd.fujitsu.oasys3                 oa3
+application/vnd.fujitsu.oasysgp                        fg5
+application/vnd.fujitsu.oasysprs               bh2
+# application/vnd.fujixerox.art-ex
+# application/vnd.fujixerox.art4
+# application/vnd.fujixerox.hbpl
+application/vnd.fujixerox.ddd                  ddd
+application/vnd.fujixerox.docuworks            xdw
+application/vnd.fujixerox.docuworks.binder     xbd
+# application/vnd.fut-misnet
+application/vnd.fuzzysheet                     fzs
+application/vnd.genomatix.tuxedo               txd
+# application/vnd.geocube+xml
+application/vnd.geogebra.file                  ggb
+application/vnd.geogebra.tool                  ggt
+application/vnd.geometry-explorer              gex gre
+application/vnd.geonext                                gxt
+application/vnd.geoplan                                g2w
+application/vnd.geospace                       g3w
+# application/vnd.globalplatform.card-content-mgt
+# application/vnd.globalplatform.card-content-mgt-response
+application/vnd.gmx                            gmx
+application/vnd.google-earth.kml+xml           kml
+application/vnd.google-earth.kmz               kmz
+application/vnd.grafeq                         gqf gqs
+# application/vnd.gridmp
+application/vnd.groove-account                 gac
+application/vnd.groove-help                    ghf
+application/vnd.groove-identity-message                gim
+application/vnd.groove-injector                        grv
+application/vnd.groove-tool-message            gtm
+application/vnd.groove-tool-template           tpl
+application/vnd.groove-vcard                   vcg
+# application/vnd.hal+json
+application/vnd.hal+xml                                hal
+application/vnd.handheld-entertainment+xml     zmm
+application/vnd.hbci                           hbci
+# application/vnd.hcl-bireports
+application/vnd.hhe.lesson-player              les
+application/vnd.hp-hpgl                                hpgl
+application/vnd.hp-hpid                                hpid
+application/vnd.hp-hps                         hps
+application/vnd.hp-jlyt                                jlt
+application/vnd.hp-pcl                         pcl
+application/vnd.hp-pclxl                       pclxl
+# application/vnd.httphone
+application/vnd.hydrostatix.sof-data           sfd-hdstx
+# application/vnd.hzn-3d-crossword
+# application/vnd.ibm.afplinedata
+# application/vnd.ibm.electronic-media
+application/vnd.ibm.minipay                    mpy
+application/vnd.ibm.modcap                     afp listafp list3820
+application/vnd.ibm.rights-management          irm
+application/vnd.ibm.secure-container           sc
+application/vnd.iccprofile                     icc icm
+application/vnd.igloader                       igl
+application/vnd.immervision-ivp                        ivp
+application/vnd.immervision-ivu                        ivu
+# application/vnd.informedcontrol.rms+xml
+# application/vnd.informix-visionary
+# application/vnd.infotech.project
+# application/vnd.infotech.project+xml
+# application/vnd.innopath.wamp.notification
+application/vnd.insors.igm                     igm
+application/vnd.intercon.formnet               xpw xpx
+application/vnd.intergeo                       i2g
+# application/vnd.intertrust.digibox
+# application/vnd.intertrust.nncp
+application/vnd.intu.qbo                       qbo
+application/vnd.intu.qfx                       qfx
+# application/vnd.iptc.g2.conceptitem+xml
+# application/vnd.iptc.g2.knowledgeitem+xml
+# application/vnd.iptc.g2.newsitem+xml
+# application/vnd.iptc.g2.newsmessage+xml
+# application/vnd.iptc.g2.packageitem+xml
+# application/vnd.iptc.g2.planningitem+xml
+application/vnd.ipunplugged.rcprofile          rcprofile
+application/vnd.irepository.package+xml                irp
+application/vnd.is-xpr                         xpr
+application/vnd.isac.fcs                       fcs
+application/vnd.jam                            jam
+# application/vnd.japannet-directory-service
+# application/vnd.japannet-jpnstore-wakeup
+# application/vnd.japannet-payment-wakeup
+# application/vnd.japannet-registration
+# application/vnd.japannet-registration-wakeup
+# application/vnd.japannet-setstore-wakeup
+# application/vnd.japannet-verification
+# application/vnd.japannet-verification-wakeup
+application/vnd.jcp.javame.midlet-rms          rms
+application/vnd.jisp                           jisp
+application/vnd.joost.joda-archive             joda
+application/vnd.kahootz                                ktz ktr
+application/vnd.kde.karbon                     karbon
+application/vnd.kde.kchart                     chrt
+application/vnd.kde.kformula                   kfo
+application/vnd.kde.kivio                      flw
+application/vnd.kde.kontour                    kon
+application/vnd.kde.kpresenter                 kpr kpt
+application/vnd.kde.kspread                    ksp
+application/vnd.kde.kword                      kwd kwt
+application/vnd.kenameaapp                     htke
+application/vnd.kidspiration                   kia
+application/vnd.kinar                          kne knp
+application/vnd.koan                           skp skd skt skm
+application/vnd.kodak-descriptor               sse
+application/vnd.las.las+xml                    lasxml
+# application/vnd.liberty-request+xml
+application/vnd.llamagraphics.life-balance.desktop     lbd
+application/vnd.llamagraphics.life-balance.exchange+xml        lbe
+application/vnd.lotus-1-2-3                    123
+application/vnd.lotus-approach                 apr
+application/vnd.lotus-freelance                        pre
+application/vnd.lotus-notes                    nsf
+application/vnd.lotus-organizer                        org
+application/vnd.lotus-screencam                        scm
+application/vnd.lotus-wordpro                  lwp
+application/vnd.macports.portpkg               portpkg
+# application/vnd.marlin.drm.actiontoken+xml
+# application/vnd.marlin.drm.conftoken+xml
+# application/vnd.marlin.drm.license+xml
+# application/vnd.marlin.drm.mdcf
+application/vnd.mcd                            mcd
+application/vnd.medcalcdata                    mc1
+application/vnd.mediastation.cdkey             cdkey
+# application/vnd.meridian-slingshot
+application/vnd.mfer                           mwf
+application/vnd.mfmp                           mfm
+application/vnd.micrografx.flo                 flo
+application/vnd.micrografx.igx                 igx
+application/vnd.mif                            mif
+# application/vnd.minisoft-hp3000-save
+# application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf                     daf
+application/vnd.mobius.dis                     dis
+application/vnd.mobius.mbk                     mbk
+application/vnd.mobius.mqy                     mqy
+application/vnd.mobius.msl                     msl
+application/vnd.mobius.plc                     plc
+application/vnd.mobius.txf                     txf
+application/vnd.mophun.application             mpn
+application/vnd.mophun.certificate             mpc
+# application/vnd.motorola.flexsuite
+# application/vnd.motorola.flexsuite.adsi
+# application/vnd.motorola.flexsuite.fis
+# application/vnd.motorola.flexsuite.gotap
+# application/vnd.motorola.flexsuite.kmr
+# application/vnd.motorola.flexsuite.ttc
+# application/vnd.motorola.flexsuite.wem
+# application/vnd.motorola.iprm
+application/vnd.mozilla.xul+xml                        xul
+application/vnd.ms-artgalry                    cil
+# application/vnd.ms-asf
+application/vnd.ms-cab-compressed              cab
+# application/vnd.ms-color.iccprofile
+application/vnd.ms-excel                       xls xlm xla xlc xlt xlw
+application/vnd.ms-excel.addin.macroenabled.12         xlam
+application/vnd.ms-excel.sheet.binary.macroenabled.12  xlsb
+application/vnd.ms-excel.sheet.macroenabled.12         xlsm
+application/vnd.ms-excel.template.macroenabled.12      xltm
+application/vnd.ms-fontobject                  eot
+application/vnd.ms-htmlhelp                    chm
+application/vnd.ms-ims                         ims
+application/vnd.ms-lrm                         lrm
+# application/vnd.ms-office.activex+xml
+application/vnd.ms-officetheme                 thmx
+# application/vnd.ms-opentype
+# application/vnd.ms-package.obfuscated-opentype
+application/vnd.ms-pki.seccat                  cat
+application/vnd.ms-pki.stl                     stl
+# application/vnd.ms-playready.initiator+xml
+application/vnd.ms-powerpoint                  ppt pps pot
+application/vnd.ms-powerpoint.addin.macroenabled.12            ppam
+application/vnd.ms-powerpoint.presentation.macroenabled.12     pptm
+application/vnd.ms-powerpoint.slide.macroenabled.12            sldm
+application/vnd.ms-powerpoint.slideshow.macroenabled.12                ppsm
+application/vnd.ms-powerpoint.template.macroenabled.12         potm
+# application/vnd.ms-printing.printticket+xml
+application/vnd.ms-project                     mpp mpt
+# application/vnd.ms-tnef
+# application/vnd.ms-wmdrm.lic-chlg-req
+# application/vnd.ms-wmdrm.lic-resp
+# application/vnd.ms-wmdrm.meter-chlg-req
+# application/vnd.ms-wmdrm.meter-resp
+application/vnd.ms-word.document.macroenabled.12       docm
+application/vnd.ms-word.template.macroenabled.12       dotm
+application/vnd.ms-works                       wps wks wcm wdb
+application/vnd.ms-wpl                         wpl
+application/vnd.ms-xpsdocument                 xps
+application/vnd.mseq                           mseq
+# application/vnd.msign
+# application/vnd.multiad.creator
+# application/vnd.multiad.creator.cif
+# application/vnd.music-niff
+application/vnd.musician                       mus
+application/vnd.muvee.style                    msty
+application/vnd.mynfc                          taglet
+# application/vnd.ncd.control
+# application/vnd.ncd.reference
+# application/vnd.nervana
+# application/vnd.netfpx
+application/vnd.neurolanguage.nlu              nlu
+application/vnd.nitf                           ntf nitf
+application/vnd.noblenet-directory             nnd
+application/vnd.noblenet-sealer                        nns
+application/vnd.noblenet-web                   nnw
+# application/vnd.nokia.catalogs
+# application/vnd.nokia.conml+wbxml
+# application/vnd.nokia.conml+xml
+# application/vnd.nokia.isds-radio-presets
+# application/vnd.nokia.iptv.config+xml
+# application/vnd.nokia.landmark+wbxml
+# application/vnd.nokia.landmark+xml
+# application/vnd.nokia.landmarkcollection+xml
+# application/vnd.nokia.n-gage.ac+xml
+application/vnd.nokia.n-gage.data              ngdat
+application/vnd.nokia.n-gage.symbian.install   n-gage
+# application/vnd.nokia.ncd
+# application/vnd.nokia.pcd+wbxml
+# application/vnd.nokia.pcd+xml
+application/vnd.nokia.radio-preset             rpst
+application/vnd.nokia.radio-presets            rpss
+application/vnd.novadigm.edm                   edm
+application/vnd.novadigm.edx                   edx
+application/vnd.novadigm.ext                   ext
+# application/vnd.ntt-local.file-transfer
+# application/vnd.ntt-local.sip-ta_remote
+# application/vnd.ntt-local.sip-ta_tcp_stream
+application/vnd.oasis.opendocument.chart               odc
+application/vnd.oasis.opendocument.chart-template      otc
+application/vnd.oasis.opendocument.database            odb
+application/vnd.oasis.opendocument.formula             odf
+application/vnd.oasis.opendocument.formula-template    odft
+application/vnd.oasis.opendocument.graphics            odg
+application/vnd.oasis.opendocument.graphics-template   otg
+application/vnd.oasis.opendocument.image               odi
+application/vnd.oasis.opendocument.image-template      oti
+application/vnd.oasis.opendocument.presentation                odp
+application/vnd.oasis.opendocument.presentation-template       otp
+application/vnd.oasis.opendocument.spreadsheet         ods
+application/vnd.oasis.opendocument.spreadsheet-template        ots
+application/vnd.oasis.opendocument.text                        odt
+application/vnd.oasis.opendocument.text-master         odm
+application/vnd.oasis.opendocument.text-template       ott
+application/vnd.oasis.opendocument.text-web            oth
+# application/vnd.obn
+# application/vnd.oftn.l10n+json
+# application/vnd.oipf.contentaccessdownload+xml
+# application/vnd.oipf.contentaccessstreaming+xml
+# application/vnd.oipf.cspg-hexbinary
+# application/vnd.oipf.dae.svg+xml
+# application/vnd.oipf.dae.xhtml+xml
+# application/vnd.oipf.mippvcontrolmessage+xml
+# application/vnd.oipf.pae.gem
+# application/vnd.oipf.spdiscovery+xml
+# application/vnd.oipf.spdlist+xml
+# application/vnd.oipf.ueprofile+xml
+# application/vnd.oipf.userprofile+xml
+application/vnd.olpc-sugar                     xo
+# application/vnd.oma-scws-config
+# application/vnd.oma-scws-http-request
+# application/vnd.oma-scws-http-response
+# application/vnd.oma.bcast.associated-procedure-parameter+xml
+# application/vnd.oma.bcast.drm-trigger+xml
+# application/vnd.oma.bcast.imd+xml
+# application/vnd.oma.bcast.ltkm
+# application/vnd.oma.bcast.notification+xml
+# application/vnd.oma.bcast.provisioningtrigger
+# application/vnd.oma.bcast.sgboot
+# application/vnd.oma.bcast.sgdd+xml
+# application/vnd.oma.bcast.sgdu
+# application/vnd.oma.bcast.simple-symbol-container
+# application/vnd.oma.bcast.smartcard-trigger+xml
+# application/vnd.oma.bcast.sprov+xml
+# application/vnd.oma.bcast.stkm
+# application/vnd.oma.cab-address-book+xml
+# application/vnd.oma.cab-feature-handler+xml
+# application/vnd.oma.cab-pcc+xml
+# application/vnd.oma.cab-user-prefs+xml
+# application/vnd.oma.dcd
+# application/vnd.oma.dcdc
+application/vnd.oma.dd2+xml                    dd2
+# application/vnd.oma.drm.risd+xml
+# application/vnd.oma.group-usage-list+xml
+# application/vnd.oma.pal+xml
+# application/vnd.oma.poc.detailed-progress-report+xml
+# application/vnd.oma.poc.final-report+xml
+# application/vnd.oma.poc.groups+xml
+# application/vnd.oma.poc.invocation-descriptor+xml
+# application/vnd.oma.poc.optimized-progress-report+xml
+# application/vnd.oma.push
+# application/vnd.oma.scidm.messages+xml
+# application/vnd.oma.xcap-directory+xml
+# application/vnd.omads-email+xml
+# application/vnd.omads-file+xml
+# application/vnd.omads-folder+xml
+# application/vnd.omaloc-supl-init
+application/vnd.openofficeorg.extension                oxt
+# application/vnd.openxmlformats-officedocument.custom-properties+xml
+# application/vnd.openxmlformats-officedocument.customxmlproperties+xml
+# application/vnd.openxmlformats-officedocument.drawing+xml
+# application/vnd.openxmlformats-officedocument.drawingml.chart+xml
+# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml
+# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml
+# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml
+# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml
+# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml
+# application/vnd.openxmlformats-officedocument.extended-properties+xml
+# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml
+# application/vnd.openxmlformats-officedocument.presentationml.comments+xml
+# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml
+# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml
+# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml
+application/vnd.openxmlformats-officedocument.presentationml.presentation      pptx
+# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml
+# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml
+application/vnd.openxmlformats-officedocument.presentationml.slide     sldx
+# application/vnd.openxmlformats-officedocument.presentationml.slide+xml
+# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml
+# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml
+application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
+# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml
+# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml
+# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml
+# application/vnd.openxmlformats-officedocument.presentationml.tags+xml
+application/vnd.openxmlformats-officedocument.presentationml.template  potx
+# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml
+# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet      xlsx
+# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.template   xltx
+# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml
+# application/vnd.openxmlformats-officedocument.theme+xml
+# application/vnd.openxmlformats-officedocument.themeoverride+xml
+# application/vnd.openxmlformats-officedocument.vmldrawing
+# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.document        docx
+# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.template        dotx
+# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml
+# application/vnd.openxmlformats-package.core-properties+xml
+# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml
+# application/vnd.openxmlformats-package.relationships+xml
+# application/vnd.quobject-quoxdocument
+# application/vnd.osa.netdeploy
+application/vnd.osgeo.mapguide.package         mgp
+# application/vnd.osgi.bundle
+application/vnd.osgi.dp                                dp
+application/vnd.osgi.subsystem                 esa
+# application/vnd.otps.ct-kip+xml
+application/vnd.palm                           pdb pqa oprc
+# application/vnd.paos.xml
+application/vnd.pawaafile                      paw
+application/vnd.pg.format                      str
+application/vnd.pg.osasli                      ei6
+# application/vnd.piaccess.application-licence
+application/vnd.picsel                         efif
+application/vnd.pmi.widget                     wg
+# application/vnd.poc.group-advertisement+xml
+application/vnd.pocketlearn                    plf
+application/vnd.powerbuilder6                  pbd
+# application/vnd.powerbuilder6-s
+# application/vnd.powerbuilder7
+# application/vnd.powerbuilder7-s
+# application/vnd.powerbuilder75
+# application/vnd.powerbuilder75-s
+# application/vnd.preminet
+application/vnd.previewsystems.box             box
+application/vnd.proteus.magazine               mgz
+application/vnd.publishare-delta-tree          qps
+application/vnd.pvi.ptid1                      ptid
+# application/vnd.pwg-multiplexed
+# application/vnd.pwg-xhtml-print+xml
+# application/vnd.qualcomm.brew-app-res
+application/vnd.quark.quarkxpress              qxd qxt qwd qwt qxl qxb
+# application/vnd.radisys.moml+xml
+# application/vnd.radisys.msml+xml
+# application/vnd.radisys.msml-audit+xml
+# application/vnd.radisys.msml-audit-conf+xml
+# application/vnd.radisys.msml-audit-conn+xml
+# application/vnd.radisys.msml-audit-dialog+xml
+# application/vnd.radisys.msml-audit-stream+xml
+# application/vnd.radisys.msml-conf+xml
+# application/vnd.radisys.msml-dialog+xml
+# application/vnd.radisys.msml-dialog-base+xml
+# application/vnd.radisys.msml-dialog-fax-detect+xml
+# application/vnd.radisys.msml-dialog-fax-sendrecv+xml
+# application/vnd.radisys.msml-dialog-group+xml
+# application/vnd.radisys.msml-dialog-speech+xml
+# application/vnd.radisys.msml-dialog-transform+xml
+# application/vnd.rainstor.data
+# application/vnd.rapid
+application/vnd.realvnc.bed                    bed
+application/vnd.recordare.musicxml             mxl
+application/vnd.recordare.musicxml+xml         musicxml
+# application/vnd.renlearn.rlprint
+application/vnd.rig.cryptonote                 cryptonote
+application/vnd.rim.cod                                cod
+application/vnd.rn-realmedia                   rm
+application/vnd.rn-realmedia-vbr               rmvb
+application/vnd.route66.link66+xml             link66
+# application/vnd.rs-274x
+# application/vnd.ruckus.download
+# application/vnd.s3sms
+application/vnd.sailingtracker.track           st
+# application/vnd.sbm.cid
+# application/vnd.sbm.mid2
+# application/vnd.scribus
+# application/vnd.sealed.3df
+# application/vnd.sealed.csf
+# application/vnd.sealed.doc
+# application/vnd.sealed.eml
+# application/vnd.sealed.mht
+# application/vnd.sealed.net
+# application/vnd.sealed.ppt
+# application/vnd.sealed.tiff
+# application/vnd.sealed.xls
+# application/vnd.sealedmedia.softseal.html
+# application/vnd.sealedmedia.softseal.pdf
+application/vnd.seemail                                see
+application/vnd.sema                           sema
+application/vnd.semd                           semd
+application/vnd.semf                           semf
+application/vnd.shana.informed.formdata                ifm
+application/vnd.shana.informed.formtemplate    itp
+application/vnd.shana.informed.interchange     iif
+application/vnd.shana.informed.package         ipk
+application/vnd.simtech-mindmapper             twd twds
+application/vnd.smaf                           mmf
+# application/vnd.smart.notebook
+application/vnd.smart.teacher                  teacher
+# application/vnd.software602.filler.form+xml
+# application/vnd.software602.filler.form-xml-zip
+application/vnd.solent.sdkm+xml                        sdkm sdkd
+application/vnd.spotfire.dxp                   dxp
+application/vnd.spotfire.sfs                   sfs
+# application/vnd.sss-cod
+# application/vnd.sss-dtf
+# application/vnd.sss-ntf
+application/vnd.stardivision.calc              sdc
+application/vnd.stardivision.draw              sda
+application/vnd.stardivision.impress           sdd
+application/vnd.stardivision.math              smf
+application/vnd.stardivision.writer            sdw vor
+application/vnd.stardivision.writer-global     sgl
+application/vnd.stepmania.package              smzip
+application/vnd.stepmania.stepchart            sm
+# application/vnd.street-stream
+application/vnd.sun.xml.calc                   sxc
+application/vnd.sun.xml.calc.template          stc
+application/vnd.sun.xml.draw                   sxd
+application/vnd.sun.xml.draw.template          std
+application/vnd.sun.xml.impress                        sxi
+application/vnd.sun.xml.impress.template       sti
+application/vnd.sun.xml.math                   sxm
+application/vnd.sun.xml.writer                 sxw
+application/vnd.sun.xml.writer.global          sxg
+application/vnd.sun.xml.writer.template                stw
+# application/vnd.sun.wadl+xml
+application/vnd.sus-calendar                   sus susp
+application/vnd.svd                            svd
+# application/vnd.swiftview-ics
+application/vnd.symbian.install                        sis sisx
+application/vnd.syncml+xml                     xsm
+application/vnd.syncml.dm+wbxml                        bdm
+application/vnd.syncml.dm+xml                  xdm
+# application/vnd.syncml.dm.notification
+# application/vnd.syncml.ds.notification
+application/vnd.tao.intent-module-archive      tao
+application/vnd.tcpdump.pcap                   pcap cap dmp
+application/vnd.tmobile-livetv                 tmo
+application/vnd.trid.tpt                       tpt
+application/vnd.triscape.mxs                   mxs
+application/vnd.trueapp                                tra
+# application/vnd.truedoc
+# application/vnd.ubisoft.webplayer
+application/vnd.ufdl                           ufd ufdl
+application/vnd.uiq.theme                      utz
+application/vnd.umajin                         umj
+application/vnd.unity                          unityweb
+application/vnd.uoml+xml                       uoml
+# application/vnd.uplanet.alert
+# application/vnd.uplanet.alert-wbxml
+# application/vnd.uplanet.bearer-choice
+# application/vnd.uplanet.bearer-choice-wbxml
+# application/vnd.uplanet.cacheop
+# application/vnd.uplanet.cacheop-wbxml
+# application/vnd.uplanet.channel
+# application/vnd.uplanet.channel-wbxml
+# application/vnd.uplanet.list
+# application/vnd.uplanet.list-wbxml
+# application/vnd.uplanet.listcmd
+# application/vnd.uplanet.listcmd-wbxml
+# application/vnd.uplanet.signal
+application/vnd.vcx                            vcx
+# application/vnd.vd-study
+# application/vnd.vectorworks
+# application/vnd.verimatrix.vcas
+# application/vnd.vidsoft.vidconference
+application/vnd.visio                          vsd vst vss vsw
+application/vnd.visionary                      vis
+# application/vnd.vividence.scriptfile
+application/vnd.vsf                            vsf
+# application/vnd.wap.sic
+# application/vnd.wap.slc
+application/vnd.wap.wbxml                      wbxml
+application/vnd.wap.wmlc                       wmlc
+application/vnd.wap.wmlscriptc                 wmlsc
+application/vnd.webturbo                       wtb
+# application/vnd.wfa.wsc
+# application/vnd.wmc
+# application/vnd.wmf.bootstrap
+# application/vnd.wolfram.mathematica
+# application/vnd.wolfram.mathematica.package
+application/vnd.wolfram.player                 nbp
+application/vnd.wordperfect                    wpd
+application/vnd.wqd                            wqd
+# application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf                         stf
+# application/vnd.wv.csp+wbxml
+# application/vnd.wv.csp+xml
+# application/vnd.wv.ssp+xml
+application/vnd.xara                           xar
+application/vnd.xfdl                           xfdl
+# application/vnd.xfdl.webform
+# application/vnd.xmi+xml
+# application/vnd.xmpie.cpkg
+# application/vnd.xmpie.dpkg
+# application/vnd.xmpie.plan
+# application/vnd.xmpie.ppkg
+# application/vnd.xmpie.xlim
+application/vnd.yamaha.hv-dic                  hvd
+application/vnd.yamaha.hv-script               hvs
+application/vnd.yamaha.hv-voice                        hvp
+application/vnd.yamaha.openscoreformat                 osf
+application/vnd.yamaha.openscoreformat.osfpvg+xml      osfpvg
+# application/vnd.yamaha.remote-setup
+application/vnd.yamaha.smaf-audio              saf
+application/vnd.yamaha.smaf-phrase             spf
+# application/vnd.yamaha.through-ngn
+# application/vnd.yamaha.tunnel-udpencap
+application/vnd.yellowriver-custom-menu                cmp
+application/vnd.zul                            zir zirz
+application/vnd.zzazz.deck+xml                 zaz
+application/voicexml+xml                       vxml
+# application/vq-rtcpxr
+# application/watcherinfo+xml
+# application/whoispp-query
+# application/whoispp-response
+application/widget                             wgt
+application/winhlp                             hlp
+# application/wita
+# application/wordperfect5.1
+application/wsdl+xml                           wsdl
+application/wspolicy+xml                       wspolicy
+application/x-7z-compressed                    7z
+application/x-abiword                          abw
+application/x-ace-compressed                   ace
+# application/x-amf
+application/x-apple-diskimage                  dmg
+application/x-authorware-bin                   aab x32 u32 vox
+application/x-authorware-map                   aam
+application/x-authorware-seg                   aas
+application/x-bcpio                            bcpio
+application/x-bittorrent                       torrent
+application/x-blorb                            blb blorb
+application/x-bzip                             bz
+application/x-bzip2                            bz2 boz
+application/x-cbr                              cbr cba cbt cbz cb7
+application/x-cdlink                           vcd
+application/x-cfs-compressed                   cfs
+application/x-chat                             chat
+application/x-chess-pgn                                pgn
+application/x-conference                       nsc
+# application/x-compress
+application/x-cpio                             cpio
+application/x-csh                              csh
+application/x-debian-package                   deb udeb
+application/x-dgc-compressed                   dgc
+application/x-director                 dir dcr dxr cst cct cxt w3d fgd swa
+application/x-doom                             wad
+application/x-dtbncx+xml                       ncx
+application/x-dtbook+xml                       dtb
+application/x-dtbresource+xml                  res
+application/x-dvi                              dvi
+application/x-envoy                            evy
+application/x-eva                              eva
+application/x-font-bdf                         bdf
+# application/x-font-dos
+# application/x-font-framemaker
+application/x-font-ghostscript                 gsf
+# application/x-font-libgrx
+application/x-font-linux-psf                   psf
+application/x-font-otf                         otf
+application/x-font-pcf                         pcf
+application/x-font-snf                         snf
+# application/x-font-speedo
+# application/x-font-sunos-news
+application/x-font-ttf                         ttf ttc
+application/x-font-type1                       pfa pfb pfm afm
+application/x-font-woff                                woff
+# application/x-font-vfont
+application/x-freearc                          arc
+application/x-futuresplash                     spl
+application/x-gca-compressed                   gca
+application/x-glulx                            ulx
+application/x-gnumeric                         gnumeric
+application/x-gramps-xml                       gramps
+application/x-gtar                             gtar
+# application/x-gzip
+application/x-hdf                              hdf
+application/x-install-instructions             install
+application/x-iso9660-image                    iso
+application/x-java-jnlp-file                   jnlp
+application/x-latex                            latex
+application/x-lzh-compressed                   lzh lha
+application/x-mie                              mie
+application/x-mobipocket-ebook                 prc mobi
+application/x-ms-application                   application
+application/x-ms-shortcut                      lnk
+application/x-ms-wmd                           wmd
+application/x-ms-wmz                           wmz
+application/x-ms-xbap                          xbap
+application/x-msaccess                         mdb
+application/x-msbinder                         obd
+application/x-mscardfile                       crd
+application/x-msclip                           clp
+application/x-msdownload                       exe dll com bat msi
+application/x-msmediaview                      mvb m13 m14
+application/x-msmetafile                       wmf wmz emf emz
+application/x-msmoney                          mny
+application/x-mspublisher                      pub
+application/x-msschedule                       scd
+application/x-msterminal                       trm
+application/x-mswrite                          wri
+application/x-netcdf                           nc cdf
+application/x-nzb                              nzb
+application/x-pkcs12                           p12 pfx
+application/x-pkcs7-certificates               p7b spc
+application/x-pkcs7-certreqresp                        p7r
+application/x-rar-compressed                   rar
+application/x-research-info-systems            ris
+application/x-sh                               sh
+application/x-shar                             shar
+application/x-shockwave-flash                  swf
+application/x-silverlight-app                  xap
+application/x-sql                              sql
+application/x-stuffit                          sit
+application/x-stuffitx                         sitx
+application/x-subrip                           srt
+application/x-sv4cpio                          sv4cpio
+application/x-sv4crc                           sv4crc
+application/x-t3vm-image                       t3
+application/x-tads                             gam
+application/x-tar                              tar
+application/x-tcl                              tcl
+application/x-tex                              tex
+application/x-tex-tfm                          tfm
+application/x-texinfo                          texinfo texi
+application/x-tgif                             obj
+application/x-ustar                            ustar
+application/x-wais-source                      src
+application/x-x509-ca-cert                     der crt
+application/x-xfig                             fig
+application/x-xliff+xml                                xlf
+application/x-xpinstall                                xpi
+application/x-xz                               xz
+application/x-zmachine                         z1 z2 z3 z4 z5 z6 z7 z8
+# application/x400-bp
+application/xaml+xml                           xaml
+# application/xcap-att+xml
+# application/xcap-caps+xml
+application/xcap-diff+xml                      xdf
+# application/xcap-el+xml
+# application/xcap-error+xml
+# application/xcap-ns+xml
+# application/xcon-conference-info-diff+xml
+# application/xcon-conference-info+xml
+application/xenc+xml                           xenc
+application/xhtml+xml                          xhtml xht
+# application/xhtml-voice+xml
+application/xml                                        xml xsl
+application/xml-dtd                            dtd
+# application/xml-external-parsed-entity
+# application/xmpp+xml
+application/xop+xml                            xop
+application/xproc+xml                          xpl
+application/xslt+xml                           xslt
+application/xspf+xml                           xspf
+application/xv+xml                             mxml xhvml xvml xvm
+application/yang                               yang
+application/yin+xml                            yin
+application/zip                                        zip
+# audio/1d-interleaved-parityfec
+# audio/32kadpcm
+# audio/3gpp
+# audio/3gpp2
+# audio/ac3
+audio/adpcm                                    adp
+# audio/amr
+# audio/amr-wb
+# audio/amr-wb+
+# audio/asc
+# audio/atrac-advanced-lossless
+# audio/atrac-x
+# audio/atrac3
+audio/basic                                    au snd
+# audio/bv16
+# audio/bv32
+# audio/clearmode
+# audio/cn
+# audio/dat12
+# audio/dls
+# audio/dsr-es201108
+# audio/dsr-es202050
+# audio/dsr-es202211
+# audio/dsr-es202212
+# audio/dv
+# audio/dvi4
+# audio/eac3
+# audio/evrc
+# audio/evrc-qcp
+# audio/evrc0
+# audio/evrc1
+# audio/evrcb
+# audio/evrcb0
+# audio/evrcb1
+# audio/evrcwb
+# audio/evrcwb0
+# audio/evrcwb1
+# audio/example
+# audio/fwdred
+# audio/g719
+# audio/g722
+# audio/g7221
+# audio/g723
+# audio/g726-16
+# audio/g726-24
+# audio/g726-32
+# audio/g726-40
+# audio/g728
+# audio/g729
+# audio/g7291
+# audio/g729d
+# audio/g729e
+# audio/gsm
+# audio/gsm-efr
+# audio/gsm-hr-08
+# audio/ilbc
+# audio/ip-mr_v2.5
+# audio/isac
+# audio/l16
+# audio/l20
+# audio/l24
+# audio/l8
+# audio/lpc
+audio/midi                                     mid midi kar rmi
+# audio/mobile-xmf
+audio/mp4                                      mp4a
+# audio/mp4a-latm
+# audio/mpa
+# audio/mpa-robust
+audio/mpeg                                     mpga mp2 mp2a mp3 m2a m3a
+# audio/mpeg4-generic
+# audio/musepack
+audio/ogg                                      oga ogg spx
+# audio/opus
+# audio/parityfec
+# audio/pcma
+# audio/pcma-wb
+# audio/pcmu-wb
+# audio/pcmu
+# audio/prs.sid
+# audio/qcelp
+# audio/red
+# audio/rtp-enc-aescm128
+# audio/rtp-midi
+# audio/rtx
+audio/s3m                                      s3m
+audio/silk                                     sil
+# audio/smv
+# audio/smv0
+# audio/smv-qcp
+# audio/sp-midi
+# audio/speex
+# audio/t140c
+# audio/t38
+# audio/telephone-event
+# audio/tone
+# audio/uemclip
+# audio/ulpfec
+# audio/vdvi
+# audio/vmr-wb
+# audio/vnd.3gpp.iufp
+# audio/vnd.4sb
+# audio/vnd.audiokoz
+# audio/vnd.celp
+# audio/vnd.cisco.nse
+# audio/vnd.cmles.radio-events
+# audio/vnd.cns.anp1
+# audio/vnd.cns.inf1
+audio/vnd.dece.audio                           uva uvva
+audio/vnd.digital-winds                                eol
+# audio/vnd.dlna.adts
+# audio/vnd.dolby.heaac.1
+# audio/vnd.dolby.heaac.2
+# audio/vnd.dolby.mlp
+# audio/vnd.dolby.mps
+# audio/vnd.dolby.pl2
+# audio/vnd.dolby.pl2x
+# audio/vnd.dolby.pl2z
+# audio/vnd.dolby.pulse.1
+audio/vnd.dra                                  dra
+audio/vnd.dts                                  dts
+audio/vnd.dts.hd                               dtshd
+# audio/vnd.dvb.file
+# audio/vnd.everad.plj
+# audio/vnd.hns.audio
+audio/vnd.lucent.voice                         lvp
+audio/vnd.ms-playready.media.pya               pya
+# audio/vnd.nokia.mobile-xmf
+# audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800                      ecelp4800
+audio/vnd.nuera.ecelp7470                      ecelp7470
+audio/vnd.nuera.ecelp9600                      ecelp9600
+# audio/vnd.octel.sbc
+# audio/vnd.qcelp
+# audio/vnd.rhetorex.32kadpcm
+audio/vnd.rip                                  rip
+# audio/vnd.sealedmedia.softseal.mpeg
+# audio/vnd.vmx.cvsd
+# audio/vorbis
+# audio/vorbis-config
+audio/webm                                     weba
+audio/x-aac                                    aac
+audio/x-aiff                                   aif aiff aifc
+audio/x-caf                                    caf
+audio/x-flac                                   flac
+audio/x-matroska                               mka
+audio/x-mpegurl                                        m3u
+audio/x-ms-wax                                 wax
+audio/x-ms-wma                                 wma
+audio/x-pn-realaudio                           ram ra
+audio/x-pn-realaudio-plugin                    rmp
+# audio/x-tta
+audio/x-wav                                    wav
+audio/xm                                       xm
+chemical/x-cdx                                 cdx
+chemical/x-cif                                 cif
+chemical/x-cmdf                                        cmdf
+chemical/x-cml                                 cml
+chemical/x-csml                                        csml
+# chemical/x-pdb
+chemical/x-xyz                                 xyz
+image/bmp                                      bmp
+image/cgm                                      cgm
+# image/example
+# image/fits
+image/g3fax                                    g3
+image/gif                                      gif
+image/ief                                      ief
+# image/jp2
+image/jpeg                                     jpeg jpg jpe
+# image/jpm
+# image/jpx
+image/ktx                                      ktx
+# image/naplps
+image/png                                      png
+image/prs.btif                                 btif
+# image/prs.pti
+image/sgi                                      sgi
+image/svg+xml                                  svg svgz
+# image/t38
+image/tiff                                     tiff tif
+# image/tiff-fx
+image/vnd.adobe.photoshop                      psd
+# image/vnd.cns.inf2
+image/vnd.dece.graphic                         uvi uvvi uvg uvvg
+image/vnd.dvb.subtitle                         sub
+image/vnd.djvu                                 djvu djv
+image/vnd.dwg                                  dwg
+image/vnd.dxf                                  dxf
+image/vnd.fastbidsheet                         fbs
+image/vnd.fpx                                  fpx
+image/vnd.fst                                  fst
+image/vnd.fujixerox.edmics-mmr                 mmr
+image/vnd.fujixerox.edmics-rlc                 rlc
+# image/vnd.globalgraphics.pgb
+# image/vnd.microsoft.icon
+# image/vnd.mix
+image/vnd.ms-modi                              mdi
+image/vnd.ms-photo                             wdp
+image/vnd.net-fpx                              npx
+# image/vnd.radiance
+# image/vnd.sealed.png
+# image/vnd.sealedmedia.softseal.gif
+# image/vnd.sealedmedia.softseal.jpg
+# image/vnd.svf
+image/vnd.wap.wbmp                             wbmp
+image/vnd.xiff                                 xif
+image/webp                                     webp
+image/x-3ds                                    3ds
+image/x-cmu-raster                             ras
+image/x-cmx                                    cmx
+image/x-freehand                               fh fhc fh4 fh5 fh7
+image/x-icon                                   ico
+image/x-mrsid-image                            sid
+image/x-pcx                                    pcx
+image/x-pict                                   pic pct
+image/x-portable-anymap                                pnm
+image/x-portable-bitmap                                pbm
+image/x-portable-graymap                       pgm
+image/x-portable-pixmap                                ppm
+image/x-rgb                                    rgb
+image/x-tga                                    tga
+image/x-xbitmap                                        xbm
+image/x-xpixmap                                        xpm
+image/x-xwindowdump                            xwd
+# message/cpim
+# message/delivery-status
+# message/disposition-notification
+# message/example
+# message/external-body
+# message/feedback-report
+# message/global
+# message/global-delivery-status
+# message/global-disposition-notification
+# message/global-headers
+# message/http
+# message/imdn+xml
+# message/news
+# message/partial
+message/rfc822                                 eml mime
+# message/s-http
+# message/sip
+# message/sipfrag
+# message/tracking-status
+# message/vnd.si.simp
+# model/example
+model/iges                                     igs iges
+model/mesh                                     msh mesh silo
+model/vnd.collada+xml                          dae
+model/vnd.dwf                                  dwf
+# model/vnd.flatland.3dml
+model/vnd.gdl                                  gdl
+# model/vnd.gs-gdl
+# model/vnd.gs.gdl
+model/vnd.gtw                                  gtw
+# model/vnd.moml+xml
+model/vnd.mts                                  mts
+# model/vnd.parasolid.transmit.binary
+# model/vnd.parasolid.transmit.text
+model/vnd.vtu                                  vtu
+model/vrml                                     wrl vrml
+model/x3d+binary                               x3db x3dbz
+model/x3d+vrml                                 x3dv x3dvz
+model/x3d+xml                                  x3d x3dz
+# multipart/alternative
+# multipart/appledouble
+# multipart/byteranges
+# multipart/digest
+# multipart/encrypted
+# multipart/example
+# multipart/form-data
+# multipart/header-set
+# multipart/mixed
+# multipart/parallel
+# multipart/related
+# multipart/report
+# multipart/signed
+# multipart/voice-message
+# text/1d-interleaved-parityfec
+text/cache-manifest                            appcache
+text/calendar                                  ics ifb
+text/css                                       css
+text/csv                                       csv
+# text/directory
+# text/dns
+# text/ecmascript
+# text/enriched
+# text/example
+# text/fwdred
+text/html                                      html htm
+# text/javascript
+text/n3                                                n3
+# text/parityfec
+text/plain                                     txt text conf def list log in
+# text/prs.fallenstein.rst
+text/prs.lines.tag                             dsc
+# text/vnd.radisys.msml-basic-layout
+# text/red
+# text/rfc822-headers
+text/richtext                                  rtx
+# text/rtf
+# text/rtp-enc-aescm128
+# text/rtx
+text/sgml                                      sgml sgm
+# text/t140
+text/tab-separated-values                      tsv
+text/troff                                     t tr roff man me ms
+text/turtle                                    ttl
+# text/ulpfec
+text/uri-list                                  uri uris urls
+text/vcard                                     vcard
+# text/vnd.abc
+text/vnd.curl                                  curl
+text/vnd.curl.dcurl                            dcurl
+text/vnd.curl.scurl                            scurl
+text/vnd.curl.mcurl                            mcurl
+# text/vnd.dmclientscript
+text/vnd.dvb.subtitle                          sub
+# text/vnd.esmertec.theme-descriptor
+text/vnd.fly                                   fly
+text/vnd.fmi.flexstor                          flx
+text/vnd.graphviz                              gv
+text/vnd.in3d.3dml                             3dml
+text/vnd.in3d.spot                             spot
+# text/vnd.iptc.newsml
+# text/vnd.iptc.nitf
+# text/vnd.latex-z
+# text/vnd.motorola.reflex
+# text/vnd.ms-mediapackage
+# text/vnd.net2phone.commcenter.command
+# text/vnd.si.uricatalogue
+text/vnd.sun.j2me.app-descriptor               jad
+# text/vnd.trolltech.linguist
+# text/vnd.wap.si
+# text/vnd.wap.sl
+text/vnd.wap.wml                               wml
+text/vnd.wap.wmlscript                         wmls
+text/x-asm                                     s asm
+text/x-c                                       c cc cxx cpp h hh dic
+text/x-fortran                                 f for f77 f90
+text/x-java-source                             java
+text/x-opml                                    opml
+text/x-pascal                                  p pas
+text/x-nfo                                     nfo
+text/x-setext                                  etx
+text/x-sfv                                     sfv
+text/x-uuencode                                        uu
+text/x-vcalendar                               vcs
+text/x-vcard                                   vcf
+# text/xml
+# text/xml-external-parsed-entity
+# video/1d-interleaved-parityfec
+video/3gpp                                     3gp
+# video/3gpp-tt
+video/3gpp2                                    3g2
+# video/bmpeg
+# video/bt656
+# video/celb
+# video/dv
+# video/example
+video/h261                                     h261
+video/h263                                     h263
+# video/h263-1998
+# video/h263-2000
+video/h264                                     h264
+# video/h264-rcdo
+# video/h264-svc
+video/jpeg                                     jpgv
+# video/jpeg2000
+video/jpm                                      jpm jpgm
+video/mj2                                      mj2 mjp2
+# video/mp1s
+# video/mp2p
+# video/mp2t
+video/mp4                                      mp4 mp4v mpg4
+# video/mp4v-es
+video/mpeg                                     mpeg mpg mpe m1v m2v
+# video/mpeg4-generic
+# video/mpv
+# video/nv
+video/ogg                                      ogv
+# video/parityfec
+# video/pointer
+video/quicktime                                        qt mov
+# video/raw
+# video/rtp-enc-aescm128
+# video/rtx
+# video/smpte292m
+# video/ulpfec
+# video/vc1
+# video/vnd.cctv
+video/vnd.dece.hd                              uvh uvvh
+video/vnd.dece.mobile                          uvm uvvm
+# video/vnd.dece.mp4
+video/vnd.dece.pd                              uvp uvvp
+video/vnd.dece.sd                              uvs uvvs
+video/vnd.dece.video                           uvv uvvv
+# video/vnd.directv.mpeg
+# video/vnd.directv.mpeg-tts
+# video/vnd.dlna.mpeg-tts
+video/vnd.dvb.file                             dvb
+video/vnd.fvt                                  fvt
+# video/vnd.hns.video
+# video/vnd.iptvforum.1dparityfec-1010
+# video/vnd.iptvforum.1dparityfec-2005
+# video/vnd.iptvforum.2dparityfec-1010
+# video/vnd.iptvforum.2dparityfec-2005
+# video/vnd.iptvforum.ttsavc
+# video/vnd.iptvforum.ttsmpeg2
+# video/vnd.motorola.video
+# video/vnd.motorola.videop
+video/vnd.mpegurl                              mxu m4u
+video/vnd.ms-playready.media.pyv               pyv
+# video/vnd.nokia.interleaved-multimedia
+# video/vnd.nokia.videovoip
+# video/vnd.objectvideo
+# video/vnd.sealed.mpeg1
+# video/vnd.sealed.mpeg4
+# video/vnd.sealed.swf
+# video/vnd.sealedmedia.softseal.mov
+video/vnd.uvvu.mp4                             uvu uvvu
+video/vnd.vivo                                 viv
+video/webm                                     webm
+video/x-f4v                                    f4v
+video/x-fli                                    fli
+video/x-flv                                    flv
+video/x-m4v                                    m4v
+video/x-matroska                               mkv mk3d mks
+video/x-mng                                    mng
+video/x-ms-asf                                 asf asx
+video/x-ms-vob                                 vob
+video/x-ms-wm                                  wm
+video/x-ms-wmv                                 wmv
+video/x-ms-wmx                                 wmx
+video/x-ms-wvx                                 wvx
+video/x-msvideo                                        avi
+video/x-sgi-movie                              movie
+video/x-smv                                    smv
+x-conference/x-cooltalk                                ice
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/types/node.types b/deps/npm/node_modules/node-gyp/node_modules/request/node_modules/mime/types/node.types
new file mode 100644 (file)
index 0000000..9097334
--- /dev/null
@@ -0,0 +1,59 @@
+# What: Google Chrome Extension
+# Why: To allow apps to (work) be served with the right content type header.
+# http://codereview.chromium.org/2830017
+# Added by: niftylettuce
+application/x-chrome-extension  crx
+
+# What: OTF Message Silencer
+# Why: To silence the "Resource interpreted as font but transferred with MIME
+# type font/otf" message that occurs in Google Chrome
+# Added by: niftylettuce
+font/opentype  otf
+
+# What: HTC support
+# Why: To properly render .htc files such as CSS3PIE
+# Added by: niftylettuce
+text/x-component  htc
+
+# What: HTML5 application cache manifest
+# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps
+# per https://developer.mozilla.org/en/offline_resources_in_firefox
+# Added by: louisremi
+text/cache-manifest  appcache manifest
+
+# What: node binary buffer format
+# Why: semi-standard extension w/in the node community
+# Added by: tootallnate
+application/octet-stream  buffer
+
+# What: The "protected" MP-4 formats used by iTunes.
+# Why: Required for streaming music to browsers (?)
+# Added by: broofa
+application/mp4  m4p
+audio/mp4  m4a
+
+# What: Music playlist format (http://en.wikipedia.org/wiki/M3U)
+# Why: See https://github.com/bentomas/node-mime/pull/6
+# Added by: mjrusso
+application/x-mpegURL  m3u8
+
+# What: Video format, Part of RFC1890
+# Why: See https://github.com/bentomas/node-mime/pull/6
+# Added by: mjrusso
+video/MP2T  ts
+
+# What: The FLAC lossless codec format
+# Why: Streaming and serving FLAC audio
+# Added by: jacobrask
+audio/flac  flac
+
+# What: EventSource mime type
+# Why: mime type of Server-Sent Events stream
+# http://www.w3.org/TR/eventsource/#text-event-stream
+# Added by: francois2metz
+text/event-stream  event-stream
+
+# What: Mozilla App manifest mime type
+# Why: https://developer.mozilla.org/en/Apps/Manifest#Serving_manifests
+# Added by: ednapiranha
+application/x-web-app-manifest+json   webapp
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/oauth.js b/deps/npm/node_modules/node-gyp/node_modules/request/oauth.js
new file mode 100644 (file)
index 0000000..e35bfa6
--- /dev/null
@@ -0,0 +1,43 @@
+var crypto = require('crypto')
+  , qs = require('querystring')
+  ;
+
+function sha1 (key, body) {
+  return crypto.createHmac('sha1', key).update(body).digest('base64')
+}
+
+function rfc3986 (str) {
+  return encodeURIComponent(str)
+    .replace(/!/g,'%21')
+    .replace(/\*/g,'%2A')
+    .replace(/\(/g,'%28')
+    .replace(/\)/g,'%29')
+    .replace(/'/g,'%27')
+    ;
+}
+
+function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret) {
+  // adapted from https://dev.twitter.com/docs/auth/oauth and 
+  // https://dev.twitter.com/docs/auth/creating-signature
+
+  var querystring = Object.keys(params).sort().map(function(key){
+    // big WTF here with the escape + encoding but it's what twitter wants
+    return escape(rfc3986(key)) + "%3D" + escape(rfc3986(params[key]))
+  }).join('%26')
+
+  var base = [
+    httpMethod ? httpMethod.toUpperCase() : 'GET',
+    rfc3986(base_uri),
+    querystring
+  ].join('&')
+
+  var key = [
+    consumer_secret,
+    token_secret || ''
+  ].map(rfc3986).join('&')
+
+  return sha1(key, base)
+}
+
+exports.hmacsign = hmacsign
+exports.rfc3986 = rfc3986
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/package.json b/deps/npm/node_modules/node-gyp/node_modules/request/package.json
new file mode 100644 (file)
index 0000000..5a4850c
--- /dev/null
@@ -0,0 +1,45 @@
+{
+  "name": "request",
+  "description": "Simplified HTTP request client.",
+  "tags": [
+    "http",
+    "simple",
+    "util",
+    "utility"
+  ],
+  "version": "2.12.0",
+  "author": {
+    "name": "Mikeal Rogers",
+    "email": "mikeal.rogers@gmail.com"
+  },
+  "repository": {
+    "type": "git",
+    "url": "http://github.com/mikeal/request.git"
+  },
+  "bugs": {
+    "url": "http://github.com/mikeal/request/issues"
+  },
+  "engines": [
+    "node >= 0.3.6"
+  ],
+  "main": "./main",
+  "dependencies": {
+    "form-data": "~0.0.3",
+    "mime": "~1.2.7"
+  },
+  "bundleDependencies": [
+    "form-data",
+    "mime"
+  ],
+  "scripts": {
+    "test": "node tests/run.js"
+  },
+  "readme": "# Request -- Simplified HTTP request method\n\n## Install\n\n<pre>\n  npm install request\n</pre>\n\nOr from source:\n\n<pre>\n  git clone git://github.com/mikeal/request.git \n  cd request\n  npm link\n</pre>\n\n## Super simple to use\n\nRequest is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.\n\n```javascript\nvar request = require('request');\nrequest('http://www.google.com', function (error, response, body) {\n  if (!error && response.statusCode == 200) {\n    console.log(body) // Print the google web page.\n  }\n})\n```\n\n## Streaming\n\nYou can stream any response to a file stream.\n\n```javascript\nrequest('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))\n```\n\nYou can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.\n\n```javascript\nfs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))\n```\n\nRequest can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.\n\n```javascript\nrequest.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))\n```\n\nNow let's get fancy.\n\n```javascript\nhttp.createServer(function (req, resp) {\n  if (req.url === '/doodle.png') {\n    if (req.method === 'PUT') {\n      req.pipe(request.put('http://mysite.com/doodle.png'))\n    } else if (req.method === 'GET' || req.method === 'HEAD') {\n      request.get('http://mysite.com/doodle.png').pipe(resp)\n    } \n  }\n})\n```\n\nYou can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:\n\n```javascript\nhttp.createServer(function (req, resp) {\n  if (req.url === '/doodle.png') {\n    var x = request('http://mysite.com/doodle.png')\n    req.pipe(x)\n    x.pipe(resp)\n  }\n})\n```\n\nAnd since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)\n\n```javascript\nreq.pipe(request('http://mysite.com/doodle.png')).pipe(resp)\n```\n\nAlso, none of this new functionality conflicts with requests previous features, it just expands them.\n\n```javascript\nvar r = request.defaults({'proxy':'http://localproxy.com'})\n\nhttp.createServer(function (req, resp) {\n  if (req.url === '/doodle.png') {\n    r.get('http://google.com/doodle.png').pipe(resp)\n  }\n})\n```\nYou can still use intermediate proxies, the requests will still follow HTTP forwards, etc.\n\n## Forms\n\n`request` supports `application/x-www-form-urlencoded` and `multipart/form-data` form uploads. For `multipart/related` refer to the `multipart` API.\n\nUrl encoded forms are simple\n\n```javascript\nrequest.post('http://service.com/upload', {form:{key:'value'}})\n// or\nrequest.post('http://service.com/upload').form({key:'value'})\n```\n\nFor `multipart/form-data` we use the [form-data](https://github.com/felixge/node-form-data) library by [@felixge](https://github.com/felixge). You don't need to worry about piping the form object or setting the headers, `request` will handle that for you.\n\n```javascript\nvar r = request.post('http://service.com/upload')\nvar form = r.form()\nform.append('my_field', 'my_value')\nform.append('my_buffer', new Buffer([1, 2, 3]))\nform.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png'))\nform.append('remote_file', request('http://google.com/doodle.png'))\n```\n\n## OAuth Signing\n\n```javascript\n// Twitter OAuth\nvar qs = require('querystring')\n  , oauth =\n    { callback: 'http://mysite.com/callback/'\n    , consumer_key: CONSUMER_KEY\n    , consumer_secret: CONSUMER_SECRET\n    }\n  , url = 'https://api.twitter.com/oauth/request_token'\n  ;\nrequest.post({url:url, oauth:oauth}, function (e, r, body) {\n  // Assume by some stretch of magic you aquired the verifier\n  var access_token = qs.parse(body)\n    , oauth = \n      { consumer_key: CONSUMER_KEY\n      , consumer_secret: CONSUMER_SECRET\n      , token: access_token.oauth_token\n      , verifier: VERIFIER\n      , token_secret: access_token.oauth_token_secret\n      }\n    , url = 'https://api.twitter.com/oauth/access_token'\n    ;\n  request.post({url:url, oauth:oauth}, function (e, r, body) {\n    var perm_token = qs.parse(body)\n      , oauth = \n        { consumer_key: CONSUMER_KEY\n        , consumer_secret: CONSUMER_SECRET\n        , token: perm_token.oauth_token\n        , token_secret: perm_token.oauth_token_secret\n        }\n      , url = 'https://api.twitter.com/1/users/show.json?'\n      , params = \n        { screen_name: perm_token.screen_name\n        , user_id: perm_token.user_id\n        }\n      ;\n    url += qs.stringify(params)\n    request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {\n      console.log(user)\n    })\n  })\n})\n```\n\n\n\n### request(options, callback)\n\nThe first argument can be either a url or an options object. The only required option is uri, all others are optional.\n\n* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()\n* `qs` - object containing querystring values to be appended to the uri\n* `method` - http method, defaults to GET\n* `headers` - http headers, defaults to {}\n* `body` - entity body for POST and PUT requests. Must be buffer or string.\n* `form` - when passed an object this will set `body` but to a querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header. When passed no option a FormData instance is returned that will be piped to request.\n* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header.  Additionally, parses the response body as json.\n* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.\n* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.\n* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.\n* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.\n* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.\n* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.\n* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.\n* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request\t\n* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.\n* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.\n* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.\n* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)\n* `aws` - object containing aws signing information, should have the properties `key` and `secret` as well as `bucket` unless you're specifying your bucket as part of the path, or you are making a request that doesn't use a bucket (i.e. GET Services)\n\n\nThe callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.\n\n## Convenience methods\n\nThere are also shorthand methods for different HTTP METHODs and some other conveniences.\n\n### request.defaults(options)  \n  \nThis method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.\n\n### request.put\n\nSame as request() but defaults to `method: \"PUT\"`.\n\n```javascript\nrequest.put(url)\n```\n\n### request.post\n\nSame as request() but defaults to `method: \"POST\"`.\n\n```javascript\nrequest.post(url)\n```\n\n### request.head\n\nSame as request() but defaults to `method: \"HEAD\"`.\n\n```javascript\nrequest.head(url)\n```\n\n### request.del\n\nSame as request() but defaults to `method: \"DELETE\"`.\n\n```javascript\nrequest.del(url)\n```\n\n### request.get\n\nAlias to normal request method for uniformity.\n\n```javascript\nrequest.get(url)\n```\n### request.cookie\n\nFunction that creates a new cookie.\n\n```javascript\nrequest.cookie('cookie_string_here')\n```\n### request.jar\n\nFunction that creates a new cookie jar.\n\n```javascript\nrequest.jar()\n```\n\n\n## Examples:\n\n```javascript\n  var request = require('request')\n    , rand = Math.floor(Math.random()*100000000).toString()\n    ;\n  request(\n    { method: 'PUT'\n    , uri: 'http://mikeal.iriscouch.com/testjs/' + rand\n    , multipart: \n      [ { 'content-type': 'application/json'\n        ,  body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})\n        }\n      , { body: 'I am an attachment' }\n      ] \n    }\n  , function (error, response, body) {\n      if(response.statusCode == 201){\n        console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)\n      } else {\n        console.log('error: '+ response.statusCode)\n        console.log(body)\n      }\n    }\n  )\n```\nCookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent).\n\n```javascript\nvar request = request.defaults({jar: false})\nrequest('http://www.google.com', function () {\n  request('http://images.google.com')\n})\n```\n\nIf you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:\n\n```javascript\nvar j = request.jar()\nvar request = request.defaults({jar:j})\nrequest('http://www.google.com', function () {\n  request('http://images.google.com')\n})\n```\nOR\n\n```javascript\nvar j = request.jar()\nvar cookie = request.cookie('your_cookie_here')\nj.add(cookie)\nrequest({url: 'http://www.google.com', jar: j}, function () {\n  request('http://images.google.com')\n})\n```\n",
+  "readmeFilename": "README.md",
+  "_id": "request@2.12.0",
+  "dist": {
+    "shasum": "ff89254ae367bb5b470abbabc89274f5294ee2b0"
+  },
+  "_from": "request@>= 2 && <= 2.14",
+  "_resolved": "https://registry.npmjs.org/request/-/request-2.12.0.tgz"
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/googledoodle.png b/deps/npm/node_modules/node-gyp/node_modules/request/tests/googledoodle.png
new file mode 100644 (file)
index 0000000..f80c9c5
Binary files /dev/null and b/deps/npm/node_modules/node-gyp/node_modules/request/tests/googledoodle.png differ
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/run.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/run.js
new file mode 100644 (file)
index 0000000..538a65c
--- /dev/null
@@ -0,0 +1,45 @@
+var spawn = require('child_process').spawn
+  , exitCode = 0
+  ;
+
+var tests = [
+    'test-body.js'
+  , 'test-cookie.js'
+  , 'test-cookiejar.js'
+  , 'test-defaults.js'
+  , 'test-errors.js'
+  , 'test-form.js'
+  , 'test-follow-all-303.js'
+  , 'test-follow-all.js'
+  , 'test-headers.js'
+  , 'test-httpModule.js'
+  , 'test-https.js'
+  , 'test-https-strict.js'
+  , 'test-oauth.js'
+  , 'test-params.js'
+  , 'test-pipes.js'
+  , 'test-pool.js'
+  , 'test-protocol-changing-redirect.js'
+  , 'test-proxy.js'
+  , 'test-piped-redirect.js'
+  , 'test-qs.js'
+  , 'test-redirect.js'
+  , 'test-timeout.js'
+  , 'test-toJSON.js'
+  , 'test-tunnel.js'
+]
+
+var next = function () {
+  if (tests.length === 0) process.exit(exitCode);
+
+  var file = tests.shift()
+  console.log(file)
+  var proc = spawn('node', [ 'tests/' + file ])
+  proc.stdout.pipe(process.stdout)
+  proc.stderr.pipe(process.stderr)
+  proc.on('exit', function (code) {
+       exitCode += code || 0
+       next()
+  })
+}
+next()
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/server.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/server.js
new file mode 100644 (file)
index 0000000..b6eacba
--- /dev/null
@@ -0,0 +1,90 @@
+var fs = require('fs')
+  , http = require('http')
+  , path = require('path')
+  , https = require('https')
+  , events = require('events')
+  , stream = require('stream')
+  , assert = require('assert')
+  ;
+
+exports.createServer =  function (port) {
+  port = port || 6767
+  var s = http.createServer(function (req, resp) {
+    s.emit(req.url, req, resp);
+  })
+  s.port = port
+  s.url = 'http://localhost:'+port
+  return s;
+}
+
+exports.createSSLServer = function(port, opts) {
+  port = port || 16767
+
+  var options = { 'key' : path.join(__dirname, 'ssl', 'test.key')
+                , 'cert': path.join(__dirname, 'ssl', 'test.crt')
+                }
+  if (opts) {
+    for (var i in opts) options[i] = opts[i]
+  }
+
+  for (var i in options) {
+    options[i] = fs.readFileSync(options[i])
+  }
+
+  var s = https.createServer(options, function (req, resp) {
+    s.emit(req.url, req, resp);
+  })
+  s.port = port
+  s.url = 'https://localhost:'+port
+  return s;
+}
+
+exports.createPostStream = function (text) {
+  var postStream = new stream.Stream();
+  postStream.writeable = true;
+  postStream.readable = true;
+  setTimeout(function () {postStream.emit('data', new Buffer(text)); postStream.emit('end')}, 0);
+  return postStream;
+}
+exports.createPostValidator = function (text, reqContentType) {
+  var l = function (req, resp) {
+    var r = '';
+    req.on('data', function (chunk) {r += chunk})
+    req.on('end', function () {
+      if (req.headers['content-type'] && req.headers['content-type'].indexOf('boundary=') >= 0) {
+        var boundary = req.headers['content-type'].split('boundary=')[1];
+        text = text.replace(/__BOUNDARY__/g, boundary);
+      }
+      if (r !== text) console.log(r, text);
+      assert.equal(r, text)
+      if (reqContentType) {
+        assert.ok(req.headers['content-type'])
+        assert.ok(~req.headers['content-type'].indexOf(reqContentType))
+      }
+      resp.writeHead(200, {'content-type':'text/plain'})
+      resp.write('OK')
+      resp.end()
+    })
+  }
+  return l;
+}
+exports.createGetResponse = function (text, contentType) {
+  var l = function (req, resp) {
+    contentType = contentType || 'text/plain'
+    resp.writeHead(200, {'content-type':contentType})
+    resp.write(text)
+    resp.end()
+  }
+  return l;
+}
+exports.createChunkResponse = function (chunks, contentType) {
+  var l = function (req, resp) {
+    contentType = contentType || 'text/plain'
+    resp.writeHead(200, {'content-type':contentType})
+    chunks.forEach(function (chunk) {
+      resp.write(chunk)
+    })
+    resp.end()
+  }
+  return l;
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/squid.conf b/deps/npm/node_modules/node-gyp/node_modules/request/tests/squid.conf
new file mode 100644 (file)
index 0000000..0d4a3b6
--- /dev/null
@@ -0,0 +1,77 @@
+#
+# Recommended minimum configuration:
+#
+acl manager proto cache_object
+acl localhost src 127.0.0.1/32 ::1
+acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
+
+# Example rule allowing access from your local networks.
+# Adapt to list your (internal) IP networks from where browsing
+# should be allowed
+acl localnet src 10.0.0.0/8    # RFC1918 possible internal network
+acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
+acl localnet src 192.168.0.0/16        # RFC1918 possible internal network
+acl localnet src fc00::/7       # RFC 4193 local private network range
+acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines
+
+acl SSL_ports port 443
+acl Safe_ports port 80         # http
+acl Safe_ports port 21         # ftp
+acl Safe_ports port 443                # https
+acl Safe_ports port 70         # gopher
+acl Safe_ports port 210                # wais
+acl Safe_ports port 1025-65535 # unregistered ports
+acl Safe_ports port 280                # http-mgmt
+acl Safe_ports port 488                # gss-http
+acl Safe_ports port 591                # filemaker
+acl Safe_ports port 777                # multiling http
+acl CONNECT method CONNECT
+
+#
+# Recommended minimum Access Permission configuration:
+#
+# Only allow cachemgr access from localhost
+http_access allow manager localhost
+http_access deny manager
+
+# Deny requests to certain unsafe ports
+http_access deny !Safe_ports
+
+# Deny CONNECT to other than secure SSL ports
+#http_access deny CONNECT !SSL_ports
+
+# We strongly recommend the following be uncommented to protect innocent
+# web applications running on the proxy server who think the only
+# one who can access services on "localhost" is a local user
+#http_access deny to_localhost
+
+#
+# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
+#
+
+# Example rule allowing access from your local networks.
+# Adapt localnet in the ACL section to list your (internal) IP networks
+# from where browsing should be allowed
+http_access allow localnet
+http_access allow localhost
+
+# And finally deny all other access to this proxy
+http_access deny all
+
+# Squid normally listens to port 3128
+http_port 3128
+
+# We recommend you to use at least the following line.
+hierarchy_stoplist cgi-bin ?
+
+# Uncomment and adjust the following to add a disk cache directory.
+#cache_dir ufs /usr/local/var/cache 100 16 256
+
+# Leave coredumps in the first cache dir
+coredump_dir /usr/local/var/cache
+
+# Add any of your own refresh_pattern entries above these.
+refresh_pattern ^ftp:          1440    20%     10080
+refresh_pattern ^gopher:       1440    0%      1440
+refresh_pattern -i (/cgi-bin/|\?) 0    0%      0
+refresh_pattern .              0       20%     4320
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.cnf b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.cnf
new file mode 100644 (file)
index 0000000..425a889
--- /dev/null
@@ -0,0 +1,20 @@
+[ req ]
+default_bits           = 1024
+days                   = 3650
+distinguished_name     = req_distinguished_name
+attributes             = req_attributes
+prompt                 = no
+output_password        = password
+
+[ req_distinguished_name ]
+C                      = US
+ST                     = CA
+L                      = Oakland
+O                      = request
+OU                     = request Certificate Authority
+CN                     = requestCA
+emailAddress           = mikeal@mikealrogers.com
+
+[ req_attributes ]
+challengePassword              = password challenge
+
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.crl b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.crl
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.crt b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.crt
new file mode 100644 (file)
index 0000000..b4524e4
--- /dev/null
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICvTCCAiYCCQDn+P/MSbDsWjANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1
+ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG
+A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n
+ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGiMQswCQYD
+VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT
+B3JlcXVlc3QxJjAkBgNVBAsTHXJlcXVlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
+MRIwEAYDVQQDEwlyZXF1ZXN0Q0ExJjAkBgkqhkiG9w0BCQEWF21pa2VhbEBtaWtl
+YWxyb2dlcnMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7t9pQUAK4
+5XJYTI6NrF0n3G2HZsfN+rPYSVzzL8SuVyb1tHXos+vbPm3NKI4E8X1yVAXU8CjJ
+5SqXnp4DAypAhaseho81cbhk7LXUhFz78OvAa+OD+xTAEAnNQ8tGUr4VGyplEjfD
+xsBVuqV2j8GPNTftr+drOCFlqfAgMrBn4wIDAQABMA0GCSqGSIb3DQEBBQUAA4GB
+ADVdTlVAL45R+PACNS7Gs4o81CwSclukBu4FJbxrkd4xGQmurgfRrYYKjtqiopQm
+D7ysRamS3HMN9/VKq2T7r3z1PMHPAy7zM4uoXbbaTKwlnX4j/8pGPn8Ca3qHXYlo
+88L/OOPc6Di7i7qckS3HFbXQCTiULtxWmy97oEuTwrAj
+-----END CERTIFICATE-----
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.csr b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.csr
new file mode 100644 (file)
index 0000000..e48c56e
--- /dev/null
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICBjCCAW8CAQAwgaIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE
+BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEmMCQGA1UECxMdcmVxdWVzdCBD
+ZXJ0aWZpY2F0ZSBBdXRob3JpdHkxEjAQBgNVBAMTCXJlcXVlc3RDQTEmMCQGCSqG
+SIb3DQEJARYXbWlrZWFsQG1pa2VhbHJvZ2Vycy5jb20wgZ8wDQYJKoZIhvcNAQEB
+BQADgY0AMIGJAoGBALu32lBQArjlclhMjo2sXSfcbYdmx836s9hJXPMvxK5XJvW0
+deiz69s+bc0ojgTxfXJUBdTwKMnlKpeengMDKkCFqx6GjzVxuGTstdSEXPvw68Br
+44P7FMAQCc1Dy0ZSvhUbKmUSN8PGwFW6pXaPwY81N+2v52s4IWWp8CAysGfjAgMB
+AAGgIzAhBgkqhkiG9w0BCQcxFBMScGFzc3dvcmQgY2hhbGxlbmdlMA0GCSqGSIb3
+DQEBBQUAA4GBAGJO7grHeVHXetjHEK8urIxdnvfB2qeZeObz4GPKIkqUurjr0rfj
+bA3EK1kDMR5aeQWR8RunixdM16Q6Ry0lEdLVWkdSwRN9dmirIHT9cypqnD/FYOia
+SdezZ0lUzXgmJIwRYRwB1KSMMocIf52ll/xC2bEGg7/ZAEuAyAgcZV3X
+-----END CERTIFICATE REQUEST-----
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.key b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.key
new file mode 100644 (file)
index 0000000..a53e7f7
--- /dev/null
@@ -0,0 +1,18 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,C8B5887048377F02
+
+nyD5ZH0Wup2uWsDvurq5mKDaDrf8lvNn9w0SH/ZkVnfR1/bkwqrFriqJWvZNUG+q
+nS0iBYczsWLJnbub9a1zLOTENWUKVD5uqbC3aGHhnoUTNSa27DONgP8gHOn6JgR+
+GAKo01HCSTiVT4LjkwN337QKHnMP2fTzg+IoC/CigvMcq09hRLwU1/guq0GJKGwH
+gTxYNuYmQC4Tjh8vdS4liF+Ve/P3qPR2CehZrIOkDT8PHJBGQJRo4xGUIB7Tpk38
+VCk+UZ0JCS2coY8VkY/9tqFJp/ZnnQQVmaNbdRqg7ECKL+bXnNo7yjzmazPZmPe3
+/ShbE0+CTt7LrjCaQAxWbeDzqfo1lQfgN1LulTm8MCXpQaJpv7v1VhIhQ7afjMYb
+4thW/ypHPiYS2YJCAkAVlua9Oxzzh1qJoh8Df19iHtpd79Q77X/qf+1JvITlMu0U
+gi7yEatmQcmYNws1mtTC1q2DXrO90c+NZ0LK/Alse6NRL/xiUdjug2iHeTf/idOR
+Gg/5dSZbnnlj1E5zjSMDkzg6EHAFmHV4jYGSAFLEQgp4V3ZhMVoWZrvvSHgKV/Qh
+FqrAK4INr1G2+/QTd09AIRzfy3/j6yD4A9iNaOsEf9Ua7Qh6RcALRCAZTWR5QtEf
+dX+iSNJ4E85qXs0PqwkMDkoaxIJ+tmIRJY7y8oeylV8cfGAi8Soubt/i3SlR8IHC
+uDMas/2OnwafK3N7ODeE1i7r7wkzQkSHaEz0TrF8XRnP25jAICCSLiMdAAjKfxVb
+EvzsFSuAy3Jt6bU3hSLY9o4YVYKE+68ITMv9yNjvTsEiW+T+IbN34w==
+-----END RSA PRIVATE KEY-----
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.srl b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/ca.srl
new file mode 100644 (file)
index 0000000..17128db
--- /dev/null
@@ -0,0 +1 @@
+ADF62016AA40C9C3
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.cnf b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.cnf
new file mode 100644 (file)
index 0000000..cd1fd1e
--- /dev/null
@@ -0,0 +1,19 @@
+[ req ]
+default_bits           = 1024
+days                   = 3650
+distinguished_name     = req_distinguished_name
+attributes             = req_attributes
+prompt                 = no
+
+[ req_distinguished_name ]
+C                      = US
+ST                     = CA
+L                      = Oakland
+O                      = request
+OU                     = testing
+CN                     = testing.request.mikealrogers.com
+emailAddress           = mikeal@mikealrogers.com
+
+[ req_attributes ]
+challengePassword              = password challenge
+
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.crt b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.crt
new file mode 100644 (file)
index 0000000..efe96ce
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICejCCAeMCCQCt9iAWqkDJwzANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1
+ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG
+A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n
+ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGjMQswCQYD
+VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT
+B3JlcXVlc3QxEDAOBgNVBAsTB3Rlc3RpbmcxKTAnBgNVBAMTIHRlc3RpbmcucmVx
+dWVzdC5taWtlYWxyb2dlcnMuY29tMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlr
+ZWFscm9nZXJzLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDgVl0jMumvOpmM
+20W5v9yhGgZj8hPhEQF/N7yCBVBn/rWGYm70IHC8T/pR5c0LkWc5gdnCJEvKWQjh
+DBKxZD8FAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEABShRkNgFbgs4vUWW9R9deNJj
+7HJoiTmvkmoOC7QzcYkjdgHbOxsSq3rBnwxsVjY9PAtPwBn0GRspOeG7KzKRgySB
+kb22LyrCFKbEOfKO/+CJc80ioK9zEPVjGsFMyAB+ftYRqM+s/4cQlTg/m89l01wC
+yapjN3RxZbInGhWR+jA=
+-----END CERTIFICATE-----
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.csr b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.csr
new file mode 100644 (file)
index 0000000..a8e7595
--- /dev/null
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBgjCCASwCAQAwgaMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE
+BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEQMA4GA1UECxMHdGVzdGluZzEp
+MCcGA1UEAxMgdGVzdGluZy5yZXF1ZXN0Lm1pa2VhbHJvZ2Vycy5jb20xJjAkBgkq
+hkiG9w0BCQEWF21pa2VhbEBtaWtlYWxyb2dlcnMuY29tMFwwDQYJKoZIhvcNAQEB
+BQADSwAwSAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg
+cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAaAjMCEGCSqGSIb3DQEJBzEU
+ExJwYXNzd29yZCBjaGFsbGVuZ2UwDQYJKoZIhvcNAQEFBQADQQBD3E5WekQzCEJw
+7yOcqvtPYIxGaX8gRKkYfLPoj3pm3GF5SGqtJKhylKfi89szHXgktnQgzff9FN+A
+HidVJ/3u
+-----END CERTIFICATE REQUEST-----
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.js
new file mode 100644 (file)
index 0000000..05e21c1
--- /dev/null
@@ -0,0 +1,28 @@
+var fs = require("fs")
+var https = require("https")
+var options = { key: fs.readFileSync("./server.key")
+              , cert: fs.readFileSync("./server.crt") }
+
+var server = https.createServer(options, function (req, res) {
+  res.writeHead(200)
+  res.end()
+  server.close()
+})
+server.listen(1337)
+
+var ca = fs.readFileSync("./ca.crt")
+var agent = new https.Agent({ host: "localhost", port: 1337, ca: ca })
+
+https.request({ host: "localhost"
+              , method: "HEAD"
+              , port: 1337
+              , headers: { host: "testing.request.mikealrogers.com" }
+              , agent: agent
+              , ca: [ ca ]
+              , path: "/" }, function (res) {
+  if (res.client.authorized) {
+    console.log("node test: OK")
+  } else {
+    throw new Error(res.client.authorizationError)
+  }
+}).end()
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.key b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/ca/server.key
new file mode 100644 (file)
index 0000000..72d8698
--- /dev/null
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg
+cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAQJAK+r8ZM2sze8s7FRo/ApB
+iRBtO9fCaIdJwbwJnXKo4RKwZDt1l2mm+fzZ+/QaQNjY1oTROkIIXmnwRvZWfYlW
+gQIhAPKYsG+YSBN9o8Sdp1DMyZ/rUifKX3OE6q9tINkgajDVAiEA7Ltqh01+cnt0
+JEnud/8HHcuehUBLMofeg0G+gCnSbXECIQCqDvkXsWNNLnS/3lgsnvH0Baz4sbeJ
+rjIpuVEeg8eM5QIgbu0+9JmOV6ybdmmiMV4yAncoF35R/iKGVHDZCAsQzDECIQDZ
+0jGz22tlo5YMcYSqrdD3U4sds1pwiAaWFRbCunoUJw==
+-----END RSA PRIVATE KEY-----
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/npm-ca.crt b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/npm-ca.crt
new file mode 100644 (file)
index 0000000..fde2fe9
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIIChzCCAfACCQDauvz/KHp8ejANBgkqhkiG9w0BAQUFADCBhzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMQwwCgYDVQQKEwNucG0x
+IjAgBgNVBAsTGW5wbSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxDjAMBgNVBAMTBW5w
+bUNBMRcwFQYJKoZIhvcNAQkBFghpQGl6cy5tZTAeFw0xMTA5MDUwMTQ3MTdaFw0y
+MTA5MDIwMTQ3MTdaMIGHMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNV
+BAcTB09ha2xhbmQxDDAKBgNVBAoTA25wbTEiMCAGA1UECxMZbnBtIENlcnRpZmlj
+YXRlIEF1dGhvcml0eTEOMAwGA1UEAxMFbnBtQ0ExFzAVBgkqhkiG9w0BCQEWCGlA
+aXpzLm1lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLI4tIqPpRW+ACw9GE
+OgBlJZwK5f8nnKCLK629Pv5yJpQKs3DENExAyOgDcyaF0HD0zk8zTp+ZsLaNdKOz
+Gn2U181KGprGKAXP6DU6ByOJDWmTlY6+Ad1laYT0m64fERSpHw/hjD3D+iX4aMOl
+y0HdbT5m1ZGh6SJz3ZqxavhHLQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAC4ySDbC
+l7W1WpLmtLGEQ/yuMLUf6Jy/vr+CRp4h+UzL+IQpCv8FfxsYE7dhf/bmWTEupBkv
+yNL18lipt2jSvR3v6oAHAReotvdjqhxddpe5Holns6EQd1/xEZ7sB1YhQKJtvUrl
+ZNufy1Jf1r0ldEGeA+0ISck7s+xSh9rQD2Op
+-----END CERTIFICATE-----
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/test.crt b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/test.crt
new file mode 100644 (file)
index 0000000..b357f86
--- /dev/null
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICQzCCAawCCQCO/XWtRFck1jANBgkqhkiG9w0BAQUFADBmMQswCQYDVQQGEwJU
+SDEQMA4GA1UECBMHQmFuZ2tvazEOMAwGA1UEBxMFU2lsb20xGzAZBgNVBAoTElRo
+ZSBSZXF1ZXN0IE1vZHVsZTEYMBYGA1UEAxMPcmVxdWVzdC5leGFtcGxlMB4XDTEx
+MTIwMzAyMjkyM1oXDTIxMTEzMDAyMjkyM1owZjELMAkGA1UEBhMCVEgxEDAOBgNV
+BAgTB0Jhbmdrb2sxDjAMBgNVBAcTBVNpbG9tMRswGQYDVQQKExJUaGUgUmVxdWVz
+dCBNb2R1bGUxGDAWBgNVBAMTD3JlcXVlc3QuZXhhbXBsZTCBnzANBgkqhkiG9w0B
+AQEFAAOBjQAwgYkCgYEAwmctddZqlA48+NXs0yOy92DijcQV1jf87zMiYAIlNUto
+wghVbTWgJU5r0pdKrD16AptnWJTzKanhItEX8XCCPgsNkq1afgTtJP7rNkwu3xcj
+eIMkhJg/ay4ZnkbnhYdsii5VTU5prix6AqWRAhbkBgoA+iVyHyof8wvZyKBoFTMC
+AwEAATANBgkqhkiG9w0BAQUFAAOBgQB6BybMJbpeiABgihDfEVBcAjDoQ8gUMgwV
+l4NulugfKTDmArqnR9aPd4ET5jX5dkMP4bwCHYsvrcYDeWEQy7x5WWuylOdKhua4
+L4cEi2uDCjqEErIG3cc1MCOk6Cl6Ld6tkIzQSf953qfdEACRytOeUqLNQcrXrqeE
+c7U8F6MWLQ==
+-----END CERTIFICATE-----
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/test.key b/deps/npm/node_modules/node-gyp/node_modules/request/tests/ssl/test.key
new file mode 100644 (file)
index 0000000..b85810d
--- /dev/null
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDCZy111mqUDjz41ezTI7L3YOKNxBXWN/zvMyJgAiU1S2jCCFVt
+NaAlTmvSl0qsPXoCm2dYlPMpqeEi0RfxcII+Cw2SrVp+BO0k/us2TC7fFyN4gySE
+mD9rLhmeRueFh2yKLlVNTmmuLHoCpZECFuQGCgD6JXIfKh/zC9nIoGgVMwIDAQAB
+AoGBALXFwfUf8vHTSmGlrdZS2AGFPvEtuvldyoxi9K5u8xmdFCvxnOcLsF2RsTHt
+Mu5QYWhUpNJoG+IGLTPf7RJdj/kNtEs7xXqWy4jR36kt5z5MJzqiK+QIgiO9UFWZ
+fjUb6oeDnTIJA9YFBdYi97MDuL89iU/UK3LkJN3hd4rciSbpAkEA+MCkowF5kSFb
+rkOTBYBXZfiAG78itDXN6DXmqb9XYY+YBh3BiQM28oxCeQYyFy6pk/nstnd4TXk6
+V/ryA2g5NwJBAMgRKTY9KvxJWbESeMEFe2iBIV0c26/72Amgi7ZKUCLukLfD4tLF
++WSZdmTbbqI1079YtwaiOVfiLm45Q/3B0eUCQAaQ/0eWSGE+Yi8tdXoVszjr4GXb
+G81qBi91DMu6U1It+jNfIba+MPsiHLcZJMVb4/oWBNukN7bD1nhwFWdlnu0CQQCf
+Is9WHkdvz2RxbZDxb8verz/7kXXJQJhx5+rZf7jIYFxqX3yvTNv3wf2jcctJaWlZ
+fVZwB193YSivcgt778xlAkEAprYUz3jczjF5r2hrgbizPzPDR94tM5BTO3ki2v3w
+kbf+j2g7FNAx6kZiVN8XwfLc8xEeUGiPKwtq3ddPDFh17w==
+-----END RSA PRIVATE KEY-----
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-body.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-body.js
new file mode 100644 (file)
index 0000000..a624397
--- /dev/null
@@ -0,0 +1,117 @@
+var server = require('./server')
+  , events = require('events')
+  , stream = require('stream')
+  , assert = require('assert')
+  , request = require('../main.js')
+  ;
+
+var s = server.createServer();
+
+var tests =
+  { testGet :
+    { resp : server.createGetResponse("TESTING!")
+    , expectBody: "TESTING!"
+    }
+  , testGetChunkBreak :
+    { resp : server.createChunkResponse(
+      [ new Buffer([239])
+      , new Buffer([163])
+      , new Buffer([191])
+      , new Buffer([206])
+      , new Buffer([169])
+      , new Buffer([226])
+      , new Buffer([152])
+      , new Buffer([131])
+      ])
+    , expectBody: "Ω☃"
+    }
+  , testGetBuffer :
+    { resp : server.createGetResponse(new Buffer("TESTING!"))
+    , encoding: null
+    , expectBody: new Buffer("TESTING!")
+    }
+  , testGetEncoding :
+    { resp : server.createGetResponse(new Buffer('efa3bfcea9e29883', 'hex'))
+    , encoding: 'hex'
+    , expectBody: "efa3bfcea9e29883"
+    }
+  , testGetJSON :
+     { resp : server.createGetResponse('{"test":true}', 'application/json')
+     , json : true
+     , expectBody: {"test":true}
+     }
+  , testPutString :
+    { resp : server.createPostValidator("PUTTINGDATA")
+    , method : "PUT"
+    , body : "PUTTINGDATA"
+    }
+  , testPutBuffer :
+    { resp : server.createPostValidator("PUTTINGDATA")
+    , method : "PUT"
+    , body : new Buffer("PUTTINGDATA")
+    }
+  , testPutJSON :
+    { resp : server.createPostValidator(JSON.stringify({foo: 'bar'}))
+    , method: "PUT"
+    , json: {foo: 'bar'}
+    }
+  , testPutMultipart :
+    { resp: server.createPostValidator(
+        '--__BOUNDARY__\r\n' +
+        'content-type: text/html\r\n' +
+        '\r\n' +
+        '<html><body>Oh hi.</body></html>' +
+        '\r\n--__BOUNDARY__\r\n\r\n' +
+        'Oh hi.' +
+        '\r\n--__BOUNDARY__--'
+        )
+    , method: "PUT"
+    , multipart:
+      [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'}
+      , {'body': 'Oh hi.'}
+      ]
+    }
+  , testPutMultipartPreambleCRLF :
+    { resp: server.createPostValidator(
+        '\r\n--__BOUNDARY__\r\n' +
+        'content-type: text/html\r\n' +
+        '\r\n' +
+        '<html><body>Oh hi.</body></html>' +
+        '\r\n--__BOUNDARY__\r\n\r\n' +
+        'Oh hi.' +
+        '\r\n--__BOUNDARY__--'
+        )
+    , method: "PUT"
+    , preambleCRLF: true
+    , multipart:
+      [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'}
+      , {'body': 'Oh hi.'}
+      ]
+    }
+  }
+
+s.listen(s.port, function () {
+
+  var counter = 0
+
+  for (i in tests) {
+    (function () {
+      var test = tests[i]
+      s.on('/'+i, test.resp)
+      test.uri = s.url + '/' + i
+      request(test, function (err, resp, body) {
+        if (err) throw err
+        if (test.expectBody) {
+          assert.deepEqual(test.expectBody, body)
+        }
+        counter = counter - 1;
+        if (counter === 0) {
+          console.log(Object.keys(tests).length+" tests passed.")
+          s.close()
+        }
+      })
+      counter++
+    })()
+  }
+})
+
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-cookie.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-cookie.js
new file mode 100644 (file)
index 0000000..6c6a7a7
--- /dev/null
@@ -0,0 +1,29 @@
+var Cookie = require('../vendor/cookie')
+  , assert = require('assert');
+
+var str = 'Sid="s543qactge.wKE61E01Bs%2BKhzmxrwrnug="; Path=/; httpOnly; Expires=Sat, 04 Dec 2010 23:27:28 GMT';
+var cookie = new Cookie(str);
+
+// test .toString()
+assert.equal(cookie.toString(), str);
+
+// test .path
+assert.equal(cookie.path, '/');
+
+// test .httpOnly
+assert.equal(cookie.httpOnly, true);
+
+// test .name
+assert.equal(cookie.name, 'Sid');
+
+// test .value
+assert.equal(cookie.value, '"s543qactge.wKE61E01Bs%2BKhzmxrwrnug="');
+
+// test .expires
+assert.equal(cookie.expires instanceof Date, true);
+
+// test .path default
+var cookie = new Cookie('foo=bar', { url: 'http://foo.com/bar' });
+assert.equal(cookie.path, '/bar');
+
+console.log('All tests passed');
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-cookiejar.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-cookiejar.js
new file mode 100644 (file)
index 0000000..76fcd71
--- /dev/null
@@ -0,0 +1,90 @@
+var Cookie = require('../vendor/cookie')
+  , Jar = require('../vendor/cookie/jar')
+  , assert = require('assert');
+
+function expires(ms) {
+  return new Date(Date.now() + ms).toUTCString();
+}
+
+// test .get() expiration
+(function() {
+  var jar = new Jar;
+  var cookie = new Cookie('sid=1234; path=/; expires=' + expires(1000));
+  jar.add(cookie);
+  setTimeout(function(){
+    var cookies = jar.get({ url: 'http://foo.com/foo' });
+    assert.equal(cookies.length, 1);
+    assert.equal(cookies[0], cookie);
+    setTimeout(function(){
+      var cookies = jar.get({ url: 'http://foo.com/foo' });
+      assert.equal(cookies.length, 0);
+    }, 1000);
+  }, 5);
+})();
+
+// test .get() path support
+(function() {
+  var jar = new Jar;
+  var a = new Cookie('sid=1234; path=/');
+  var b = new Cookie('sid=1111; path=/foo/bar');
+  var c = new Cookie('sid=2222; path=/');
+  jar.add(a);
+  jar.add(b);
+  jar.add(c);
+
+  // should remove the duplicates
+  assert.equal(jar.cookies.length, 2);
+
+  // same name, same path, latter prevails
+  var cookies = jar.get({ url: 'http://foo.com/' });
+  assert.equal(cookies.length, 1);
+  assert.equal(cookies[0], c);
+
+  // same name, diff path, path specifity prevails, latter prevails
+  var cookies = jar.get({ url: 'http://foo.com/foo/bar' });
+  assert.equal(cookies.length, 1);
+  assert.equal(cookies[0], b);
+
+  var jar = new Jar;
+  var a = new Cookie('sid=1111; path=/foo/bar');
+  var b = new Cookie('sid=1234; path=/');
+  jar.add(a);
+  jar.add(b);
+
+  var cookies = jar.get({ url: 'http://foo.com/foo/bar' });
+  assert.equal(cookies.length, 1);
+  assert.equal(cookies[0], a);
+
+  var cookies = jar.get({ url: 'http://foo.com/' });
+  assert.equal(cookies.length, 1);
+  assert.equal(cookies[0], b);
+
+  var jar = new Jar;
+  var a = new Cookie('sid=1111; path=/foo/bar');
+  var b = new Cookie('sid=3333; path=/foo/bar');
+  var c = new Cookie('pid=3333; path=/foo/bar');
+  var d = new Cookie('sid=2222; path=/foo/');
+  var e = new Cookie('sid=1234; path=/');
+  jar.add(a);
+  jar.add(b);
+  jar.add(c);
+  jar.add(d);
+  jar.add(e);
+
+  var cookies = jar.get({ url: 'http://foo.com/foo/bar' });
+  assert.equal(cookies.length, 2);
+  assert.equal(cookies[0], b);
+  assert.equal(cookies[1], c);
+
+  var cookies = jar.get({ url: 'http://foo.com/foo/' });
+  assert.equal(cookies.length, 1);
+  assert.equal(cookies[0], d);
+
+  var cookies = jar.get({ url: 'http://foo.com/' });
+  assert.equal(cookies.length, 1);
+  assert.equal(cookies[0], e);
+})();
+
+setTimeout(function() {
+  console.log('All tests passed');
+}, 1200);
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-defaults.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-defaults.js
new file mode 100644 (file)
index 0000000..ba09418
--- /dev/null
@@ -0,0 +1,114 @@
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+  ;
+
+var s = server.createServer();
+
+s.listen(s.port, function () {
+  var counter = 0;
+  s.on('/get', function (req, resp) {
+    assert.equal(req.headers.foo, 'bar');
+    assert.equal(req.method, 'GET')
+    resp.writeHead(200, {'Content-Type': 'text/plain'});
+    resp.end('TESTING!');
+  });
+
+  // test get(string, function)
+  request.defaults({headers:{foo:"bar"}})(s.url + '/get', function (e, r, b){
+    if (e) throw e;
+    assert.deepEqual("TESTING!", b);
+    counter += 1;
+  });
+
+  s.on('/post', function (req, resp) {
+    assert.equal(req.headers.foo, 'bar');
+    assert.equal(req.headers['content-type'], null);
+    assert.equal(req.method, 'POST')
+    resp.writeHead(200, {'Content-Type': 'application/json'});
+    resp.end(JSON.stringify({foo:'bar'}));
+  });
+
+  // test post(string, object, function)
+  request.defaults({headers:{foo:"bar"}}).post(s.url + '/post', {json: true}, function (e, r, b){
+    if (e) throw e;
+    assert.deepEqual('bar', b.foo);
+    counter += 1;
+  });
+
+  s.on('/post-body', function (req, resp) {
+    assert.equal(req.headers.foo, 'bar');
+    assert.equal(req.headers['content-type'], 'application/json');
+    assert.equal(req.method, 'POST')
+    resp.writeHead(200, {'Content-Type': 'application/json'});
+    resp.end(JSON.stringify({foo:'bar'}));
+  });
+
+  // test post(string, object, function) with body
+  request.defaults({headers:{foo:"bar"}}).post(s.url + '/post-body', {json: true, body:{bar:"baz"}}, function (e, r, b){
+    if (e) throw e;
+    assert.deepEqual('bar', b.foo);
+    counter += 1;
+  });
+
+  s.on('/del', function (req, resp) {
+    assert.equal(req.headers.foo, 'bar');
+    assert.equal(req.method, 'DELETE')
+    resp.writeHead(200, {'Content-Type': 'application/json'});
+    resp.end(JSON.stringify({foo:'bar'}));
+  });
+
+  // test .del(string, function)
+  request.defaults({headers:{foo:"bar"}, json:true}).del(s.url + '/del', function (e, r, b){
+    if (e) throw e;
+    assert.deepEqual('bar', b.foo);
+    counter += 1;
+  });
+
+  s.on('/head', function (req, resp) {
+    assert.equal(req.headers.foo, 'bar');
+    assert.equal(req.method, 'HEAD')
+    resp.writeHead(200, {'Content-Type': 'text/plain'});
+    resp.end();
+  });
+
+  // test head.(object, function)
+  request.defaults({headers:{foo:"bar"}}).head({uri: s.url + '/head'}, function (e, r, b){
+    if (e) throw e;
+    counter += 1;
+  });
+
+  s.on('/get_custom', function(req, resp) {
+    assert.equal(req.headers.foo, 'bar');
+    assert.equal(req.headers.x, 'y');
+    resp.writeHead(200, {'Content-Type': 'text/plain'});
+    resp.end();
+  });
+
+  // test custom request handler function
+  var defaultRequest = request.defaults({
+    headers:{foo:"bar"}
+    , body: 'TESTING!'
+  }, function(uri, options, callback) {
+    var params = request.initParams(uri, options, callback);
+    options = params.options;
+    options.headers.x = 'y';
+
+    return request(params.uri, params.options, params.callback);
+  });
+
+  var msg = 'defaults test failed. head request should throw earlier';
+  assert.throws(function() {
+    defaultRequest.head(s.url + '/get_custom', function(e, r, b) {
+      throw new Error(msg);
+    });
+    counter+=1;
+  }, msg);
+
+  defaultRequest.get(s.url + '/get_custom', function(e, r, b) {
+    if(e) throw e;
+    counter += 1;
+    console.log(counter.toString() + " tests passed.");
+    s.close();
+  });
+})
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-errors.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-errors.js
new file mode 100644 (file)
index 0000000..1986a59
--- /dev/null
@@ -0,0 +1,37 @@
+var server = require('./server')
+  , events = require('events')
+  , assert = require('assert')
+  , request = require('../main.js')
+  ;
+
+var local = 'http://localhost:8888/asdf'
+
+try {
+  request({uri:local, body:{}})
+  assert.fail("Should have throw") 
+} catch(e) {
+  assert.equal(e.message, 'Argument error, options.body.')
+}
+
+try {
+  request({uri:local, multipart: 'foo'})
+  assert.fail("Should have throw")
+} catch(e) {
+  assert.equal(e.message, 'Argument error, options.multipart.')
+}
+
+try {
+  request({uri:local, multipart: [{}]})
+  assert.fail("Should have throw")
+} catch(e) {
+  assert.equal(e.message, 'Body attribute missing in multipart.')
+}
+
+try {
+  request(local, {multipart: [{}]})
+  assert.fail("Should have throw")
+} catch(e) {
+  assert.equal(e.message, 'Body attribute missing in multipart.')
+}
+
+console.log("All tests passed.")
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-follow-all-303.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-follow-all-303.js
new file mode 100644 (file)
index 0000000..3f2162d
--- /dev/null
@@ -0,0 +1,30 @@
+var request = require('../main');
+var http = require('http');
+var requests = 0;
+var assert = require('assert');
+
+var server = http.createServer(function (req, res) {
+  console.error(req.method, req.url);
+  requests ++;
+
+  if (req.method === 'POST') {
+    console.error('send 303');
+    res.setHeader('location', req.url);
+    res.statusCode = 303;
+    res.end('try again, i guess\n');
+  } else {
+    console.error('send 200')
+    res.end('ok: ' + requests);
+  }
+});
+server.listen(6767);
+
+request.post({ url: 'http://localhost:6767/foo',
+               followAllRedirects: true,
+               form: { foo: 'bar' } }, function (er, req, body) {
+  if (er) throw er;
+  assert.equal(body, 'ok: 2');
+  assert.equal(requests, 2);
+  console.error('ok - ' + process.version);
+  server.close();
+});
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-follow-all.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-follow-all.js
new file mode 100644 (file)
index 0000000..b78745b
--- /dev/null
@@ -0,0 +1,35 @@
+var request = require('../main');
+var http = require('http');
+var requests = 0;
+var assert = require('assert');
+
+var server = http.createServer(function (req, res) {
+  requests ++;
+
+  // redirect everything 3 times, no matter what.
+  var c = req.headers.cookie;
+
+  if (!c) c = 0;
+  else c = +c.split('=')[1] || 0;
+
+  if (c > 3) {
+    res.end('ok: '+requests);
+    return;
+  }
+
+  res.setHeader('set-cookie', 'c=' + (c + 1));
+  res.setHeader('location', req.url);
+  res.statusCode = 302;
+  res.end('try again, i guess\n');
+});
+server.listen(6767);
+
+request.post({ url: 'http://localhost:6767/foo',
+               followAllRedirects: true,
+               form: { foo: 'bar' } }, function (er, req, body) {
+  if (er) throw er;
+  assert.equal(body, 'ok: 5');
+  assert.equal(requests, 5);
+  console.error('ok - ' + process.version);
+  server.close();
+});
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-form.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-form.js
new file mode 100644 (file)
index 0000000..aeefd31
--- /dev/null
@@ -0,0 +1,79 @@
+var assert = require('assert')
+var http = require('http');
+var path = require('path');
+var mime = require('mime');
+var request = require('../main.js');
+var fs = require('fs');
+
+var remoteFile = 'http://nodejs.org/images/logo.png';
+
+var FIELDS = [
+  {name: 'my_field', value: 'my_value'},
+  {name: 'my_buffer', value: new Buffer([1, 2, 3])},
+  {name: 'my_file', value: fs.createReadStream(__dirname + '/unicycle.jpg')},
+  {name: 'remote_file', value: request(remoteFile) }
+];
+
+var server = http.createServer(function(req, res) {
+
+  // temp workaround
+  var data = '';
+  req.setEncoding('utf8');
+
+  req.on('data', function(d) {
+    data += d;
+  });
+
+  req.on('end', function() {
+    // check for the fields' traces
+
+    // 1st field : my_field
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf(field.value) != -1 );
+
+    // 2nd field : my_buffer
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf(field.value) != -1 );
+
+    // 3rd field : my_file
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
+    // check for unicycle.jpg traces
+    assert.ok( data.indexOf('2005:06:21 01:44:12') != -1 );
+    assert.ok( data.indexOf('Content-Type: '+mime.lookup(field.value.path) ) != -1 );
+
+    // 4th field : remote_file
+    var field = FIELDS.shift();
+    assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
+    assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
+    // check for http://nodejs.org/images/logo.png traces
+    assert.ok( data.indexOf('ImageReady') != -1 );
+    assert.ok( data.indexOf('Content-Type: '+mime.lookup(remoteFile) ) != -1 );
+
+    res.writeHead(200);
+    res.end('done');
+
+  });
+
+
+});
+
+server.listen(8080, function() {
+
+  var req = request.post('http://localhost:8080/upload', function () {
+    server.close();
+  })
+  var form = req.form()
+  
+  FIELDS.forEach(function(field) {
+    form.append(field.name, field.value);
+  });
+
+});
+
+process.on('exit', function() {
+  assert.strictEqual(FIELDS.length, 0);
+});
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-headers.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-headers.js
new file mode 100644 (file)
index 0000000..31fe3f4
--- /dev/null
@@ -0,0 +1,52 @@
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+  , Cookie = require('../vendor/cookie')
+  , Jar = require('../vendor/cookie/jar')
+  , s = server.createServer()
+
+s.listen(s.port, function () {
+  var serverUri = 'http://localhost:' + s.port
+    , numTests = 0
+    , numOutstandingTests = 0
+
+  function createTest(requestObj, serverAssertFn) {
+    var testNumber = numTests;
+    numTests += 1;
+    numOutstandingTests += 1;
+    s.on('/' + testNumber, function (req, res) {
+      serverAssertFn(req, res);
+      res.writeHead(200);
+      res.end();
+    });
+    requestObj.url = serverUri + '/' + testNumber
+    request(requestObj, function (err, res, body) {
+      assert.ok(!err)
+      assert.equal(res.statusCode, 200)
+      numOutstandingTests -= 1
+      if (numOutstandingTests === 0) {
+        console.log(numTests + ' tests passed.')
+        s.close()
+      }
+    })
+  }
+
+  // Issue #125: headers.cookie shouldn't be replaced when a cookie jar isn't specified
+  createTest({headers: {cookie: 'foo=bar'}}, function (req, res) {
+    assert.ok(req.headers.cookie)
+    assert.equal(req.headers.cookie, 'foo=bar')
+  })
+
+  // Issue #125: headers.cookie + cookie jar
+  var jar = new Jar()
+  jar.add(new Cookie('quux=baz'));
+  createTest({jar: jar, headers: {cookie: 'foo=bar'}}, function (req, res) {
+    assert.ok(req.headers.cookie)
+    assert.equal(req.headers.cookie, 'foo=bar; quux=baz')
+  })
+
+  // There should be no cookie header when neither headers.cookie nor a cookie jar is specified
+  createTest({}, function (req, res) {
+    assert.ok(!req.headers.cookie)
+  })
+})
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-httpModule.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-httpModule.js
new file mode 100644 (file)
index 0000000..1866de2
--- /dev/null
@@ -0,0 +1,94 @@
+var http = require('http')
+  , https = require('https')
+  , server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+
+
+var faux_requests_made = {'http':0, 'https':0}
+function wrap_request(name, module) {
+  // Just like the http or https module, but note when a request is made.
+  var wrapped = {}
+  Object.keys(module).forEach(function(key) {
+    var value = module[key];
+
+    if(key != 'request')
+      wrapped[key] = value;
+    else
+      wrapped[key] = function(options, callback) {
+        faux_requests_made[name] += 1
+        return value.apply(this, arguments)
+      }
+  })
+
+  return wrapped;
+}
+
+
+var faux_http = wrap_request('http', http)
+  , faux_https = wrap_request('https', https)
+  , plain_server = server.createServer()
+  , https_server = server.createSSLServer()
+
+
+plain_server.listen(plain_server.port, function() {
+  plain_server.on('/plain', function (req, res) {
+    res.writeHead(200)
+    res.end('plain')
+  })
+  plain_server.on('/to_https', function (req, res) {
+    res.writeHead(301, {'location':'https://localhost:'+https_server.port + '/https'})
+    res.end()
+  })
+
+  https_server.listen(https_server.port, function() {
+    https_server.on('/https', function (req, res) {
+      res.writeHead(200)
+      res.end('https')
+    })
+    https_server.on('/to_plain', function (req, res) {
+      res.writeHead(302, {'location':'http://localhost:'+plain_server.port + '/plain'})
+      res.end()
+    })
+
+    run_tests()
+    run_tests({})
+    run_tests({'http:':faux_http})
+    run_tests({'https:':faux_https})
+    run_tests({'http:':faux_http, 'https:':faux_https})
+  })
+})
+
+function run_tests(httpModules) {
+  var to_https = 'http://localhost:'+plain_server.port+'/to_https'
+  var to_plain = 'https://localhost:'+https_server.port+'/to_plain'
+
+  request(to_https, {'httpModules':httpModules}, function (er, res, body) {
+    assert.ok(!er, 'Bounce to SSL worked')
+    assert.equal(body, 'https', 'Received HTTPS server body')
+    done()
+  })
+
+  request(to_plain, {'httpModules':httpModules}, function (er, res, body) {
+    assert.ok(!er, 'Bounce to plaintext server worked')
+    assert.equal(body, 'plain', 'Received HTTPS server body')
+    done()
+  })
+}
+
+
+var passed = 0;
+function done() {
+  passed += 1
+  var expected = 10
+
+  if(passed == expected) {
+    plain_server.close()
+    https_server.close()
+
+    assert.equal(faux_requests_made.http, 4, 'Wrapped http module called appropriately')
+    assert.equal(faux_requests_made.https, 4, 'Wrapped https module called appropriately')
+
+    console.log((expected+2) + ' tests passed.')
+  }
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-https-strict.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-https-strict.js
new file mode 100644 (file)
index 0000000..470b68d
--- /dev/null
@@ -0,0 +1,97 @@
+// a test where we validate the siguature of the keys
+// otherwise exactly the same as the ssl test
+
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+  , fs = require('fs')
+  , path = require('path')
+  , opts = { key: path.resolve(__dirname, 'ssl/ca/server.key')
+           , cert: path.resolve(__dirname, 'ssl/ca/server.crt') }
+  , s = server.createSSLServer(null, opts)
+  , caFile = path.resolve(__dirname, 'ssl/ca/ca.crt')
+  , ca = fs.readFileSync(caFile)
+
+var tests =
+  { testGet :
+    { resp : server.createGetResponse("TESTING!")
+    , expectBody: "TESTING!"
+    }
+  , testGetChunkBreak :
+    { resp : server.createChunkResponse(
+      [ new Buffer([239])
+      , new Buffer([163])
+      , new Buffer([191])
+      , new Buffer([206])
+      , new Buffer([169])
+      , new Buffer([226])
+      , new Buffer([152])
+      , new Buffer([131])
+      ])
+    , expectBody: "Ω☃"
+    }
+  , testGetJSON :
+    { resp : server.createGetResponse('{"test":true}', 'application/json')
+    , json : true
+    , expectBody: {"test":true}
+    }
+  , testPutString :
+    { resp : server.createPostValidator("PUTTINGDATA")
+    , method : "PUT"
+    , body : "PUTTINGDATA"
+    }
+  , testPutBuffer :
+    { resp : server.createPostValidator("PUTTINGDATA")
+    , method : "PUT"
+    , body : new Buffer("PUTTINGDATA")
+    }
+  , testPutJSON :
+    { resp : server.createPostValidator(JSON.stringify({foo: 'bar'}))
+    , method: "PUT"
+    , json: {foo: 'bar'}
+    }
+  , testPutMultipart :
+    { resp: server.createPostValidator(
+        '--__BOUNDARY__\r\n' +
+        'content-type: text/html\r\n' +
+        '\r\n' +
+        '<html><body>Oh hi.</body></html>' +
+        '\r\n--__BOUNDARY__\r\n\r\n' +
+        'Oh hi.' +
+        '\r\n--__BOUNDARY__--'
+        )
+    , method: "PUT"
+    , multipart:
+      [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'}
+      , {'body': 'Oh hi.'}
+      ]
+    }
+  }
+
+s.listen(s.port, function () {
+
+  var counter = 0
+
+  for (i in tests) {
+    (function () {
+      var test = tests[i]
+      s.on('/'+i, test.resp)
+      test.uri = s.url + '/' + i
+      test.strictSSL = true
+      test.ca = ca
+      test.headers = { host: 'testing.request.mikealrogers.com' }
+      request(test, function (err, resp, body) {
+        if (err) throw err
+        if (test.expectBody) {
+          assert.deepEqual(test.expectBody, body)
+        }
+        counter = counter - 1;
+        if (counter === 0) {
+          console.log(Object.keys(tests).length+" tests passed.")
+          s.close()
+        }
+      })
+      counter++
+    })()
+  }
+})
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-https.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-https.js
new file mode 100644 (file)
index 0000000..58e7db9
--- /dev/null
@@ -0,0 +1,86 @@
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+
+var s = server.createSSLServer();
+
+var tests =
+  { testGet :
+    { resp : server.createGetResponse("TESTING!")
+    , expectBody: "TESTING!"
+    }
+  , testGetChunkBreak :
+    { resp : server.createChunkResponse(
+      [ new Buffer([239])
+      , new Buffer([163])
+      , new Buffer([191])
+      , new Buffer([206])
+      , new Buffer([169])
+      , new Buffer([226])
+      , new Buffer([152])
+      , new Buffer([131])
+      ])
+    , expectBody: "Ω☃"
+    }
+  , testGetJSON :
+    { resp : server.createGetResponse('{"test":true}', 'application/json')
+    , json : true
+    , expectBody: {"test":true}
+    }
+  , testPutString :
+    { resp : server.createPostValidator("PUTTINGDATA")
+    , method : "PUT"
+    , body : "PUTTINGDATA"
+    }
+  , testPutBuffer :
+    { resp : server.createPostValidator("PUTTINGDATA")
+    , method : "PUT"
+    , body : new Buffer("PUTTINGDATA")
+    }
+  , testPutJSON :
+    { resp : server.createPostValidator(JSON.stringify({foo: 'bar'}))
+    , method: "PUT"
+    , json: {foo: 'bar'}
+    }
+  , testPutMultipart :
+    { resp: server.createPostValidator(
+        '--__BOUNDARY__\r\n' +
+        'content-type: text/html\r\n' +
+        '\r\n' +
+        '<html><body>Oh hi.</body></html>' +
+        '\r\n--__BOUNDARY__\r\n\r\n' +
+        'Oh hi.' +
+        '\r\n--__BOUNDARY__--'
+        )
+    , method: "PUT"
+    , multipart:
+      [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'}
+      , {'body': 'Oh hi.'}
+      ]
+    }
+  }
+
+s.listen(s.port, function () {
+
+  var counter = 0
+
+  for (i in tests) {
+    (function () {
+      var test = tests[i]
+      s.on('/'+i, test.resp)
+      test.uri = s.url + '/' + i
+      request(test, function (err, resp, body) {
+        if (err) throw err
+        if (test.expectBody) {
+          assert.deepEqual(test.expectBody, body)
+        }
+        counter = counter - 1;
+        if (counter === 0) {
+          console.log(Object.keys(tests).length+" tests passed.")
+          s.close()
+        }
+      })
+      counter++
+    })()
+  }
+})
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-oauth.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-oauth.js
new file mode 100644 (file)
index 0000000..72ca923
--- /dev/null
@@ -0,0 +1,117 @@
+var hmacsign = require('../oauth').hmacsign
+  , assert = require('assert')
+  , qs = require('querystring')
+  , request = require('../main')
+  ;
+
+function getsignature (r) {
+  var sign
+  r.headers.Authorization.slice('OAuth '.length).replace(/,\ /g, ',').split(',').forEach(function (v) {
+    if (v.slice(0, 'oauth_signature="'.length) === 'oauth_signature="') sign = v.slice('oauth_signature="'.length, -1)
+  })
+  return decodeURIComponent(sign)
+}
+
+// Tests from Twitter documentation https://dev.twitter.com/docs/auth/oauth
+
+var reqsign = hmacsign('POST', 'https://api.twitter.com/oauth/request_token', 
+  { oauth_callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11'
+  , oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g'
+  , oauth_nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk'
+  , oauth_signature_method: 'HMAC-SHA1'
+  , oauth_timestamp: '1272323042'
+  , oauth_version: '1.0'
+  }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98")
+
+console.log(reqsign)
+console.log('8wUi7m5HFQy76nowoCThusfgB+Q=')
+assert.equal(reqsign, '8wUi7m5HFQy76nowoCThusfgB+Q=')
+
+var accsign = hmacsign('POST', 'https://api.twitter.com/oauth/access_token',
+  { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g'
+  , oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8'
+  , oauth_signature_method: 'HMAC-SHA1'
+  , oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc'
+  , oauth_timestamp: '1272323047'
+  , oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY'
+  , oauth_version: '1.0'
+  }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA")
+  
+console.log(accsign)
+console.log('PUw/dHA4fnlJYM6RhXk5IU/0fCc=')
+assert.equal(accsign, 'PUw/dHA4fnlJYM6RhXk5IU/0fCc=')
+
+var upsign = hmacsign('POST', 'http://api.twitter.com/1/statuses/update.json', 
+  { oauth_consumer_key: "GDdmIQH6jhtmLUypg82g"
+  , oauth_nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y"
+  , oauth_signature_method: "HMAC-SHA1"
+  , oauth_token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw"
+  , oauth_timestamp: "1272325550"
+  , oauth_version: "1.0"
+  , status: 'setting up my twitter 私のさえずりを設定する'
+  }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA")
+
+console.log(upsign)
+console.log('yOahq5m0YjDDjfjxHaXEsW9D+X0=')
+assert.equal(upsign, 'yOahq5m0YjDDjfjxHaXEsW9D+X0=')
+
+
+var rsign = request.post(
+  { url: 'https://api.twitter.com/oauth/request_token'
+  , oauth: 
+    { callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11'
+    , consumer_key: 'GDdmIQH6jhtmLUypg82g'
+    , nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk'
+    , timestamp: '1272323042'
+    , version: '1.0'
+    , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98"
+    }
+  })
+
+setTimeout(function () {
+  console.log(getsignature(rsign))
+  assert.equal(reqsign, getsignature(rsign))
+})
+
+var raccsign = request.post(
+  { url: 'https://api.twitter.com/oauth/access_token'
+  , oauth:  
+    { consumer_key: 'GDdmIQH6jhtmLUypg82g'
+    , nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8'
+    , signature_method: 'HMAC-SHA1'
+    , token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc'
+    , timestamp: '1272323047'
+    , verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY'
+    , version: '1.0'
+    , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98"
+    , token_secret: "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA" 
+    }
+  })
+
+setTimeout(function () {
+  console.log(getsignature(raccsign))
+  assert.equal(accsign, getsignature(raccsign))
+}, 1) 
+
+var rupsign = request.post(
+  { url: 'http://api.twitter.com/1/statuses/update.json' 
+  , oauth: 
+    { consumer_key: "GDdmIQH6jhtmLUypg82g"
+    , nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y"
+    , signature_method: "HMAC-SHA1"
+    , token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw"
+    , timestamp: "1272325550"
+    , version: "1.0"
+    , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98"
+    , token_secret: "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA"
+    }
+  , form: {status: 'setting up my twitter 私のさえずりを設定する'} 
+  })
+setTimeout(function () {
+  console.log(getsignature(rupsign))
+  assert.equal(upsign, getsignature(rupsign))
+}, 1)
+
+
+
+
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-params.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-params.js
new file mode 100644 (file)
index 0000000..5ddb311
--- /dev/null
@@ -0,0 +1,92 @@
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+  ;
+
+var s = server.createServer();
+
+var tests =
+  { testGet :
+    { resp : server.createGetResponse("TESTING!")
+    , expectBody: "TESTING!"
+    }
+    , testGetChunkBreak :
+      { resp : server.createChunkResponse(
+        [ new Buffer([239])
+        , new Buffer([163])
+        , new Buffer([191])
+        , new Buffer([206])
+        , new Buffer([169])
+        , new Buffer([226])
+        , new Buffer([152])
+        , new Buffer([131])
+        ])
+      , expectBody: "Ω☃"
+      }
+    , testGetBuffer :
+      { resp : server.createGetResponse(new Buffer("TESTING!"))
+      , encoding: null
+      , expectBody: new Buffer("TESTING!")
+      }
+    , testGetJSON :
+       { resp : server.createGetResponse('{"test":true}', 'application/json')
+       , json : true
+       , expectBody: {"test":true}
+       }
+    , testPutString :
+      { resp : server.createPostValidator("PUTTINGDATA")
+      , method : "PUT"
+      , body : "PUTTINGDATA"
+      }
+    , testPutBuffer :
+      { resp : server.createPostValidator("PUTTINGDATA")
+      , method : "PUT"
+      , body : new Buffer("PUTTINGDATA")
+      }
+    , testPutJSON :
+      { resp : server.createPostValidator(JSON.stringify({foo: 'bar'}))
+      , method: "PUT"
+      , json: {foo: 'bar'}
+      }
+    , testPutMultipart :
+      { resp: server.createPostValidator(
+          '--__BOUNDARY__\r\n' +
+          'content-type: text/html\r\n' +
+          '\r\n' +
+          '<html><body>Oh hi.</body></html>' +
+          '\r\n--__BOUNDARY__\r\n\r\n' +
+          'Oh hi.' +
+          '\r\n--__BOUNDARY__--'
+          )
+      , method: "PUT"
+      , multipart:
+        [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'}
+        , {'body': 'Oh hi.'}
+        ]
+      }
+  }
+
+s.listen(s.port, function () {
+
+  var counter = 0
+
+  for (i in tests) {
+    (function () {
+      var test = tests[i]
+      s.on('/'+i, test.resp)
+      //test.uri = s.url + '/' + i
+      request(s.url + '/' + i, test, function (err, resp, body) {
+        if (err) throw err
+        if (test.expectBody) {
+          assert.deepEqual(test.expectBody, body)
+        }
+        counter = counter - 1;
+        if (counter === 0) {
+          console.log(Object.keys(tests).length+" tests passed.")
+          s.close()
+        }
+      })
+      counter++
+    })()
+  }
+})
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-piped-redirect.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-piped-redirect.js
new file mode 100644 (file)
index 0000000..25bf35d
--- /dev/null
@@ -0,0 +1,52 @@
+var http = require('http')
+  , assert = require('assert')
+  , request = require('../main.js')
+  ;
+
+var portOne = 8968
+  , portTwo = 8969
+  ;
+
+
+// server one
+var s1 = http.createServer(function (req, resp)
+{
+  if (req.url == '/original')
+  {
+    resp.writeHeader(302, {'location': '/redirected'})
+    resp.end()
+  }
+  else if (req.url == '/redirected')
+  {
+    resp.writeHeader(200, {'content-type': 'text/plain'})
+    resp.write('OK')
+    resp.end()
+  }
+
+}).listen(portOne);
+
+
+// server two
+var s2 = http.createServer(function (req, resp)
+{
+
+  var x = request('http://localhost:'+portOne+'/original')
+  req.pipe(x)
+  x.pipe(resp)
+
+}).listen(portTwo, function()
+{
+
+  var r = request('http://localhost:'+portTwo+'/original', function (err, res, body) {
+
+    assert.equal(body, 'OK')
+
+    s1.close()
+    s2.close()
+
+  });
+
+  // it hangs, so wait a second :)
+  r.timeout = 1000;
+
+});
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-pipes.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-pipes.js
new file mode 100644 (file)
index 0000000..7162981
--- /dev/null
@@ -0,0 +1,216 @@
+var server = require('./server')
+  , events = require('events')
+  , stream = require('stream')
+  , assert = require('assert')
+  , fs = require('fs')
+  , request = require('../main.js')
+  , path = require('path')
+  , util = require('util')
+  ;
+
+var s = server.createServer(3453);
+
+function ValidationStream(str) {
+  this.str = str
+  this.buf = ''
+  this.on('data', function (data) {
+    this.buf += data
+  })
+  this.on('end', function () {
+    assert.equal(this.str, this.buf)
+  })
+  this.writable = true
+}
+util.inherits(ValidationStream, stream.Stream)
+ValidationStream.prototype.write = function (chunk) {
+  this.emit('data', chunk)
+}
+ValidationStream.prototype.end = function (chunk) {
+  if (chunk) emit('data', chunk)
+  this.emit('end')
+}
+
+s.listen(s.port, function () {
+  counter = 0;
+
+  var check = function () {
+    counter = counter - 1
+    if (counter === 0) {
+      console.log('All tests passed.')
+      setTimeout(function () {
+        process.exit();
+      }, 500)
+    }
+  }
+
+  // Test pipeing to a request object
+  s.once('/push', server.createPostValidator("mydata"));
+
+  var mydata = new stream.Stream();
+  mydata.readable = true
+
+  counter++
+  var r1 = request.put({url:'http://localhost:3453/push'}, function () {
+    check();
+  })
+  mydata.pipe(r1)
+
+  mydata.emit('data', 'mydata');
+  mydata.emit('end');
+
+  // Test pipeing to a request object with a json body
+  s.once('/push-json', server.createPostValidator("{\"foo\":\"bar\"}", "application/json"));
+
+  var mybodydata = new stream.Stream();
+  mybodydata.readable = true
+
+  counter++
+  var r2 = request.put({url:'http://localhost:3453/push-json',json:true}, function () {
+    check();
+  })
+  mybodydata.pipe(r2)
+
+  mybodydata.emit('data', JSON.stringify({foo:"bar"}));
+  mybodydata.emit('end');
+
+  // Test pipeing from a request object.
+  s.once('/pull', server.createGetResponse("mypulldata"));
+
+  var mypulldata = new stream.Stream();
+  mypulldata.writable = true
+
+  counter++
+  request({url:'http://localhost:3453/pull'}).pipe(mypulldata)
+
+  var d = '';
+
+  mypulldata.write = function (chunk) {
+    d += chunk;
+  }
+  mypulldata.end = function () {
+    assert.equal(d, 'mypulldata');
+    check();
+  };
+
+
+  s.on('/cat', function (req, resp) {
+    if (req.method === "GET") {
+      resp.writeHead(200, {'content-type':'text/plain-test', 'content-length':4});
+      resp.end('asdf')
+    } else if (req.method === "PUT") {
+      assert.equal(req.headers['content-type'], 'text/plain-test');
+      assert.equal(req.headers['content-length'], 4)
+      var validate = '';
+
+      req.on('data', function (chunk) {validate += chunk})
+      req.on('end', function () {
+        resp.writeHead(201);
+        resp.end();
+        assert.equal(validate, 'asdf');
+        check();
+      })
+    }
+  })
+  s.on('/pushjs', function (req, resp) {
+    if (req.method === "PUT") {
+      assert.equal(req.headers['content-type'], 'application/javascript');
+      check();
+    }
+  })
+  s.on('/catresp', function (req, resp) {
+    request.get('http://localhost:3453/cat').pipe(resp)
+  })
+  s.on('/doodle', function (req, resp) {
+    if (req.headers['x-oneline-proxy']) {
+      resp.setHeader('x-oneline-proxy', 'yup')
+    }
+    resp.writeHead('200', {'content-type':'image/png'})
+    fs.createReadStream(path.join(__dirname, 'googledoodle.png')).pipe(resp)
+  })
+  s.on('/onelineproxy', function (req, resp) {
+    var x = request('http://localhost:3453/doodle')
+    req.pipe(x)
+    x.pipe(resp)
+  })
+
+  counter++
+  fs.createReadStream(__filename).pipe(request.put('http://localhost:3453/pushjs'))
+
+  counter++
+  request.get('http://localhost:3453/cat').pipe(request.put('http://localhost:3453/cat'))
+
+  counter++
+  request.get('http://localhost:3453/catresp', function (e, resp, body) {
+    assert.equal(resp.headers['content-type'], 'text/plain-test');
+    assert.equal(resp.headers['content-length'], 4)
+    check();
+  })
+
+  var doodleWrite = fs.createWriteStream(path.join(__dirname, 'test.png'))
+
+  counter++
+  request.get('http://localhost:3453/doodle').pipe(doodleWrite)
+
+  doodleWrite.on('close', function () {
+    assert.deepEqual(fs.readFileSync(path.join(__dirname, 'googledoodle.png')), fs.readFileSync(path.join(__dirname, 'test.png')))
+    check()
+  })
+
+  process.on('exit', function () {
+    fs.unlinkSync(path.join(__dirname, 'test.png'))
+  })
+
+  counter++
+  request.get({uri:'http://localhost:3453/onelineproxy', headers:{'x-oneline-proxy':'nope'}}, function (err, resp, body) {
+    assert.equal(resp.headers['x-oneline-proxy'], 'yup')
+    check()
+  })
+
+  s.on('/afterresponse', function (req, resp) {
+    resp.write('d')
+    resp.end()
+  })
+
+  counter++
+  var afterresp = request.post('http://localhost:3453/afterresponse').on('response', function () {
+    var v = new ValidationStream('d')
+    afterresp.pipe(v)
+    v.on('end', check)
+  })
+  
+  s.on('/forward1', function (req, resp) {
+   resp.writeHead(302, {location:'/forward2'})
+    resp.end()
+  })
+  s.on('/forward2', function (req, resp) {
+    resp.writeHead('200', {'content-type':'image/png'})
+    resp.write('d')
+    resp.end()
+  })
+  
+  counter++
+  var validateForward = new ValidationStream('d')
+  validateForward.on('end', check)
+  request.get('http://localhost:3453/forward1').pipe(validateForward)
+
+  // Test pipe options
+  s.once('/opts', server.createGetResponse('opts response'));
+
+  var optsStream = new stream.Stream();
+  optsStream.writable = true
+  
+  var optsData = '';
+  optsStream.write = function (buf) {
+    optsData += buf;
+    if (optsData === 'opts response') {
+      setTimeout(check, 10);
+    }
+  }
+
+  optsStream.end = function () {
+    assert.fail('end called')
+  };
+
+  counter++
+  request({url:'http://localhost:3453/opts'}).pipe(optsStream, { end : false })
+})
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-pool.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-pool.js
new file mode 100644 (file)
index 0000000..1e7d578
--- /dev/null
@@ -0,0 +1,16 @@
+var request = require('../main')
+  , http = require('http')
+  , assert = require('assert')
+  ;
+
+var s = http.createServer(function (req, resp) {
+  resp.statusCode = 200;
+  resp.end('asdf');
+}).listen(8080, function () {
+  request({'url': 'http://localhost:8080', 'pool': false}, function (e, resp) {
+    var agent = resp.request.agent;
+    assert.strictEqual(typeof agent, 'boolean');
+    assert.strictEqual(agent, false);
+    s.close();
+  });
+});
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-protocol-changing-redirect.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-protocol-changing-redirect.js
new file mode 100644 (file)
index 0000000..f74e196
--- /dev/null
@@ -0,0 +1,60 @@
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+
+
+var s = server.createServer()
+var ss = server.createSSLServer()
+var sUrl = 'http://localhost:' + s.port
+var ssUrl = 'https://localhost:' + ss.port
+
+s.listen(s.port, bouncy(s, ssUrl))
+ss.listen(ss.port, bouncy(ss, sUrl))
+
+var hits = {}
+var expect = {}
+var pending = 0
+function bouncy (s, server) { return function () {
+
+  var redirs = { a: 'b'
+               , b: 'c'
+               , c: 'd'
+               , d: 'e'
+               , e: 'f'
+               , f: 'g'
+               , g: 'h'
+               , h: 'end' }
+
+  var perm = true
+  Object.keys(redirs).forEach(function (p) {
+    var t = redirs[p]
+
+    // switch type each time
+    var type = perm ? 301 : 302
+    perm = !perm
+    s.on('/' + p, function (req, res) {
+      res.writeHead(type, { location: server + '/' + t })
+      res.end()
+    })
+  })
+
+  s.on('/end', function (req, res) {
+    var h = req.headers['x-test-key']
+    hits[h] = true
+    pending --
+    if (pending === 0) done()
+  })
+}}
+
+for (var i = 0; i < 5; i ++) {
+  pending ++
+  var val = 'test_' + i
+  expect[val] = true
+  request({ url: (i % 2 ? sUrl : ssUrl) + '/a'
+          , headers: { 'x-test-key': val } })
+}
+
+function done () {
+  assert.deepEqual(hits, expect)
+  process.exit(0)
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-proxy.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-proxy.js
new file mode 100644 (file)
index 0000000..647157c
--- /dev/null
@@ -0,0 +1,39 @@
+var server = require('./server')
+  , events = require('events')
+  , stream = require('stream')
+  , assert = require('assert')
+  , fs = require('fs')
+  , request = require('../main.js')
+  , path = require('path')
+  , util = require('util')
+  ;
+
+var port = 6768
+  , called = false
+  , proxiedHost = 'google.com'
+  ;
+
+var s = server.createServer(port)
+s.listen(port, function () {
+  s.on('http://google.com/', function (req, res) {
+    called = true
+    assert.equal(req.headers.host, proxiedHost)
+    res.writeHeader(200)
+    res.end()
+  })
+  request ({
+    url: 'http://'+proxiedHost,
+    proxy: 'http://localhost:'+port
+    /*
+    //should behave as if these arguments where passed:
+    url: 'http://localhost:'+port,
+    headers: {host: proxiedHost}
+    //*/
+  }, function (err, res, body) {
+    s.close()
+  })
+})
+
+process.on('exit', function () {
+  assert.ok(called, 'the request must be made to the proxy server')
+})
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-qs.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-qs.js
new file mode 100644 (file)
index 0000000..1aac22b
--- /dev/null
@@ -0,0 +1,28 @@
+var request = request = require('../main.js')
+  , assert = require('assert')
+  ;
+
+// Test adding a querystring
+var req1 = request.get({ uri: 'http://www.google.com', qs: { q : 'search' }})
+setTimeout(function() {
+       assert.equal('/?q=search', req1.path)
+}, 1)
+
+// Test replacing a querystring value
+var req2 = request.get({ uri: 'http://www.google.com?q=abc', qs: { q : 'search' }})
+setTimeout(function() {
+       assert.equal('/?q=search', req2.path)
+}, 1)
+
+// Test appending a querystring value to the ones present in the uri
+var req3 = request.get({ uri: 'http://www.google.com?x=y', qs: { q : 'search' }})
+setTimeout(function() {
+       assert.equal('/?x=y&q=search', req3.path)
+}, 1)
+
+// Test leaving a querystring alone
+var req4 = request.get({ uri: 'http://www.google.com?x=y'})
+setTimeout(function() {
+       assert.equal('/?x=y', req4.path)
+}, 1)
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-redirect.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-redirect.js
new file mode 100644 (file)
index 0000000..b84844a
--- /dev/null
@@ -0,0 +1,154 @@
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+  , Cookie = require('../vendor/cookie')
+  , Jar = require('../vendor/cookie/jar')
+
+var s = server.createServer()
+
+s.listen(s.port, function () {
+  var server = 'http://localhost:' + s.port;
+  var hits = {}
+  var passed = 0;
+
+  bouncer(301, 'temp')
+  bouncer(302, 'perm')
+  bouncer(302, 'nope')
+
+  function bouncer(code, label) {
+    var landing = label+'_landing';
+
+    s.on('/'+label, function (req, res) {
+      hits[label] = true;
+      res.writeHead(code, {
+        'location':server + '/'+landing,
+        'set-cookie': 'ham=eggs'
+      })
+      res.end()
+    })
+
+    s.on('/'+landing, function (req, res) {
+      if (req.method !== 'GET') { // We should only accept GET redirects
+        console.error("Got a non-GET request to the redirect destination URL");
+        res.writeHead(400);
+        res.end();
+        return;
+      }
+      // Make sure the cookie doesn't get included twice, see #139:
+      // Make sure cookies are set properly after redirect
+      assert.equal(req.headers.cookie, 'foo=bar; quux=baz; ham=eggs');
+      hits[landing] = true;
+      res.writeHead(200)
+      res.end(landing)
+    })
+  }
+
+  // Permanent bounce
+  var jar = new Jar()
+  jar.add(new Cookie('quux=baz'))
+  request({uri: server+'/perm', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode)
+    assert.ok(hits.perm, 'Original request is to /perm')
+    assert.ok(hits.perm_landing, 'Forward to permanent landing URL')
+    assert.equal(body, 'perm_landing', 'Got permanent landing content')
+    passed += 1
+    done()
+  })
+  
+  // Temporary bounce
+  request({uri: server+'/temp', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode)
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(hits.temp_landing, 'Forward to temporary landing URL')
+    assert.equal(body, 'temp_landing', 'Got temporary landing content')
+    passed += 1
+    done()
+  })
+  
+  // Prevent bouncing.
+  request({uri:server+'/nope', jar: jar, headers: {cookie: 'foo=bar'}, followRedirect:false}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 302) throw new Error('Status is not 302: '+res.statusCode)
+    assert.ok(hits.nope, 'Original request to /nope')
+    assert.ok(!hits.nope_landing, 'No chasing the redirect')
+    assert.equal(res.statusCode, 302, 'Response is the bounce itself')
+    passed += 1
+    done()
+  })
+  
+  // Should not follow post redirects by default
+  request.post(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode)
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(!hits.temp_landing, 'No chasing the redirect when post')
+    assert.equal(res.statusCode, 301, 'Response is the bounce itself')
+    passed += 1
+    done()
+  })
+  
+  // Should follow post redirects when followAllRedirects true
+  request.post({uri:server+'/temp', followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode)
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(hits.temp_landing, 'Forward to temporary landing URL')
+    assert.equal(body, 'temp_landing', 'Got temporary landing content')
+    passed += 1
+    done()
+  })
+  
+  request.post({uri:server+'/temp', followAllRedirects:false, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode)
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(!hits.temp_landing, 'No chasing the redirect')
+    assert.equal(res.statusCode, 301, 'Response is the bounce itself')
+    passed += 1
+    done()
+  })
+
+  // Should not follow delete redirects by default
+  request.del(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode < 301) throw new Error('Status is not a redirect.')
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(!hits.temp_landing, 'No chasing the redirect when delete')
+    assert.equal(res.statusCode, 301, 'Response is the bounce itself')
+    passed += 1
+    done()
+  })
+  
+  // Should not follow delete redirects even if followRedirect is set to true
+  request.del(server+'/temp', { followRedirect: true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode)
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(!hits.temp_landing, 'No chasing the redirect when delete')
+    assert.equal(res.statusCode, 301, 'Response is the bounce itself')
+    passed += 1
+    done()
+  })
+  
+  // Should follow delete redirects when followAllRedirects true
+  request.del(server+'/temp', {followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode)
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(hits.temp_landing, 'Forward to temporary landing URL')
+    assert.equal(body, 'temp_landing', 'Got temporary landing content')
+    passed += 1
+    done()
+  })
+
+  var reqs_done = 0;
+  function done() {
+    reqs_done += 1;
+    if(reqs_done == 9) {
+      console.log(passed + ' tests passed.')
+      s.close()
+    }
+  }
+})
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-s3.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-s3.js
new file mode 100644 (file)
index 0000000..5f59c4a
--- /dev/null
@@ -0,0 +1,13 @@
+var request = require('../main')
+
+var r = request.get('https://log.curlybracecast.com.s3.amazonaws.com/', 
+  { aws: 
+    { key: 'AKIAI6KIQRRVMGK3WK5Q'
+    , secret: 'j4kaxM7TUiN7Ou0//v1ZqOVn3Aq7y1ccPh/tHTna'
+    , bucket: 'log.curlybracecast.com'
+    }
+  }, function (e, resp, body) {
+    console.log(r.headers)
+    console.log(body)
+  }
+)
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-timeout.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-timeout.js
new file mode 100644 (file)
index 0000000..673f8ad
--- /dev/null
@@ -0,0 +1,87 @@
+var server = require('./server')
+  , events = require('events')
+  , stream = require('stream')
+  , assert = require('assert')
+  , request = require('../main.js')
+  ;
+
+var s = server.createServer();
+var expectedBody = "waited";
+var remainingTests = 5;
+
+s.listen(s.port, function () {
+  // Request that waits for 200ms
+  s.on('/timeout', function (req, resp) {
+    setTimeout(function(){
+      resp.writeHead(200, {'content-type':'text/plain'})
+      resp.write(expectedBody)
+      resp.end()
+    }, 200);
+  });
+
+  // Scenario that should timeout
+  var shouldTimeout = {
+    url: s.url + "/timeout",
+    timeout:100
+  }
+
+
+  request(shouldTimeout, function (err, resp, body) {
+    assert.equal(err.code, "ETIMEDOUT");
+    checkDone();
+  })
+
+
+  // Scenario that shouldn't timeout
+  var shouldntTimeout = {
+    url: s.url + "/timeout",
+    timeout:300
+  }
+
+  request(shouldntTimeout, function (err, resp, body) {
+    assert.equal(err, null);
+    assert.equal(expectedBody, body)
+    checkDone();
+  })
+
+  // Scenario with no timeout set, so shouldn't timeout
+  var noTimeout = {
+    url: s.url + "/timeout"
+  }
+
+  request(noTimeout, function (err, resp, body) {
+    assert.equal(err);
+    assert.equal(expectedBody, body)
+    checkDone();
+  })
+
+  // Scenario with a negative timeout value, should be treated a zero or the minimum delay
+  var negativeTimeout = {
+    url: s.url + "/timeout",
+    timeout:-1000
+  }
+
+  request(negativeTimeout, function (err, resp, body) {
+    assert.equal(err.code, "ETIMEDOUT");
+    checkDone();
+  })
+
+  // Scenario with a float timeout value, should be rounded by setTimeout anyway
+  var floatTimeout = {
+    url: s.url + "/timeout",
+    timeout: 100.76
+  }
+
+  request(floatTimeout, function (err, resp, body) {
+    assert.equal(err.code, "ETIMEDOUT");
+    checkDone();
+  })
+
+  function checkDone() {
+    if(--remainingTests == 0) {
+      s.close();
+      console.log("All tests passed.");
+    }
+  }
+})
+
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-toJSON.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-toJSON.js
new file mode 100644 (file)
index 0000000..b7c67ef
--- /dev/null
@@ -0,0 +1,14 @@
+var request = require('../main')
+  , http = require('http')
+  , assert = require('assert')
+  ;
+
+var s = http.createServer(function (req, resp) {
+  resp.statusCode = 200
+  resp.end('asdf')
+}).listen(8080, function () {
+  var r = request('http://localhost:8080', function (e, resp) {
+    assert.equal(JSON.parse(JSON.stringify(r)).response.statusCode, 200)
+    s.close()
+  })
+})
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-tunnel.js b/deps/npm/node_modules/node-gyp/node_modules/request/tests/test-tunnel.js
new file mode 100644 (file)
index 0000000..51e2126
--- /dev/null
@@ -0,0 +1,63 @@
+// test that we can tunnel a https request over an http proxy
+// keeping all the CA and whatnot intact.
+//
+// Note: this requires that squid is installed.
+// If the proxy fails to start, we'll just log a warning and assume success.
+
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+  , fs = require('fs')
+  , path = require('path')
+  , caFile = path.resolve(__dirname, 'ssl/npm-ca.crt')
+  , ca = fs.readFileSync(caFile)
+  , child_process = require('child_process')
+  , sqConf = path.resolve(__dirname, 'squid.conf')
+  , sqArgs = ['-f', sqConf, '-N', '-d', '5']
+  , proxy = 'http://localhost:3128'
+  , hadError = null
+
+var squid = child_process.spawn('squid', sqArgs);
+var ready = false
+
+squid.stderr.on('data', function (c) {
+  console.error('SQUIDERR ' + c.toString().trim().split('\n')
+               .join('\nSQUIDERR '))
+  ready = c.toString().match(/ready to serve requests/i)
+})
+
+squid.stdout.on('data', function (c) {
+  console.error('SQUIDOUT ' + c.toString().trim().split('\n')
+               .join('\nSQUIDOUT '))
+})
+
+squid.on('exit', function (c) {
+  console.error('squid: exit '+c)
+  if (c && !ready) {
+    console.error('squid must be installed to run this test.')
+    console.error('skipping this test. please install squid and run again if you need to test tunneling.')
+    c = null
+    hadError = null
+    process.exit(0)
+    return
+  }
+
+  if (c) {
+    hadError = hadError || new Error('Squid exited with '+c)
+  }
+  if (hadError) throw hadError
+})
+
+setTimeout(function F () {
+  if (!ready) return setTimeout(F, 100)
+  request({ uri: 'https://registry.npmjs.org/'
+          , proxy: 'http://localhost:3128'
+          , strictSSL: true
+          , ca: ca
+          , json: true }, function (er, body) {
+    hadError = er
+    console.log(er || typeof body)
+    if (!er) console.log("ok")
+    squid.kill('SIGKILL')
+  })
+}, 100)
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tests/unicycle.jpg b/deps/npm/node_modules/node-gyp/node_modules/request/tests/unicycle.jpg
new file mode 100644 (file)
index 0000000..7cea4dd
Binary files /dev/null and b/deps/npm/node_modules/node-gyp/node_modules/request/tests/unicycle.jpg differ
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/tunnel.js b/deps/npm/node_modules/node-gyp/node_modules/request/tunnel.js
new file mode 100644 (file)
index 0000000..3f7bbb9
--- /dev/null
@@ -0,0 +1,227 @@
+'use strict'
+
+var net = require('net')
+  , tls = require('tls')
+  , http = require('http')
+  , https = require('https')
+  , events = require('events')
+  , assert = require('assert')
+  , util = require('util')
+  ;
+
+exports.httpOverHttp = httpOverHttp
+exports.httpsOverHttp = httpsOverHttp
+exports.httpOverHttps = httpOverHttps
+exports.httpsOverHttps = httpsOverHttps
+
+
+function httpOverHttp(options) {
+  var agent = new TunnelingAgent(options)
+  agent.request = http.request
+  return agent
+}
+
+function httpsOverHttp(options) {
+  var agent = new TunnelingAgent(options)
+  agent.request = http.request
+  agent.createSocket = createSecureSocket
+  return agent
+}
+
+function httpOverHttps(options) {
+  var agent = new TunnelingAgent(options)
+  agent.request = https.request
+  return agent
+}
+
+function httpsOverHttps(options) {
+  var agent = new TunnelingAgent(options)
+  agent.request = https.request
+  agent.createSocket = createSecureSocket
+  return agent
+}
+
+
+function TunnelingAgent(options) {
+  var self = this
+  self.options = options || {}
+  self.proxyOptions = self.options.proxy || {}
+  self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets
+  self.requests = []
+  self.sockets = []
+
+  self.on('free', function onFree(socket, host, port) {
+    for (var i = 0, len = self.requests.length; i < len; ++i) {
+      var pending = self.requests[i]
+      if (pending.host === host && pending.port === port) {
+        // Detect the request to connect same origin server,
+        // reuse the connection.
+        self.requests.splice(i, 1)
+        pending.request.onSocket(socket)
+        return
+      }
+    }
+    socket.destroy()
+    self.removeSocket(socket)
+  })
+}
+util.inherits(TunnelingAgent, events.EventEmitter)
+
+TunnelingAgent.prototype.addRequest = function addRequest(req, host, port) {
+  var self = this
+
+  if (self.sockets.length >= this.maxSockets) {
+    // We are over limit so we'll add it to the queue.
+    self.requests.push({host: host, port: port, request: req})
+    return
+  }
+
+  // If we are under maxSockets create a new one.
+  self.createSocket({host: host, port: port, request: req}, function(socket) {
+    socket.on('free', onFree)
+    socket.on('close', onCloseOrRemove)
+    socket.on('agentRemove', onCloseOrRemove)
+    req.onSocket(socket)
+
+    function onFree() {
+      self.emit('free', socket, host, port)
+    }
+
+    function onCloseOrRemove(err) {
+      self.removeSocket()
+      socket.removeListener('free', onFree)
+      socket.removeListener('close', onCloseOrRemove)
+      socket.removeListener('agentRemove', onCloseOrRemove)
+    }
+  })
+}
+
+TunnelingAgent.prototype.createSocket = function createSocket(options, cb) {
+  var self = this
+  var placeholder = {}
+  self.sockets.push(placeholder)
+
+  var connectOptions = mergeOptions({}, self.proxyOptions, 
+    { method: 'CONNECT'
+    , path: options.host + ':' + options.port
+    , agent: false
+    }
+  )
+  if (connectOptions.proxyAuth) {
+    connectOptions.headers = connectOptions.headers || {}
+    connectOptions.headers['Proxy-Authorization'] = 'Basic ' +
+        new Buffer(connectOptions.proxyAuth).toString('base64')
+  }
+
+  debug('making CONNECT request')
+  var connectReq = self.request(connectOptions)
+  connectReq.useChunkedEncodingByDefault = false // for v0.6
+  connectReq.once('response', onResponse) // for v0.6
+  connectReq.once('upgrade', onUpgrade)   // for v0.6
+  connectReq.once('connect', onConnect)   // for v0.7 or later
+  connectReq.once('error', onError)
+  connectReq.end()
+
+  function onResponse(res) {
+    // Very hacky. This is necessary to avoid http-parser leaks.
+    res.upgrade = true
+  }
+
+  function onUpgrade(res, socket, head) {
+    // Hacky.
+    process.nextTick(function() {
+      onConnect(res, socket, head)
+    })
+  }
+
+  function onConnect(res, socket, head) {
+    connectReq.removeAllListeners()
+    socket.removeAllListeners()
+
+    if (res.statusCode === 200) {
+      assert.equal(head.length, 0)
+      debug('tunneling connection has established')
+      self.sockets[self.sockets.indexOf(placeholder)] = socket
+      cb(socket)
+    } else {
+      debug('tunneling socket could not be established, statusCode=%d', res.statusCode)
+      var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode)
+      error.code = 'ECONNRESET'
+      options.request.emit('error', error)
+      self.removeSocket(placeholder)
+    }
+  }
+
+  function onError(cause) {
+    connectReq.removeAllListeners()
+
+    debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack)
+    var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message)
+    error.code = 'ECONNRESET'
+    options.request.emit('error', error)
+    self.removeSocket(placeholder)
+  }
+}
+
+TunnelingAgent.prototype.removeSocket = function removeSocket(socket) {
+  var pos = this.sockets.indexOf(socket)
+  if (pos === -1) return
+  
+  this.sockets.splice(pos, 1)
+
+  var pending = this.requests.shift()
+  if (pending) {
+    // If we have pending requests and a socket gets closed a new one
+    // needs to be created to take over in the pool for the one that closed.
+    this.createSocket(pending, function(socket) {
+      pending.request.onSocket(socket)
+    })
+  }
+}
+
+function createSecureSocket(options, cb) {
+  var self = this
+  TunnelingAgent.prototype.createSocket.call(self, options, function(socket) {
+    // 0 is dummy port for v0.6
+    var secureSocket = tls.connect(0, mergeOptions({}, self.options, 
+      { servername: options.host
+      , socket: socket
+      }
+    ))
+    cb(secureSocket)
+  })
+}
+
+
+function mergeOptions(target) {
+  for (var i = 1, len = arguments.length; i < len; ++i) {
+    var overrides = arguments[i]
+    if (typeof overrides === 'object') {
+      var keys = Object.keys(overrides)
+      for (var j = 0, keyLen = keys.length; j < keyLen; ++j) {
+        var k = keys[j]
+        if (overrides[k] !== undefined) {
+          target[k] = overrides[k]
+        }
+      }
+    }
+  }
+  return target
+}
+
+
+var debug
+if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) {
+  debug = function() {
+    var args = Array.prototype.slice.call(arguments)
+    if (typeof args[0] === 'string') {
+      args[0] = 'TUNNEL: ' + args[0]
+    } else {
+      args.unshift('TUNNEL:')
+    }
+    console.error.apply(console, args)
+  }
+} else {
+  debug = function() {}
+}
+exports.debug = debug // for test
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/uuid.js b/deps/npm/node_modules/node-gyp/node_modules/request/uuid.js
new file mode 100644 (file)
index 0000000..fc0588b
--- /dev/null
@@ -0,0 +1,19 @@
+module.exports = function () {
+  var s = [], itoh = '0123456789ABCDEF'
+  // Make array of random hex digits. The UUID only has 32 digits in it, but we
+  // allocate an extra items to make room for the '-'s we'll be inserting.
+  for (var i = 0; i <36; i++) s[i] = Math.floor(Math.random()*0x10)
+  // Conform to RFC-4122, section 4.4
+  s[14] = 4;  // Set 4 high bits of time_high field to version
+  s[19] = (s[19] & 0x3) | 0x8  // Specify 2 high bits of clock sequence
+  // Convert to hex chars
+  for (var i = 0; i <36; i++) s[i] = itoh[s[i]]
+  // Insert '-'s
+  s[8] = s[13] = s[18] = s[23] = '-'
+  return s.join('')
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/vendor/cookie/index.js b/deps/npm/node_modules/node-gyp/node_modules/request/vendor/cookie/index.js
new file mode 100644 (file)
index 0000000..ff44b3e
--- /dev/null
@@ -0,0 +1,65 @@
+/*!
+ * Tobi - Cookie
+ * Copyright(c) 2010 LearnBoost <dev@learnboost.com>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var url = require('url');
+
+/**
+ * Initialize a new `Cookie` with the given cookie `str` and `req`.
+ *
+ * @param {String} str
+ * @param {IncomingRequest} req
+ * @api private
+ */
+
+var Cookie = exports = module.exports = function Cookie(str, req) {
+  this.str = str;
+
+  // Map the key/val pairs
+  str.split(/ *; */).reduce(function(obj, pair){
+   var p = pair.indexOf('=');
+   var key = p > 0 ? pair.substring(0, p).trim() : pair.trim();
+   var lowerCasedKey = key.toLowerCase();
+   var value = p > 0 ? pair.substring(p + 1).trim() : true;
+
+   if (!obj.name) {
+    // First key is the name
+    obj.name = key;
+    obj.value = value;
+   }
+   else if (lowerCasedKey === 'httponly') {
+    obj.httpOnly = value;
+   }
+   else {
+    obj[lowerCasedKey] = value;
+   }
+   return obj;
+  }, this);
+
+  // Expires
+  this.expires = this.expires
+    ? new Date(this.expires)
+    : Infinity;
+
+  // Default or trim path
+  this.path = this.path
+    ? this.path.trim(): req 
+    ? url.parse(req.url).pathname: '/';
+};
+
+/**
+ * Return the original cookie string.
+ *
+ * @return {String}
+ * @api public
+ */
+
+Cookie.prototype.toString = function(){
+  return this.str;
+};
diff --git a/deps/npm/node_modules/node-gyp/node_modules/request/vendor/cookie/jar.js b/deps/npm/node_modules/node-gyp/node_modules/request/vendor/cookie/jar.js
new file mode 100644 (file)
index 0000000..34920e0
--- /dev/null
@@ -0,0 +1,72 @@
+/*!
+* Tobi - CookieJar
+* Copyright(c) 2010 LearnBoost <dev@learnboost.com>
+* MIT Licensed
+*/
+
+/**
+* Module dependencies.
+*/
+
+var url = require('url');
+
+/**
+* Initialize a new `CookieJar`.
+*
+* @api private
+*/
+
+var CookieJar = exports = module.exports = function CookieJar() {
+  this.cookies = [];
+};
+
+/**
+* Add the given `cookie` to the jar.
+*
+* @param {Cookie} cookie
+* @api private
+*/
+
+CookieJar.prototype.add = function(cookie){
+  this.cookies = this.cookies.filter(function(c){
+    // Avoid duplication (same path, same name)
+    return !(c.name == cookie.name && c.path == cookie.path);
+  });
+  this.cookies.push(cookie);
+};
+
+/**
+* Get cookies for the given `req`.
+*
+* @param {IncomingRequest} req
+* @return {Array}
+* @api private
+*/
+
+CookieJar.prototype.get = function(req){
+  var path = url.parse(req.url).pathname
+    , now = new Date
+    , specificity = {};
+  return this.cookies.filter(function(cookie){
+    if (0 == path.indexOf(cookie.path) && now < cookie.expires
+      && cookie.path.length > (specificity[cookie.name] || 0))
+      return specificity[cookie.name] = cookie.path.length;
+  });
+};
+
+/**
+* Return Cookie string for the given `req`.
+*
+* @param {IncomingRequest} req
+* @return {String}
+* @api private
+*/
+
+CookieJar.prototype.cookieString = function(req){
+  var cookies = this.get(req);
+  if (cookies.length) {
+    return cookies.map(function(cookie){
+      return cookie.name + '=' + cookie.value;
+    }).join('; ');
+  }
+};
index 751d240..1fcc19a 100644 (file)
@@ -10,7 +10,7 @@
     "bindings",
     "gyp"
   ],
-  "version": "0.9.5",
+  "version": "0.9.6",
   "installVersion": 9,
   "author": {
     "name": "Nathan Rajlich",
@@ -35,7 +35,7 @@
     "nopt": "2",
     "npmlog": "0",
     "osenv": "0",
-    "request": "2",
+    "request": ">= 2 && <= 2.14",
     "rimraf": "2",
     "semver": "1",
     "tar": "0",
   "engines": {
     "node": ">= 0.6.0"
   },
-  "readme": "node-gyp\n=========\n### Node.js native addon build tool\n\n`node-gyp` is a cross-platform command-line tool written in Node.js for compiling\nnative addon modules for Node.js, which takes away the pain of dealing with the\nvarious differences in build platforms. It is the replacement to the `node-waf`\nprogram which is removed for node `v0.8`. If you have a native addon for node that\nstill has a `wscript` file, then you should definitely add a `binding.gyp` file\nto support the latest versions of node.\n\nMultiple target versions of node are supported (i.e. `0.6`, `0.7`,..., `1.0`,\netc.), regardless of what version of node is actually installed on your system\n(`node-gyp` downloads the necessary development files for the target version).\n\n#### Features:\n\n * Easy to use, consistent interface\n * Same commands to build your module on every platform\n * Supports multiple target versions of Node\n\n\nInstallation\n------------\n\nYou can install with `npm`:\n\n``` bash\n$ npm install -g node-gyp\n```\n\nYou will also need to install:\n\n  * On Unix:\n    * `python`\n    * `make`\n    * A proper C/C++ compiler toolchain, like GCC\n  * On Windows:\n    * [Python][windows-python] ([`v2.7.3`][windows-python-v2.7.3] recommended, `v3.x.x` is __*not*__ supported)\n    * Windows XP/Vista/7:\n      * Microsoft Visual Studio C++ 2010 ([Express][msvc2010] version works well)\n      * For 64-bit builds of node and native modules you will _**also**_ need the [Windows 7 64-bit SDK][win7sdk]\n        * If the install fails, try uninstalling any C++ 2010 x64&x86 Redistributable that you have installed first.\n      * If you get errors that the 64-bit compilers are not installed you may also need the [compiler update for the Windows SDK 7.1]\n    * Windows 8:\n      * Microsoft Visual Studio C++ 2012 for Windows Desktop ([Express][msvc2012] version works well)\n\nNote that OS X is just a flavour of Unix and so needs `python`, `make`, and C/C++.\nAn easy way to obtain these is to install XCode from Apple,\nand then use it to install the command line tools (under Preferences -> Downloads).\n\nHow to Use\n----------\n\nTo compile your native addon, first go to its root directory:\n\n``` bash\n$ cd my_node_addon\n```\n\nThe next step is to generate the appropriate project build files for the current\nplatform. Use `configure` for that:\n\n``` bash\n$ node-gyp configure\n```\n\n__Note__: The `configure` step looks for the `binding.gyp` file in the current\ndirectory to processs. See below for instructions on creating the `binding.gyp` file.\n\nNow you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file\n(on Windows) in the `build/` directory. Next invoke the `build` command:\n\n``` bash\n$ node-gyp build\n```\n\nNow you have your compiled `.node` bindings file! The compiled bindings end up\nin `build/Debug/` or `build/Release/`, depending on the build mode. At this point\nyou can require the `.node` file with Node and run your tests!\n\n__Note:__ To create a _Debug_ build of the bindings file, pass the `--debug` (or\n`-d`) switch when running the either `configure` or `build` command.\n\n\nThe \"binding.gyp\" file\n----------------------\n\nPreviously when node had `node-waf` you had to write a `wscript` file. The\nreplacement for that is the `binding.gyp` file, which describes the configuration\nto build your module in a JSON-like format. This file gets placed in the root of\nyour package, alongside the `package.json` file.\n\nA barebones `gyp` file appropriate for building a node addon looks like:\n\n``` json\n{\n  \"targets\": [\n    {\n      \"target_name\": \"binding\",\n      \"sources\": [ \"src/binding.cc\" ]\n    }\n  ]\n}\n```\n\nSome additional resources for writing `gyp` files:\n\n * [\"Hello World\" node addon example](https://github.com/joyent/node/tree/master/test/addons/hello-world)\n * [gyp user documentation](http://code.google.com/p/gyp/wiki/GypUserDocumentation)\n * [gyp input format reference](http://code.google.com/p/gyp/wiki/InputFormatReference)\n * [*\"binding.gyp\" files out in the wild* wiki page](https://github.com/TooTallNate/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild)\n\n\nCommands\n--------\n\n`node-gyp` responds to the following commands:\n\n| **Command**   | **Description**\n|:--------------|:---------------------------------------------------------------\n| `build`       | Invokes `make`/`msbuild.exe` and builds the native addon\n| `clean`       | Removes any the `build` dir if it exists\n| `configure`   | Generates project build files for the current platform\n| `rebuild`     | Runs \"clean\", \"configure\" and \"build\" all in a row\n| `install`     | Installs node development header files for the given version\n| `list`        | Lists the currently installed node development file versions\n| `remove`      | Removes the node development header files for the given version\n\n\nLicense\n-------\n\n(The MIT License)\n\nCopyright (c) 2012 Nathan Rajlich &lt;nathan@tootallnate.net&gt;\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n[windows-python]: http://www.python.org/getit/windows\n[windows-python-v2.7.3]: http://www.python.org/download/releases/2.7.3#download\n[msvc2010]: http://go.microsoft.com/?linkid=9709949\n[msvc2012]: http://go.microsoft.com/?linkid=9816758\n[win7sdk]: http://www.microsoft.com/en-us/download/details.aspx?id=8279\n[compiler update for the Windows SDK 7.1]: http://www.microsoft.com/en-us/download/details.aspx?id=4422\n",
+  "readme": "node-gyp\n=========\n### Node.js native addon build tool\n\n`node-gyp` is a cross-platform command-line tool written in Node.js for compiling\nnative addon modules for Node.js, which takes away the pain of dealing with the\nvarious differences in build platforms. It is the replacement to the `node-waf`\nprogram which is removed for node `v0.8`. If you have a native addon for node that\nstill has a `wscript` file, then you should definitely add a `binding.gyp` file\nto support the latest versions of node.\n\nMultiple target versions of node are supported (i.e. `0.6`, `0.7`,..., `1.0`,\netc.), regardless of what version of node is actually installed on your system\n(`node-gyp` downloads the necessary development files for the target version).\n\n#### Features:\n\n * Easy to use, consistent interface\n * Same commands to build your module on every platform\n * Supports multiple target versions of Node\n\n\nInstallation\n------------\n\nYou can install with `npm`:\n\n``` bash\n$ npm install -g node-gyp\n```\n\nYou will also need to install:\n\n  * On Unix:\n    * `python` (`v2.7` recommended, `v3.x.x` is __*not*__ supported)\n    * `make`\n    * A proper C/C++ compiler toolchain, like GCC\n  * On Windows:\n    * [Python][windows-python] ([`v2.7.3`][windows-python-v2.7.3] recommended, `v3.x.x` is __*not*__ supported)\n    * Windows XP/Vista/7:\n      * Microsoft Visual Studio C++ 2010 ([Express][msvc2010] version works well)\n      * For 64-bit builds of node and native modules you will _**also**_ need the [Windows 7 64-bit SDK][win7sdk]\n        * If the install fails, try uninstalling any C++ 2010 x64&x86 Redistributable that you have installed first.\n      * If you get errors that the 64-bit compilers are not installed you may also need the [compiler update for the Windows SDK 7.1]\n    * Windows 7/8:\n      * Microsoft Visual Studio C++ 2012 for Windows Desktop ([Express][msvc2012] version works well)\n\nNote that OS X is just a flavour of Unix and so needs `python`, `make`, and C/C++.\nAn easy way to obtain these is to install XCode from Apple,\nand then use it to install the command line tools (under Preferences -> Downloads).\n\nHow to Use\n----------\n\nTo compile your native addon, first go to its root directory:\n\n``` bash\n$ cd my_node_addon\n```\n\nThe next step is to generate the appropriate project build files for the current\nplatform. Use `configure` for that:\n\n``` bash\n$ node-gyp configure\n```\n\n__Note__: The `configure` step looks for the `binding.gyp` file in the current\ndirectory to processs. See below for instructions on creating the `binding.gyp` file.\n\nNow you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file\n(on Windows) in the `build/` directory. Next invoke the `build` command:\n\n``` bash\n$ node-gyp build\n```\n\nNow you have your compiled `.node` bindings file! The compiled bindings end up\nin `build/Debug/` or `build/Release/`, depending on the build mode. At this point\nyou can require the `.node` file with Node and run your tests!\n\n__Note:__ To create a _Debug_ build of the bindings file, pass the `--debug` (or\n`-d`) switch when running the either `configure` or `build` command.\n\n\nThe \"binding.gyp\" file\n----------------------\n\nPreviously when node had `node-waf` you had to write a `wscript` file. The\nreplacement for that is the `binding.gyp` file, which describes the configuration\nto build your module in a JSON-like format. This file gets placed in the root of\nyour package, alongside the `package.json` file.\n\nA barebones `gyp` file appropriate for building a node addon looks like:\n\n``` python\n{\n  \"targets\": [\n    {\n      \"target_name\": \"binding\",\n      \"sources\": [ \"src/binding.cc\" ]\n    }\n  ]\n}\n```\n\nSome additional resources for writing `gyp` files:\n\n * [\"Hello World\" node addon example](https://github.com/joyent/node/tree/master/test/addons/hello-world)\n * [gyp user documentation](http://code.google.com/p/gyp/wiki/GypUserDocumentation)\n * [gyp input format reference](http://code.google.com/p/gyp/wiki/InputFormatReference)\n * [*\"binding.gyp\" files out in the wild* wiki page](https://github.com/TooTallNate/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild)\n\n\nCommands\n--------\n\n`node-gyp` responds to the following commands:\n\n| **Command**   | **Description**\n|:--------------|:---------------------------------------------------------------\n| `build`       | Invokes `make`/`msbuild.exe` and builds the native addon\n| `clean`       | Removes any the `build` dir if it exists\n| `configure`   | Generates project build files for the current platform\n| `rebuild`     | Runs \"clean\", \"configure\" and \"build\" all in a row\n| `install`     | Installs node development header files for the given version\n| `list`        | Lists the currently installed node development file versions\n| `remove`      | Removes the node development header files for the given version\n\n\nLicense\n-------\n\n(The MIT License)\n\nCopyright (c) 2012 Nathan Rajlich &lt;nathan@tootallnate.net&gt;\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n[windows-python]: http://www.python.org/getit/windows\n[windows-python-v2.7.3]: http://www.python.org/download/releases/2.7.3#download\n[msvc2010]: http://go.microsoft.com/?linkid=9709949\n[msvc2012]: http://go.microsoft.com/?linkid=9816758\n[win7sdk]: http://www.microsoft.com/en-us/download/details.aspx?id=8279\n[compiler update for the Windows SDK 7.1]: http://www.microsoft.com/en-us/download/details.aspx?id=4422\n",
   "readmeFilename": "README.md",
   "bugs": {
     "url": "https://github.com/TooTallNate/node-gyp/issues"
   },
-  "_id": "node-gyp@0.9.5",
-  "_from": "node-gyp@latest"
+  "_id": "node-gyp@0.9.6",
+  "_from": "node-gyp@~0.9.5"
 }
index bbada56..61738f4 100644 (file)
@@ -245,6 +245,7 @@ Object.defineProperty(exports, "defaults", {get: function () {
     , searchexclude: null
     , searchsort: "name"
     , shell : osenv.shell()
+    , shrinkwrap: true
     , "sign-git-tag": false
     , "strict-ssl": true
     , tag : "latest"
@@ -338,6 +339,7 @@ exports.types =
                 , "date", "-date"
                 , "keywords", "-keywords" ]
   , shell : String
+  , shrinkwrap: Boolean
   , "sign-git-tag": Boolean
   , "strict-ssl": Boolean
   , tag : String
index 8e38bae..e97b550 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "npmconf",
-  "version": "0.0.24",
+  "version": "0.0.25",
   "description": "The config thing npm uses",
   "main": "npmconf.js",
   "directories": {
   "bugs": {
     "url": "https://github.com/isaacs/npmconf/issues"
   },
-  "_id": "npmconf@0.0.24",
-  "_from": "npmconf@latest"
+  "_id": "npmconf@0.0.25",
+  "dist": {
+    "shasum": "8e958a7da1dd087c70a427b27d372c565b782662"
+  },
+  "_from": "npmconf@0.0.25",
+  "_resolved": "https://registry.npmjs.org/npmconf/-/npmconf-0.0.25.tgz"
 }
index c5e8b51..9ff1acf 100644 (file)
@@ -3,7 +3,7 @@
 Async is a utility module which provides straight-forward, powerful functions
 for working with asynchronous JavaScript. Although originally designed for
 use with [node.js](http://nodejs.org), it can also be used directly in the
-browser.
+browser. Also supports [component](https://github.com/component/component).
 
 Async provides around 20 functions that include the usual 'functional'
 suspects (map, reduce, filter, each…) as well as some common patterns
@@ -19,7 +19,7 @@ async.map(['file1','file2','file3'], fs.stat, function(err, results){
     // results is now an array of stats for each file
 });
 
-async.filter(['file1','file2','file3'], path.exists, function(results){
+async.filter(['file1','file2','file3'], fs.exists, function(results){
     // results now equals an array of the existing files
 });
 
@@ -310,7 +310,7 @@ __Alias:__ select
 Returns a new array of all the values which pass an async truth test.
 _The callback for each iterator call only accepts a single argument of true or
 false, it does not accept an error argument first!_ This is in-line with the
-way node libraries work with truth tests like path.exists. This operation is
+way node libraries work with truth tests like fs.exists. This operation is
 performed in parallel, but the results array will be in the same order as the
 original.
 
@@ -326,7 +326,7 @@ __Arguments__
 __Example__
 
 ```js
-async.filter(['file1','file2','file3'], path.exists, function(results){
+async.filter(['file1','file2','file3'], fs.exists, function(results){
     // results now equals an array of the existing files
 });
 ```
@@ -435,7 +435,7 @@ __Arguments__
 __Example__
 
 ```js
-async.detect(['file1','file2','file3'], path.exists, function(result){
+async.detect(['file1','file2','file3'], fs.exists, function(result){
     // result now equals the first file in the list that exists
 });
 ```
@@ -491,7 +491,7 @@ __Alias:__ any
 Returns true if at least one element in the array satisfies an async test.
 _The callback for each iterator call only accepts a single argument of true or
 false, it does not accept an error argument first!_ This is in-line with the
-way node libraries work with truth tests like path.exists. Once any iterator
+way node libraries work with truth tests like fs.exists. Once any iterator
 call returns true, the main callback is immediately called.
 
 __Arguments__
@@ -507,7 +507,7 @@ __Arguments__
 __Example__
 
 ```js
-async.some(['file1','file2','file3'], path.exists, function(result){
+async.some(['file1','file2','file3'], fs.exists, function(result){
     // if result is true then at least one of the files exists
 });
 ```
@@ -522,7 +522,7 @@ __Alias:__ all
 Returns true if every element in the array satisfies an async test.
 _The callback for each iterator call only accepts a single argument of true or
 false, it does not accept an error argument first!_ This is in-line with the
-way node libraries work with truth tests like path.exists.
+way node libraries work with truth tests like fs.exists.
 
 __Arguments__
 
@@ -537,7 +537,7 @@ __Arguments__
 __Example__
 
 ```js
-async.every(['file1','file2','file3'], path.exists, function(result){
+async.every(['file1','file2','file3'], fs.exists, function(result){
     // if result is true then every file exists
 });
 ```
diff --git a/deps/npm/node_modules/request/node_modules/form-data/node_modules/async/component.json b/deps/npm/node_modules/request/node_modules/form-data/node_modules/async/component.json
new file mode 100644 (file)
index 0000000..bbb0115
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "name": "async",
+  "repo": "caolan/async",
+  "description": "Higher-order functions and common patterns for asynchronous code",
+  "version": "0.1.23",
+  "keywords": [],
+  "dependencies": {},
+  "development": {},
+  "main": "lib/async.js",
+  "scripts": [ "lib/async.js" ]
+}
index 46f4f50..cb6320d 100755 (executable)
     //// nextTick implementation with browser-compatible fallback ////
     if (typeof process === 'undefined' || !(process.nextTick)) {
         if (typeof setImmediate === 'function') {
-            async.setImmediate = setImmediate;
-            async.nextTick = setImmediate;
+            async.nextTick = function (fn) {
+                // not a direct alias for IE10 compatibility
+                setImmediate(fn);
+            };
+            async.setImmediate = async.nextTick;
         }
         else {
             async.nextTick = function (fn) {
index f08f72e..578f9d0 100644 (file)
@@ -5,18 +5,18 @@
   "author": {
     "name": "Caolan McMahon"
   },
-  "version": "0.2.8",
+  "version": "0.2.9",
   "repository": {
     "type": "git",
-    "url": "http://github.com/caolan/async.git"
+    "url": "https://github.com/caolan/async.git"
   },
   "bugs": {
-    "url": "http://github.com/caolan/async/issues"
+    "url": "https://github.com/caolan/async/issues"
   },
   "licenses": [
     {
       "type": "MIT",
-      "url": "http://github.com/caolan/async/raw/master/LICENSE"
+      "url": "https://github.com/caolan/async/raw/master/LICENSE"
     }
   ],
   "devDependencies": {
@@ -35,8 +35,8 @@
   "scripts": {
     "test": "nodeunit test/test-async.js"
   },
-  "readme": "# Async.js\n\nAsync is a utility module which provides straight-forward, powerful functions\nfor working with asynchronous JavaScript. Although originally designed for\nuse with [node.js](http://nodejs.org), it can also be used directly in the\nbrowser.\n\nAsync provides around 20 functions that include the usual 'functional'\nsuspects (map, reduce, filter, each…) as well as some common patterns\nfor asynchronous control flow (parallel, series, waterfall…). All these\nfunctions assume you follow the node.js convention of providing a single\ncallback as the last argument of your async function.\n\n\n## Quick Examples\n\n```javascript\nasync.map(['file1','file2','file3'], fs.stat, function(err, results){\n    // results is now an array of stats for each file\n});\n\nasync.filter(['file1','file2','file3'], path.exists, function(results){\n    // results now equals an array of the existing files\n});\n\nasync.parallel([\n    function(){ ... },\n    function(){ ... }\n], callback);\n\nasync.series([\n    function(){ ... },\n    function(){ ... }\n]);\n```\n\nThere are many more functions available so take a look at the docs below for a\nfull list. This module aims to be comprehensive, so if you feel anything is\nmissing please create a GitHub issue for it.\n\n## Common Pitfalls\n\n### Binding a context to an iterator\n\nThis section is really about bind, not about async. If you are wondering how to\nmake async execute your iterators in a given context, or are confused as to why\na method of another library isn't working as an iterator, study this example:\n\n```js\n// Here is a simple object with an (unnecessarily roundabout) squaring method\nvar AsyncSquaringLibrary = {\n  squareExponent: 2,\n  square: function(number, callback){ \n    var result = Math.pow(number, this.squareExponent);\n    setTimeout(function(){\n      callback(null, result);\n    }, 200);\n  }\n};\n\nasync.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){\n  // result is [NaN, NaN, NaN]\n  // This fails because the `this.squareExponent` expression in the square\n  // function is not evaluated in the context of AsyncSquaringLibrary, and is\n  // therefore undefined.\n});\n\nasync.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){\n  // result is [1, 4, 9]\n  // With the help of bind we can attach a context to the iterator before\n  // passing it to async. Now the square function will be executed in its \n  // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent`\n  // will be as expected.\n});\n```\n\n## Download\n\nThe source is available for download from\n[GitHub](http://github.com/caolan/async).\nAlternatively, you can install using Node Package Manager (npm):\n\n    npm install async\n\n__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed\n\n## In the Browser\n\nSo far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage:\n\n```html\n<script type=\"text/javascript\" src=\"async.js\"></script>\n<script type=\"text/javascript\">\n\n    async.map(data, asyncProcess, function(err, results){\n        alert(results);\n    });\n\n</script>\n```\n\n## Documentation\n\n### Collections\n\n* [each](#each)\n* [map](#map)\n* [filter](#filter)\n* [reject](#reject)\n* [reduce](#reduce)\n* [detect](#detect)\n* [sortBy](#sortBy)\n* [some](#some)\n* [every](#every)\n* [concat](#concat)\n\n### Control Flow\n\n* [series](#series)\n* [parallel](#parallel)\n* [whilst](#whilst)\n* [doWhilst](#doWhilst)\n* [until](#until)\n* [doUntil](#doUntil)\n* [forever](#forever)\n* [waterfall](#waterfall)\n* [compose](#compose)\n* [applyEach](#applyEach)\n* [queue](#queue)\n* [cargo](#cargo)\n* [auto](#auto)\n* [iterator](#iterator)\n* [apply](#apply)\n* [nextTick](#nextTick)\n* [times](#times)\n* [timesSeries](#timesSeries)\n\n### Utils\n\n* [memoize](#memoize)\n* [unmemoize](#unmemoize)\n* [log](#log)\n* [dir](#dir)\n* [noConflict](#noConflict)\n\n\n## Collections\n\n<a name=\"forEach\" />\n<a name=\"each\" />\n### each(arr, iterator, callback)\n\nApplies an iterator function to each item in an array, in parallel.\nThe iterator is called with an item from the list and a callback for when it\nhas finished. If the iterator passes an error to this callback, the main\ncallback for the each function is immediately called with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n  The iterator is passed a callback(err) which must be called once it has \n  completed. If no error has occured, the callback should be run without \n  arguments or with an explicit null argument.\n* callback(err) - A callback which is called after all the iterator functions\n  have finished, or an error has occurred.\n\n__Example__\n\n```js\n// assuming openFiles is an array of file names and saveFile is a function\n// to save the modified contents of that file:\n\nasync.each(openFiles, saveFile, function(err){\n    // if any of the saves produced an error, err would equal that error\n});\n```\n\n---------------------------------------\n\n<a name=\"forEachSeries\" />\n<a name=\"eachSeries\" />\n### eachSeries(arr, iterator, callback)\n\nThe same as each only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. This means the iterator functions will complete in order.\n\n\n---------------------------------------\n\n<a name=\"forEachLimit\" />\n<a name=\"eachLimit\" />\n### eachLimit(arr, limit, iterator, callback)\n\nThe same as each only no more than \"limit\" iterators will be simultaneously \nrunning at any time.\n\nNote that the items are not processed in batches, so there is no guarantee that\n the first \"limit\" iterator functions will complete before any others are \nstarted.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - The maximum number of iterators to run at any time.\n* iterator(item, callback) - A function to apply to each item in the array.\n  The iterator is passed a callback(err) which must be called once it has \n  completed. If no error has occured, the callback should be run without \n  arguments or with an explicit null argument.\n* callback(err) - A callback which is called after all the iterator functions\n  have finished, or an error has occurred.\n\n__Example__\n\n```js\n// Assume documents is an array of JSON objects and requestApi is a\n// function that interacts with a rate-limited REST api.\n\nasync.eachLimit(documents, 20, requestApi, function(err){\n    // if any of the saves produced an error, err would equal that error\n});\n```\n\n---------------------------------------\n\n<a name=\"map\" />\n### map(arr, iterator, callback)\n\nProduces a new array of values by mapping each value in the given array through\nthe iterator function. The iterator is called with an item from the array and a\ncallback for when it has finished processing. The callback takes 2 arguments, \nan error and the transformed item from the array. If the iterator passes an\nerror to this callback, the main callback for the map function is immediately\ncalled with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order, however\nthe results array will be in the same order as the original array.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n  The iterator is passed a callback(err, transformed) which must be called once \n  it has completed with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n  functions have finished, or an error has occurred. Results is an array of the\n  transformed items from the original array.\n\n__Example__\n\n```js\nasync.map(['file1','file2','file3'], fs.stat, function(err, results){\n    // results is now an array of stats for each file\n});\n```\n\n---------------------------------------\n\n<a name=\"mapSeries\" />\n### mapSeries(arr, iterator, callback)\n\nThe same as map only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n---------------------------------------\n\n<a name=\"mapLimit\" />\n### mapLimit(arr, limit, iterator, callback)\n\nThe same as map only no more than \"limit\" iterators will be simultaneously \nrunning at any time.\n\nNote that the items are not processed in batches, so there is no guarantee that\n the first \"limit\" iterator functions will complete before any others are \nstarted.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - The maximum number of iterators to run at any time.\n* iterator(item, callback) - A function to apply to each item in the array.\n  The iterator is passed a callback(err, transformed) which must be called once \n  it has completed with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n  functions have finished, or an error has occurred. Results is an array of the\n  transformed items from the original array.\n\n__Example__\n\n```js\nasync.map(['file1','file2','file3'], 1, fs.stat, function(err, results){\n    // results is now an array of stats for each file\n});\n```\n\n---------------------------------------\n\n<a name=\"filter\" />\n### filter(arr, iterator, callback)\n\n__Alias:__ select\n\nReturns a new array of all the values which pass an async truth test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like path.exists. This operation is\nperformed in parallel, but the results array will be in the same order as the\noriginal.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n  The iterator is passed a callback(truthValue) which must be called with a \n  boolean argument once it has completed.\n* callback(results) - A callback which is called after all the iterator\n  functions have finished.\n\n__Example__\n\n```js\nasync.filter(['file1','file2','file3'], path.exists, function(results){\n    // results now equals an array of the existing files\n});\n```\n\n---------------------------------------\n\n<a name=\"filterSeries\" />\n### filterSeries(arr, iterator, callback)\n\n__alias:__ selectSeries\n\nThe same as filter only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n---------------------------------------\n\n<a name=\"reject\" />\n### reject(arr, iterator, callback)\n\nThe opposite of filter. Removes values that pass an async truth test.\n\n---------------------------------------\n\n<a name=\"rejectSeries\" />\n### rejectSeries(arr, iterator, callback)\n\nThe same as reject, only the iterator is applied to each item in the array\nin series.\n\n\n---------------------------------------\n\n<a name=\"reduce\" />\n### reduce(arr, memo, iterator, callback)\n\n__aliases:__ inject, foldl\n\nReduces a list of values into a single value using an async iterator to return\neach successive step. Memo is the initial state of the reduction. This\nfunction only operates in series. For performance reasons, it may make sense to\nsplit a call to this function into a parallel map, then use the normal\nArray.prototype.reduce on the results. This function is for situations where\neach step in the reduction needs to be async, if you can get the data before\nreducing it then it's probably a good idea to do so.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* memo - The initial state of the reduction.\n* iterator(memo, item, callback) - A function applied to each item in the\n  array to produce the next step in the reduction. The iterator is passed a\n  callback(err, reduction) which accepts an optional error as its first \n  argument, and the state of the reduction as the second. If an error is \n  passed to the callback, the reduction is stopped and the main callback is \n  immediately called with the error.\n* callback(err, result) - A callback which is called after all the iterator\n  functions have finished. Result is the reduced value.\n\n__Example__\n\n```js\nasync.reduce([1,2,3], 0, function(memo, item, callback){\n    // pointless async:\n    process.nextTick(function(){\n        callback(null, memo + item)\n    });\n}, function(err, result){\n    // result is now equal to the last value of memo, which is 6\n});\n```\n\n---------------------------------------\n\n<a name=\"reduceRight\" />\n### reduceRight(arr, memo, iterator, callback)\n\n__Alias:__ foldr\n\nSame as reduce, only operates on the items in the array in reverse order.\n\n\n---------------------------------------\n\n<a name=\"detect\" />\n### detect(arr, iterator, callback)\n\nReturns the first value in a list that passes an async truth test. The\niterator is applied in parallel, meaning the first iterator to return true will\nfire the detect callback with that result. That means the result might not be\nthe first item in the original array (in terms of order) that passes the test.\n\nIf order within the original array is important then look at detectSeries.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n  The iterator is passed a callback(truthValue) which must be called with a \n  boolean argument once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n  true, or after all the iterator functions have finished. Result will be\n  the first item in the array that passes the truth test (iterator) or the\n  value undefined if none passed.\n\n__Example__\n\n```js\nasync.detect(['file1','file2','file3'], path.exists, function(result){\n    // result now equals the first file in the list that exists\n});\n```\n\n---------------------------------------\n\n<a name=\"detectSeries\" />\n### detectSeries(arr, iterator, callback)\n\nThe same as detect, only the iterator is applied to each item in the array\nin series. This means the result is always the first in the original array (in\nterms of array order) that passes the truth test.\n\n\n---------------------------------------\n\n<a name=\"sortBy\" />\n### sortBy(arr, iterator, callback)\n\nSorts a list by the results of running each value through an async iterator.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n  The iterator is passed a callback(err, sortValue) which must be called once it\n  has completed with an error (which can be null) and a value to use as the sort\n  criteria.\n* callback(err, results) - A callback which is called after all the iterator\n  functions have finished, or an error has occurred. Results is the items from\n  the original array sorted by the values returned by the iterator calls.\n\n__Example__\n\n```js\nasync.sortBy(['file1','file2','file3'], function(file, callback){\n    fs.stat(file, function(err, stats){\n        callback(err, stats.mtime);\n    });\n}, function(err, results){\n    // results is now the original array of files sorted by\n    // modified date\n});\n```\n\n---------------------------------------\n\n<a name=\"some\" />\n### some(arr, iterator, callback)\n\n__Alias:__ any\n\nReturns true if at least one element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like path.exists. Once any iterator\ncall returns true, the main callback is immediately called.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n  The iterator is passed a callback(truthValue) which must be called with a \n  boolean argument once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n  true, or after all the iterator functions have finished. Result will be\n  either true or false depending on the values of the async tests.\n\n__Example__\n\n```js\nasync.some(['file1','file2','file3'], path.exists, function(result){\n    // if result is true then at least one of the files exists\n});\n```\n\n---------------------------------------\n\n<a name=\"every\" />\n### every(arr, iterator, callback)\n\n__Alias:__ all\n\nReturns true if every element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like path.exists.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n  The iterator is passed a callback(truthValue) which must be called with a \n  boolean argument once it has completed.\n* callback(result) - A callback which is called after all the iterator\n  functions have finished. Result will be either true or false depending on\n  the values of the async tests.\n\n__Example__\n\n```js\nasync.every(['file1','file2','file3'], path.exists, function(result){\n    // if result is true then every file exists\n});\n```\n\n---------------------------------------\n\n<a name=\"concat\" />\n### concat(arr, iterator, callback)\n\nApplies an iterator to each item in a list, concatenating the results. Returns the\nconcatenated list. The iterators are called in parallel, and the results are\nconcatenated as they return. There is no guarantee that the results array will\nbe returned in the original order of the arguments passed to the iterator function.\n\n__Arguments__\n\n* arr - An array to iterate over\n* iterator(item, callback) - A function to apply to each item in the array.\n  The iterator is passed a callback(err, results) which must be called once it \n  has completed with an error (which can be null) and an array of results.\n* callback(err, results) - A callback which is called after all the iterator\n  functions have finished, or an error has occurred. Results is an array containing\n  the concatenated results of the iterator function.\n\n__Example__\n\n```js\nasync.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){\n    // files is now a list of filenames that exist in the 3 directories\n});\n```\n\n---------------------------------------\n\n<a name=\"concatSeries\" />\n### concatSeries(arr, iterator, callback)\n\nSame as async.concat, but executes in series instead of parallel.\n\n\n## Control Flow\n\n<a name=\"series\" />\n### series(tasks, [callback])\n\nRun an array of functions in series, each one running once the previous\nfunction has completed. If any functions in the series pass an error to its\ncallback, no more functions are run and the callback for the series is\nimmediately called with the value of the error. Once the tasks have completed,\nthe results are passed to the final callback as an array.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.series.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed\n  a callback(err, result) it must call on completion with an error (which can\n  be null) and an optional result value.\n* callback(err, results) - An optional callback to run once all the functions\n  have completed. This function gets a results array (or object) containing all \n  the result arguments passed to the task callbacks.\n\n__Example__\n\n```js\nasync.series([\n    function(callback){\n        // do some stuff ...\n        callback(null, 'one');\n    },\n    function(callback){\n        // do some more stuff ...\n        callback(null, 'two');\n    }\n],\n// optional callback\nfunction(err, results){\n    // results is now equal to ['one', 'two']\n});\n\n\n// an example using an object instead of an array\nasync.series({\n    one: function(callback){\n        setTimeout(function(){\n            callback(null, 1);\n        }, 200);\n    },\n    two: function(callback){\n        setTimeout(function(){\n            callback(null, 2);\n        }, 100);\n    }\n},\nfunction(err, results) {\n    // results is now equal to: {one: 1, two: 2}\n});\n```\n\n---------------------------------------\n\n<a name=\"parallel\" />\n### parallel(tasks, [callback])\n\nRun an array of functions in parallel, without waiting until the previous\nfunction has completed. If any of the functions pass an error to its\ncallback, the main callback is immediately called with the value of the error.\nOnce the tasks have completed, the results are passed to the final callback as an\narray.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.parallel.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed \n  a callback(err, result) it must call on completion with an error (which can\n  be null) and an optional result value.\n* callback(err, results) - An optional callback to run once all the functions\n  have completed. This function gets a results array (or object) containing all \n  the result arguments passed to the task callbacks.\n\n__Example__\n\n```js\nasync.parallel([\n    function(callback){\n        setTimeout(function(){\n            callback(null, 'one');\n        }, 200);\n    },\n    function(callback){\n        setTimeout(function(){\n            callback(null, 'two');\n        }, 100);\n    }\n],\n// optional callback\nfunction(err, results){\n    // the results array will equal ['one','two'] even though\n    // the second function had a shorter timeout.\n});\n\n\n// an example using an object instead of an array\nasync.parallel({\n    one: function(callback){\n        setTimeout(function(){\n            callback(null, 1);\n        }, 200);\n    },\n    two: function(callback){\n        setTimeout(function(){\n            callback(null, 2);\n        }, 100);\n    }\n},\nfunction(err, results) {\n    // results is now equals to: {one: 1, two: 2}\n});\n```\n\n---------------------------------------\n\n<a name=\"parallel\" />\n### parallelLimit(tasks, limit, [callback])\n\nThe same as parallel only the tasks are executed in parallel with a maximum of \"limit\" \ntasks executing at any time.\n\nNote that the tasks are not executed in batches, so there is no guarantee that \nthe first \"limit\" tasks will complete before any others are started.\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed \n  a callback(err, result) it must call on completion with an error (which can\n  be null) and an optional result value.\n* limit - The maximum number of tasks to run at any time.\n* callback(err, results) - An optional callback to run once all the functions\n  have completed. This function gets a results array (or object) containing all \n  the result arguments passed to the task callbacks.\n\n---------------------------------------\n\n<a name=\"whilst\" />\n### whilst(test, fn, callback)\n\nRepeatedly call fn, while test returns true. Calls the callback when stopped,\nor an error occurs.\n\n__Arguments__\n\n* test() - synchronous truth test to perform before each execution of fn.\n* fn(callback) - A function to call each time the test passes. The function is\n  passed a callback(err) which must be called once it has completed with an \n  optional error argument.\n* callback(err) - A callback which is called after the test fails and repeated\n  execution of fn has stopped.\n\n__Example__\n\n```js\nvar count = 0;\n\nasync.whilst(\n    function () { return count < 5; },\n    function (callback) {\n        count++;\n        setTimeout(callback, 1000);\n    },\n    function (err) {\n        // 5 seconds have passed\n    }\n);\n```\n\n---------------------------------------\n\n<a name=\"doWhilst\" />\n### doWhilst(fn, test, callback)\n\nThe post check version of whilst. To reflect the difference in the order of operations `test` and `fn` arguments are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.\n\n---------------------------------------\n\n<a name=\"until\" />\n### until(test, fn, callback)\n\nRepeatedly call fn, until test returns true. Calls the callback when stopped,\nor an error occurs.\n\nThe inverse of async.whilst.\n\n---------------------------------------\n\n<a name=\"doUntil\" />\n### doUntil(fn, test, callback)\n\nLike doWhilst except the test is inverted. Note the argument ordering differs from `until`.\n\n---------------------------------------\n\n<a name=\"forever\" />\n### forever(fn, callback)\n\nCalls the asynchronous function 'fn' repeatedly, in series, indefinitely.\nIf an error is passed to fn's callback then 'callback' is called with the\nerror, otherwise it will never be called.\n\n---------------------------------------\n\n<a name=\"waterfall\" />\n### waterfall(tasks, [callback])\n\nRuns an array of functions in series, each passing their results to the next in\nthe array. However, if any of the functions pass an error to the callback, the\nnext function is not executed and the main callback is immediately called with\nthe error.\n\n__Arguments__\n\n* tasks - An array of functions to run, each function is passed a \n  callback(err, result1, result2, ...) it must call on completion. The first\n  argument is an error (which can be null) and any further arguments will be \n  passed as arguments in order to the next task.\n* callback(err, [results]) - An optional callback to run once all the functions\n  have completed. This will be passed the results of the last task's callback.\n\n\n\n__Example__\n\n```js\nasync.waterfall([\n    function(callback){\n        callback(null, 'one', 'two');\n    },\n    function(arg1, arg2, callback){\n        callback(null, 'three');\n    },\n    function(arg1, callback){\n        // arg1 now equals 'three'\n        callback(null, 'done');\n    }\n], function (err, result) {\n   // result now equals 'done'    \n});\n```\n\n---------------------------------------\n<a name=\"compose\" />\n### compose(fn1, fn2...)\n\nCreates a function which is a composition of the passed asynchronous\nfunctions. Each function consumes the return value of the function that\nfollows. Composing functions f(), g() and h() would produce the result of\nf(g(h())), only this version uses callbacks to obtain the return values.\n\nEach function is executed with the `this` binding of the composed function.\n\n__Arguments__\n\n* functions... - the asynchronous functions to compose\n\n\n__Example__\n\n```js\nfunction add1(n, callback) {\n    setTimeout(function () {\n        callback(null, n + 1);\n    }, 10);\n}\n\nfunction mul3(n, callback) {\n    setTimeout(function () {\n        callback(null, n * 3);\n    }, 10);\n}\n\nvar add1mul3 = async.compose(mul3, add1);\n\nadd1mul3(4, function (err, result) {\n   // result now equals 15\n});\n```\n\n---------------------------------------\n<a name=\"applyEach\" />\n### applyEach(fns, args..., callback)\n\nApplies the provided arguments to each function in the array, calling the\ncallback after all functions have completed. If you only provide the first\nargument then it will return a function which lets you pass in the\narguments as if it were a single function call.\n\n__Arguments__\n\n* fns - the asynchronous functions to all call with the same arguments\n* args... - any number of separate arguments to pass to the function\n* callback - the final argument should be the callback, called when all\n  functions have completed processing\n\n\n__Example__\n\n```js\nasync.applyEach([enableSearch, updateSchema], 'bucket', callback);\n\n// partial application example:\nasync.each(\n    buckets,\n    async.applyEach([enableSearch, updateSchema]),\n    callback\n);\n```\n\n---------------------------------------\n\n<a name=\"applyEachSeries\" />\n### applyEachSeries(arr, iterator, callback)\n\nThe same as applyEach only the functions are applied in series.\n\n---------------------------------------\n\n<a name=\"queue\" />\n### queue(worker, concurrency)\n\nCreates a queue object with the specified concurrency. Tasks added to the\nqueue will be processed in parallel (up to the concurrency limit). If all\nworkers are in progress, the task is queued until one is available. Once\na worker has completed a task, the task's callback is called.\n\n__Arguments__\n\n* worker(task, callback) - An asynchronous function for processing a queued\n  task, which must call its callback(err) argument when finished, with an \n  optional error as an argument.\n* concurrency - An integer for determining how many worker functions should be\n  run in parallel.\n\n__Queue objects__\n\nThe queue object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* concurrency - an integer for determining how many worker functions should be\n  run in parallel. This property can be changed after a queue is created to\n  alter the concurrency on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n  once the worker has finished processing the task.\n  instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* unshift(task, [callback]) - add a new task to the front of the queue.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n```js\n// create a queue object with concurrency 2\n\nvar q = async.queue(function (task, callback) {\n    console.log('hello ' + task.name);\n    callback();\n}, 2);\n\n\n// assign a callback\nq.drain = function() {\n    console.log('all items have been processed');\n}\n\n// add some items to the queue\n\nq.push({name: 'foo'}, function (err) {\n    console.log('finished processing foo');\n});\nq.push({name: 'bar'}, function (err) {\n    console.log('finished processing bar');\n});\n\n// add some items to the queue (batch-wise)\n\nq.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {\n    console.log('finished processing bar');\n});\n\n// add some items to the front of the queue\n\nq.unshift({name: 'bar'}, function (err) {\n    console.log('finished processing bar');\n});\n```\n\n---------------------------------------\n\n<a name=\"cargo\" />\n### cargo(worker, [payload])\n\nCreates a cargo object with the specified payload. Tasks added to the\ncargo will be processed altogether (up to the payload limit). If the\nworker is in progress, the task is queued until it is available. Once\nthe worker has completed some tasks, each callback of those tasks is called.\n\n__Arguments__\n\n* worker(tasks, callback) - An asynchronous function for processing an array of\n  queued tasks, which must call its callback(err) argument when finished, with \n  an optional error as an argument.\n* payload - An optional integer for determining how many tasks should be\n  processed per round; if omitted, the default is unlimited.\n\n__Cargo objects__\n\nThe cargo object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* payload - an integer for determining how many tasks should be\n  process per round. This property can be changed after a cargo is created to\n  alter the payload on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n  once the worker has finished processing the task.\n  instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n```js\n// create a cargo object with payload 2\n\nvar cargo = async.cargo(function (tasks, callback) {\n    for(var i=0; i<tasks.length; i++){\n      console.log('hello ' + tasks[i].name);\n    }\n    callback();\n}, 2);\n\n\n// add some items\n\ncargo.push({name: 'foo'}, function (err) {\n    console.log('finished processing foo');\n});\ncargo.push({name: 'bar'}, function (err) {\n    console.log('finished processing bar');\n});\ncargo.push({name: 'baz'}, function (err) {\n    console.log('finished processing baz');\n});\n```\n\n---------------------------------------\n\n<a name=\"auto\" />\n### auto(tasks, [callback])\n\nDetermines the best order for running functions based on their requirements.\nEach function can optionally depend on other functions being completed first,\nand each function is run as soon as its requirements are satisfied. If any of\nthe functions pass an error to their callback, that function will not complete\n(so any other functions depending on it will not run) and the main callback\nwill be called immediately with the error. Functions also receive an object\ncontaining the results of functions which have completed so far.\n\nNote, all functions are called with a results object as a second argument, \nso it is unsafe to pass functions in the tasks object which cannot handle the\nextra argument. For example, this snippet of code:\n\n```js\nasync.auto({\n  readData: async.apply(fs.readFile, 'data.txt', 'utf-8');\n}, callback);\n```\n\nwill have the effect of calling readFile with the results object as the last\nargument, which will fail:\n\n```js\nfs.readFile('data.txt', 'utf-8', cb, {});\n```\n\nInstead, wrap the call to readFile in a function which does not forward the \nresults object:\n\n```js\nasync.auto({\n  readData: function(cb, results){\n    fs.readFile('data.txt', 'utf-8', cb);\n  }\n}, callback);\n```\n\n__Arguments__\n\n* tasks - An object literal containing named functions or an array of\n  requirements, with the function itself the last item in the array. The key\n  used for each function or array is used when specifying requirements. The \n  function receives two arguments: (1) a callback(err, result) which must be \n  called when finished, passing an error (which can be null) and the result of \n  the function's execution, and (2) a results object, containing the results of\n  the previously executed functions.\n* callback(err, results) - An optional callback which is called when all the\n  tasks have been completed. The callback will receive an error as an argument\n  if any tasks pass an error to their callback. Results will always be passed\n\tbut if an error occurred, no other tasks will be performed, and the results\n\tobject will only contain partial results.\n  \n\n__Example__\n\n```js\nasync.auto({\n    get_data: function(callback){\n        // async code to get some data\n    },\n    make_folder: function(callback){\n        // async code to create a directory to store a file in\n        // this is run at the same time as getting the data\n    },\n    write_file: ['get_data', 'make_folder', function(callback){\n        // once there is some data and the directory exists,\n        // write the data to a file in the directory\n        callback(null, filename);\n    }],\n    email_link: ['write_file', function(callback, results){\n        // once the file is written let's email a link to it...\n        // results.write_file contains the filename returned by write_file.\n    }]\n});\n```\n\nThis is a fairly trivial example, but to do this using the basic parallel and\nseries functions would look like this:\n\n```js\nasync.parallel([\n    function(callback){\n        // async code to get some data\n    },\n    function(callback){\n        // async code to create a directory to store a file in\n        // this is run at the same time as getting the data\n    }\n],\nfunction(err, results){\n    async.series([\n        function(callback){\n            // once there is some data and the directory exists,\n            // write the data to a file in the directory\n        },\n        function(callback){\n            // once the file is written let's email a link to it...\n        }\n    ]);\n});\n```\n\nFor a complicated series of async tasks using the auto function makes adding\nnew tasks much easier and makes the code more readable.\n\n\n---------------------------------------\n\n<a name=\"iterator\" />\n### iterator(tasks)\n\nCreates an iterator function which calls the next function in the array,\nreturning a continuation to call the next one after that. It's also possible to\n'peek' the next iterator by doing iterator.next().\n\nThis function is used internally by the async module but can be useful when\nyou want to manually control the flow of functions in series.\n\n__Arguments__\n\n* tasks - An array of functions to run.\n\n__Example__\n\n```js\nvar iterator = async.iterator([\n    function(){ sys.p('one'); },\n    function(){ sys.p('two'); },\n    function(){ sys.p('three'); }\n]);\n\nnode> var iterator2 = iterator();\n'one'\nnode> var iterator3 = iterator2();\n'two'\nnode> iterator3();\n'three'\nnode> var nextfn = iterator2.next();\nnode> nextfn();\n'three'\n```\n\n---------------------------------------\n\n<a name=\"apply\" />\n### apply(function, arguments..)\n\nCreates a continuation function with some arguments already applied, a useful\nshorthand when combined with other control flow functions. Any arguments\npassed to the returned function are added to the arguments originally passed\nto apply.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to automatically apply when the\n  continuation is called.\n\n__Example__\n\n```js\n// using apply\n\nasync.parallel([\n    async.apply(fs.writeFile, 'testfile1', 'test1'),\n    async.apply(fs.writeFile, 'testfile2', 'test2'),\n]);\n\n\n// the same process without using apply\n\nasync.parallel([\n    function(callback){\n        fs.writeFile('testfile1', 'test1', callback);\n    },\n    function(callback){\n        fs.writeFile('testfile2', 'test2', callback);\n    }\n]);\n```\n\nIt's possible to pass any number of additional arguments when calling the\ncontinuation:\n\n```js\nnode> var fn = async.apply(sys.puts, 'one');\nnode> fn('two', 'three');\none\ntwo\nthree\n```\n\n---------------------------------------\n\n<a name=\"nextTick\" />\n### nextTick(callback)\n\nCalls the callback on a later loop around the event loop. In node.js this just\ncalls process.nextTick, in the browser it falls back to setImmediate(callback)\nif available, otherwise setTimeout(callback, 0), which means other higher priority\nevents may precede the execution of the callback.\n\nThis is used internally for browser-compatibility purposes.\n\n__Arguments__\n\n* callback - The function to call on a later loop around the event loop.\n\n__Example__\n\n```js\nvar call_order = [];\nasync.nextTick(function(){\n    call_order.push('two');\n    // call_order now equals ['one','two']\n});\ncall_order.push('one')\n```\n\n<a name=\"times\" />\n### times(n, callback)\n\nCalls the callback n times and accumulates results in the same manner\nyou would use with async.map.\n\n__Arguments__\n\n* n - The number of times to run the function.\n* callback - The function to call n times.\n\n__Example__\n\n```js\n// Pretend this is some complicated async factory\nvar createUser = function(id, callback) {\n  callback(null, {\n    id: 'user' + id\n  })\n}\n// generate 5 users\nasync.times(5, function(n, next){\n    createUser(n, function(err, user) {\n      next(err, user)\n    })\n}, function(err, users) {\n  // we should now have 5 users\n});\n```\n\n<a name=\"timesSeries\" />\n### timesSeries(n, callback)\n\nThe same as times only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n## Utils\n\n<a name=\"memoize\" />\n### memoize(fn, [hasher])\n\nCaches the results of an async function. When creating a hash to store function\nresults against, the callback is omitted from the hash and an optional hash\nfunction can be used.\n\nThe cache of results is exposed as the `memo` property of the function returned\nby `memoize`.\n\n__Arguments__\n\n* fn - the function you to proxy and cache results from.\n* hasher - an optional function for generating a custom hash for storing\n  results, it has all the arguments applied to it apart from the callback, and\n  must be synchronous.\n\n__Example__\n\n```js\nvar slow_fn = function (name, callback) {\n    // do something\n    callback(null, result);\n};\nvar fn = async.memoize(slow_fn);\n\n// fn can now be used as if it were slow_fn\nfn('some name', function () {\n    // callback\n});\n```\n\n<a name=\"unmemoize\" />\n### unmemoize(fn)\n\nUndoes a memoized function, reverting it to the original, unmemoized\nform. Comes handy in tests.\n\n__Arguments__\n\n* fn - the memoized function\n\n<a name=\"log\" />\n### log(function, arguments)\n\nLogs the result of an async function to the console. Only works in node.js or\nin browsers that support console.log and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.log is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n```js\nvar hello = function(name, callback){\n    setTimeout(function(){\n        callback(null, 'hello ' + name);\n    }, 1000);\n};\n```\n```js\nnode> async.log(hello, 'world');\n'hello world'\n```\n\n---------------------------------------\n\n<a name=\"dir\" />\n### dir(function, arguments)\n\nLogs the result of an async function to the console using console.dir to\ndisplay the properties of the resulting object. Only works in node.js or\nin browsers that support console.dir and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.dir is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n```js\nvar hello = function(name, callback){\n    setTimeout(function(){\n        callback(null, {hello: name});\n    }, 1000);\n};\n```\n```js\nnode> async.dir(hello, 'world');\n{hello: 'world'}\n```\n\n---------------------------------------\n\n<a name=\"noConflict\" />\n### noConflict()\n\nChanges the value of async back to its original value, returning a reference to the\nasync object.\n",
+  "readme": "# Async.js\n\nAsync is a utility module which provides straight-forward, powerful functions\nfor working with asynchronous JavaScript. Although originally designed for\nuse with [node.js](http://nodejs.org), it can also be used directly in the\nbrowser. Also supports [component](https://github.com/component/component).\n\nAsync provides around 20 functions that include the usual 'functional'\nsuspects (map, reduce, filter, each…) as well as some common patterns\nfor asynchronous control flow (parallel, series, waterfall…). All these\nfunctions assume you follow the node.js convention of providing a single\ncallback as the last argument of your async function.\n\n\n## Quick Examples\n\n```javascript\nasync.map(['file1','file2','file3'], fs.stat, function(err, results){\n    // results is now an array of stats for each file\n});\n\nasync.filter(['file1','file2','file3'], fs.exists, function(results){\n    // results now equals an array of the existing files\n});\n\nasync.parallel([\n    function(){ ... },\n    function(){ ... }\n], callback);\n\nasync.series([\n    function(){ ... },\n    function(){ ... }\n]);\n```\n\nThere are many more functions available so take a look at the docs below for a\nfull list. This module aims to be comprehensive, so if you feel anything is\nmissing please create a GitHub issue for it.\n\n## Common Pitfalls\n\n### Binding a context to an iterator\n\nThis section is really about bind, not about async. If you are wondering how to\nmake async execute your iterators in a given context, or are confused as to why\na method of another library isn't working as an iterator, study this example:\n\n```js\n// Here is a simple object with an (unnecessarily roundabout) squaring method\nvar AsyncSquaringLibrary = {\n  squareExponent: 2,\n  square: function(number, callback){ \n    var result = Math.pow(number, this.squareExponent);\n    setTimeout(function(){\n      callback(null, result);\n    }, 200);\n  }\n};\n\nasync.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){\n  // result is [NaN, NaN, NaN]\n  // This fails because the `this.squareExponent` expression in the square\n  // function is not evaluated in the context of AsyncSquaringLibrary, and is\n  // therefore undefined.\n});\n\nasync.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){\n  // result is [1, 4, 9]\n  // With the help of bind we can attach a context to the iterator before\n  // passing it to async. Now the square function will be executed in its \n  // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent`\n  // will be as expected.\n});\n```\n\n## Download\n\nThe source is available for download from\n[GitHub](http://github.com/caolan/async).\nAlternatively, you can install using Node Package Manager (npm):\n\n    npm install async\n\n__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed\n\n## In the Browser\n\nSo far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage:\n\n```html\n<script type=\"text/javascript\" src=\"async.js\"></script>\n<script type=\"text/javascript\">\n\n    async.map(data, asyncProcess, function(err, results){\n        alert(results);\n    });\n\n</script>\n```\n\n## Documentation\n\n### Collections\n\n* [each](#each)\n* [map](#map)\n* [filter](#filter)\n* [reject](#reject)\n* [reduce](#reduce)\n* [detect](#detect)\n* [sortBy](#sortBy)\n* [some](#some)\n* [every](#every)\n* [concat](#concat)\n\n### Control Flow\n\n* [series](#series)\n* [parallel](#parallel)\n* [whilst](#whilst)\n* [doWhilst](#doWhilst)\n* [until](#until)\n* [doUntil](#doUntil)\n* [forever](#forever)\n* [waterfall](#waterfall)\n* [compose](#compose)\n* [applyEach](#applyEach)\n* [queue](#queue)\n* [cargo](#cargo)\n* [auto](#auto)\n* [iterator](#iterator)\n* [apply](#apply)\n* [nextTick](#nextTick)\n* [times](#times)\n* [timesSeries](#timesSeries)\n\n### Utils\n\n* [memoize](#memoize)\n* [unmemoize](#unmemoize)\n* [log](#log)\n* [dir](#dir)\n* [noConflict](#noConflict)\n\n\n## Collections\n\n<a name=\"forEach\" />\n<a name=\"each\" />\n### each(arr, iterator, callback)\n\nApplies an iterator function to each item in an array, in parallel.\nThe iterator is called with an item from the list and a callback for when it\nhas finished. If the iterator passes an error to this callback, the main\ncallback for the each function is immediately called with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n  The iterator is passed a callback(err) which must be called once it has \n  completed. If no error has occured, the callback should be run without \n  arguments or with an explicit null argument.\n* callback(err) - A callback which is called after all the iterator functions\n  have finished, or an error has occurred.\n\n__Example__\n\n```js\n// assuming openFiles is an array of file names and saveFile is a function\n// to save the modified contents of that file:\n\nasync.each(openFiles, saveFile, function(err){\n    // if any of the saves produced an error, err would equal that error\n});\n```\n\n---------------------------------------\n\n<a name=\"forEachSeries\" />\n<a name=\"eachSeries\" />\n### eachSeries(arr, iterator, callback)\n\nThe same as each only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. This means the iterator functions will complete in order.\n\n\n---------------------------------------\n\n<a name=\"forEachLimit\" />\n<a name=\"eachLimit\" />\n### eachLimit(arr, limit, iterator, callback)\n\nThe same as each only no more than \"limit\" iterators will be simultaneously \nrunning at any time.\n\nNote that the items are not processed in batches, so there is no guarantee that\n the first \"limit\" iterator functions will complete before any others are \nstarted.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - The maximum number of iterators to run at any time.\n* iterator(item, callback) - A function to apply to each item in the array.\n  The iterator is passed a callback(err) which must be called once it has \n  completed. If no error has occured, the callback should be run without \n  arguments or with an explicit null argument.\n* callback(err) - A callback which is called after all the iterator functions\n  have finished, or an error has occurred.\n\n__Example__\n\n```js\n// Assume documents is an array of JSON objects and requestApi is a\n// function that interacts with a rate-limited REST api.\n\nasync.eachLimit(documents, 20, requestApi, function(err){\n    // if any of the saves produced an error, err would equal that error\n});\n```\n\n---------------------------------------\n\n<a name=\"map\" />\n### map(arr, iterator, callback)\n\nProduces a new array of values by mapping each value in the given array through\nthe iterator function. The iterator is called with an item from the array and a\ncallback for when it has finished processing. The callback takes 2 arguments, \nan error and the transformed item from the array. If the iterator passes an\nerror to this callback, the main callback for the map function is immediately\ncalled with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order, however\nthe results array will be in the same order as the original array.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n  The iterator is passed a callback(err, transformed) which must be called once \n  it has completed with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n  functions have finished, or an error has occurred. Results is an array of the\n  transformed items from the original array.\n\n__Example__\n\n```js\nasync.map(['file1','file2','file3'], fs.stat, function(err, results){\n    // results is now an array of stats for each file\n});\n```\n\n---------------------------------------\n\n<a name=\"mapSeries\" />\n### mapSeries(arr, iterator, callback)\n\nThe same as map only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n---------------------------------------\n\n<a name=\"mapLimit\" />\n### mapLimit(arr, limit, iterator, callback)\n\nThe same as map only no more than \"limit\" iterators will be simultaneously \nrunning at any time.\n\nNote that the items are not processed in batches, so there is no guarantee that\n the first \"limit\" iterator functions will complete before any others are \nstarted.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - The maximum number of iterators to run at any time.\n* iterator(item, callback) - A function to apply to each item in the array.\n  The iterator is passed a callback(err, transformed) which must be called once \n  it has completed with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n  functions have finished, or an error has occurred. Results is an array of the\n  transformed items from the original array.\n\n__Example__\n\n```js\nasync.map(['file1','file2','file3'], 1, fs.stat, function(err, results){\n    // results is now an array of stats for each file\n});\n```\n\n---------------------------------------\n\n<a name=\"filter\" />\n### filter(arr, iterator, callback)\n\n__Alias:__ select\n\nReturns a new array of all the values which pass an async truth test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like fs.exists. This operation is\nperformed in parallel, but the results array will be in the same order as the\noriginal.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n  The iterator is passed a callback(truthValue) which must be called with a \n  boolean argument once it has completed.\n* callback(results) - A callback which is called after all the iterator\n  functions have finished.\n\n__Example__\n\n```js\nasync.filter(['file1','file2','file3'], fs.exists, function(results){\n    // results now equals an array of the existing files\n});\n```\n\n---------------------------------------\n\n<a name=\"filterSeries\" />\n### filterSeries(arr, iterator, callback)\n\n__alias:__ selectSeries\n\nThe same as filter only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n---------------------------------------\n\n<a name=\"reject\" />\n### reject(arr, iterator, callback)\n\nThe opposite of filter. Removes values that pass an async truth test.\n\n---------------------------------------\n\n<a name=\"rejectSeries\" />\n### rejectSeries(arr, iterator, callback)\n\nThe same as reject, only the iterator is applied to each item in the array\nin series.\n\n\n---------------------------------------\n\n<a name=\"reduce\" />\n### reduce(arr, memo, iterator, callback)\n\n__aliases:__ inject, foldl\n\nReduces a list of values into a single value using an async iterator to return\neach successive step. Memo is the initial state of the reduction. This\nfunction only operates in series. For performance reasons, it may make sense to\nsplit a call to this function into a parallel map, then use the normal\nArray.prototype.reduce on the results. This function is for situations where\neach step in the reduction needs to be async, if you can get the data before\nreducing it then it's probably a good idea to do so.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* memo - The initial state of the reduction.\n* iterator(memo, item, callback) - A function applied to each item in the\n  array to produce the next step in the reduction. The iterator is passed a\n  callback(err, reduction) which accepts an optional error as its first \n  argument, and the state of the reduction as the second. If an error is \n  passed to the callback, the reduction is stopped and the main callback is \n  immediately called with the error.\n* callback(err, result) - A callback which is called after all the iterator\n  functions have finished. Result is the reduced value.\n\n__Example__\n\n```js\nasync.reduce([1,2,3], 0, function(memo, item, callback){\n    // pointless async:\n    process.nextTick(function(){\n        callback(null, memo + item)\n    });\n}, function(err, result){\n    // result is now equal to the last value of memo, which is 6\n});\n```\n\n---------------------------------------\n\n<a name=\"reduceRight\" />\n### reduceRight(arr, memo, iterator, callback)\n\n__Alias:__ foldr\n\nSame as reduce, only operates on the items in the array in reverse order.\n\n\n---------------------------------------\n\n<a name=\"detect\" />\n### detect(arr, iterator, callback)\n\nReturns the first value in a list that passes an async truth test. The\niterator is applied in parallel, meaning the first iterator to return true will\nfire the detect callback with that result. That means the result might not be\nthe first item in the original array (in terms of order) that passes the test.\n\nIf order within the original array is important then look at detectSeries.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n  The iterator is passed a callback(truthValue) which must be called with a \n  boolean argument once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n  true, or after all the iterator functions have finished. Result will be\n  the first item in the array that passes the truth test (iterator) or the\n  value undefined if none passed.\n\n__Example__\n\n```js\nasync.detect(['file1','file2','file3'], fs.exists, function(result){\n    // result now equals the first file in the list that exists\n});\n```\n\n---------------------------------------\n\n<a name=\"detectSeries\" />\n### detectSeries(arr, iterator, callback)\n\nThe same as detect, only the iterator is applied to each item in the array\nin series. This means the result is always the first in the original array (in\nterms of array order) that passes the truth test.\n\n\n---------------------------------------\n\n<a name=\"sortBy\" />\n### sortBy(arr, iterator, callback)\n\nSorts a list by the results of running each value through an async iterator.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n  The iterator is passed a callback(err, sortValue) which must be called once it\n  has completed with an error (which can be null) and a value to use as the sort\n  criteria.\n* callback(err, results) - A callback which is called after all the iterator\n  functions have finished, or an error has occurred. Results is the items from\n  the original array sorted by the values returned by the iterator calls.\n\n__Example__\n\n```js\nasync.sortBy(['file1','file2','file3'], function(file, callback){\n    fs.stat(file, function(err, stats){\n        callback(err, stats.mtime);\n    });\n}, function(err, results){\n    // results is now the original array of files sorted by\n    // modified date\n});\n```\n\n---------------------------------------\n\n<a name=\"some\" />\n### some(arr, iterator, callback)\n\n__Alias:__ any\n\nReturns true if at least one element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like fs.exists. Once any iterator\ncall returns true, the main callback is immediately called.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n  The iterator is passed a callback(truthValue) which must be called with a \n  boolean argument once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n  true, or after all the iterator functions have finished. Result will be\n  either true or false depending on the values of the async tests.\n\n__Example__\n\n```js\nasync.some(['file1','file2','file3'], fs.exists, function(result){\n    // if result is true then at least one of the files exists\n});\n```\n\n---------------------------------------\n\n<a name=\"every\" />\n### every(arr, iterator, callback)\n\n__Alias:__ all\n\nReturns true if every element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like fs.exists.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n  The iterator is passed a callback(truthValue) which must be called with a \n  boolean argument once it has completed.\n* callback(result) - A callback which is called after all the iterator\n  functions have finished. Result will be either true or false depending on\n  the values of the async tests.\n\n__Example__\n\n```js\nasync.every(['file1','file2','file3'], fs.exists, function(result){\n    // if result is true then every file exists\n});\n```\n\n---------------------------------------\n\n<a name=\"concat\" />\n### concat(arr, iterator, callback)\n\nApplies an iterator to each item in a list, concatenating the results. Returns the\nconcatenated list. The iterators are called in parallel, and the results are\nconcatenated as they return. There is no guarantee that the results array will\nbe returned in the original order of the arguments passed to the iterator function.\n\n__Arguments__\n\n* arr - An array to iterate over\n* iterator(item, callback) - A function to apply to each item in the array.\n  The iterator is passed a callback(err, results) which must be called once it \n  has completed with an error (which can be null) and an array of results.\n* callback(err, results) - A callback which is called after all the iterator\n  functions have finished, or an error has occurred. Results is an array containing\n  the concatenated results of the iterator function.\n\n__Example__\n\n```js\nasync.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){\n    // files is now a list of filenames that exist in the 3 directories\n});\n```\n\n---------------------------------------\n\n<a name=\"concatSeries\" />\n### concatSeries(arr, iterator, callback)\n\nSame as async.concat, but executes in series instead of parallel.\n\n\n## Control Flow\n\n<a name=\"series\" />\n### series(tasks, [callback])\n\nRun an array of functions in series, each one running once the previous\nfunction has completed. If any functions in the series pass an error to its\ncallback, no more functions are run and the callback for the series is\nimmediately called with the value of the error. Once the tasks have completed,\nthe results are passed to the final callback as an array.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.series.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed\n  a callback(err, result) it must call on completion with an error (which can\n  be null) and an optional result value.\n* callback(err, results) - An optional callback to run once all the functions\n  have completed. This function gets a results array (or object) containing all \n  the result arguments passed to the task callbacks.\n\n__Example__\n\n```js\nasync.series([\n    function(callback){\n        // do some stuff ...\n        callback(null, 'one');\n    },\n    function(callback){\n        // do some more stuff ...\n        callback(null, 'two');\n    }\n],\n// optional callback\nfunction(err, results){\n    // results is now equal to ['one', 'two']\n});\n\n\n// an example using an object instead of an array\nasync.series({\n    one: function(callback){\n        setTimeout(function(){\n            callback(null, 1);\n        }, 200);\n    },\n    two: function(callback){\n        setTimeout(function(){\n            callback(null, 2);\n        }, 100);\n    }\n},\nfunction(err, results) {\n    // results is now equal to: {one: 1, two: 2}\n});\n```\n\n---------------------------------------\n\n<a name=\"parallel\" />\n### parallel(tasks, [callback])\n\nRun an array of functions in parallel, without waiting until the previous\nfunction has completed. If any of the functions pass an error to its\ncallback, the main callback is immediately called with the value of the error.\nOnce the tasks have completed, the results are passed to the final callback as an\narray.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.parallel.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed \n  a callback(err, result) it must call on completion with an error (which can\n  be null) and an optional result value.\n* callback(err, results) - An optional callback to run once all the functions\n  have completed. This function gets a results array (or object) containing all \n  the result arguments passed to the task callbacks.\n\n__Example__\n\n```js\nasync.parallel([\n    function(callback){\n        setTimeout(function(){\n            callback(null, 'one');\n        }, 200);\n    },\n    function(callback){\n        setTimeout(function(){\n            callback(null, 'two');\n        }, 100);\n    }\n],\n// optional callback\nfunction(err, results){\n    // the results array will equal ['one','two'] even though\n    // the second function had a shorter timeout.\n});\n\n\n// an example using an object instead of an array\nasync.parallel({\n    one: function(callback){\n        setTimeout(function(){\n            callback(null, 1);\n        }, 200);\n    },\n    two: function(callback){\n        setTimeout(function(){\n            callback(null, 2);\n        }, 100);\n    }\n},\nfunction(err, results) {\n    // results is now equals to: {one: 1, two: 2}\n});\n```\n\n---------------------------------------\n\n<a name=\"parallel\" />\n### parallelLimit(tasks, limit, [callback])\n\nThe same as parallel only the tasks are executed in parallel with a maximum of \"limit\" \ntasks executing at any time.\n\nNote that the tasks are not executed in batches, so there is no guarantee that \nthe first \"limit\" tasks will complete before any others are started.\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed \n  a callback(err, result) it must call on completion with an error (which can\n  be null) and an optional result value.\n* limit - The maximum number of tasks to run at any time.\n* callback(err, results) - An optional callback to run once all the functions\n  have completed. This function gets a results array (or object) containing all \n  the result arguments passed to the task callbacks.\n\n---------------------------------------\n\n<a name=\"whilst\" />\n### whilst(test, fn, callback)\n\nRepeatedly call fn, while test returns true. Calls the callback when stopped,\nor an error occurs.\n\n__Arguments__\n\n* test() - synchronous truth test to perform before each execution of fn.\n* fn(callback) - A function to call each time the test passes. The function is\n  passed a callback(err) which must be called once it has completed with an \n  optional error argument.\n* callback(err) - A callback which is called after the test fails and repeated\n  execution of fn has stopped.\n\n__Example__\n\n```js\nvar count = 0;\n\nasync.whilst(\n    function () { return count < 5; },\n    function (callback) {\n        count++;\n        setTimeout(callback, 1000);\n    },\n    function (err) {\n        // 5 seconds have passed\n    }\n);\n```\n\n---------------------------------------\n\n<a name=\"doWhilst\" />\n### doWhilst(fn, test, callback)\n\nThe post check version of whilst. To reflect the difference in the order of operations `test` and `fn` arguments are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.\n\n---------------------------------------\n\n<a name=\"until\" />\n### until(test, fn, callback)\n\nRepeatedly call fn, until test returns true. Calls the callback when stopped,\nor an error occurs.\n\nThe inverse of async.whilst.\n\n---------------------------------------\n\n<a name=\"doUntil\" />\n### doUntil(fn, test, callback)\n\nLike doWhilst except the test is inverted. Note the argument ordering differs from `until`.\n\n---------------------------------------\n\n<a name=\"forever\" />\n### forever(fn, callback)\n\nCalls the asynchronous function 'fn' repeatedly, in series, indefinitely.\nIf an error is passed to fn's callback then 'callback' is called with the\nerror, otherwise it will never be called.\n\n---------------------------------------\n\n<a name=\"waterfall\" />\n### waterfall(tasks, [callback])\n\nRuns an array of functions in series, each passing their results to the next in\nthe array. However, if any of the functions pass an error to the callback, the\nnext function is not executed and the main callback is immediately called with\nthe error.\n\n__Arguments__\n\n* tasks - An array of functions to run, each function is passed a \n  callback(err, result1, result2, ...) it must call on completion. The first\n  argument is an error (which can be null) and any further arguments will be \n  passed as arguments in order to the next task.\n* callback(err, [results]) - An optional callback to run once all the functions\n  have completed. This will be passed the results of the last task's callback.\n\n\n\n__Example__\n\n```js\nasync.waterfall([\n    function(callback){\n        callback(null, 'one', 'two');\n    },\n    function(arg1, arg2, callback){\n        callback(null, 'three');\n    },\n    function(arg1, callback){\n        // arg1 now equals 'three'\n        callback(null, 'done');\n    }\n], function (err, result) {\n   // result now equals 'done'    \n});\n```\n\n---------------------------------------\n<a name=\"compose\" />\n### compose(fn1, fn2...)\n\nCreates a function which is a composition of the passed asynchronous\nfunctions. Each function consumes the return value of the function that\nfollows. Composing functions f(), g() and h() would produce the result of\nf(g(h())), only this version uses callbacks to obtain the return values.\n\nEach function is executed with the `this` binding of the composed function.\n\n__Arguments__\n\n* functions... - the asynchronous functions to compose\n\n\n__Example__\n\n```js\nfunction add1(n, callback) {\n    setTimeout(function () {\n        callback(null, n + 1);\n    }, 10);\n}\n\nfunction mul3(n, callback) {\n    setTimeout(function () {\n        callback(null, n * 3);\n    }, 10);\n}\n\nvar add1mul3 = async.compose(mul3, add1);\n\nadd1mul3(4, function (err, result) {\n   // result now equals 15\n});\n```\n\n---------------------------------------\n<a name=\"applyEach\" />\n### applyEach(fns, args..., callback)\n\nApplies the provided arguments to each function in the array, calling the\ncallback after all functions have completed. If you only provide the first\nargument then it will return a function which lets you pass in the\narguments as if it were a single function call.\n\n__Arguments__\n\n* fns - the asynchronous functions to all call with the same arguments\n* args... - any number of separate arguments to pass to the function\n* callback - the final argument should be the callback, called when all\n  functions have completed processing\n\n\n__Example__\n\n```js\nasync.applyEach([enableSearch, updateSchema], 'bucket', callback);\n\n// partial application example:\nasync.each(\n    buckets,\n    async.applyEach([enableSearch, updateSchema]),\n    callback\n);\n```\n\n---------------------------------------\n\n<a name=\"applyEachSeries\" />\n### applyEachSeries(arr, iterator, callback)\n\nThe same as applyEach only the functions are applied in series.\n\n---------------------------------------\n\n<a name=\"queue\" />\n### queue(worker, concurrency)\n\nCreates a queue object with the specified concurrency. Tasks added to the\nqueue will be processed in parallel (up to the concurrency limit). If all\nworkers are in progress, the task is queued until one is available. Once\na worker has completed a task, the task's callback is called.\n\n__Arguments__\n\n* worker(task, callback) - An asynchronous function for processing a queued\n  task, which must call its callback(err) argument when finished, with an \n  optional error as an argument.\n* concurrency - An integer for determining how many worker functions should be\n  run in parallel.\n\n__Queue objects__\n\nThe queue object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* concurrency - an integer for determining how many worker functions should be\n  run in parallel. This property can be changed after a queue is created to\n  alter the concurrency on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n  once the worker has finished processing the task.\n  instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* unshift(task, [callback]) - add a new task to the front of the queue.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n```js\n// create a queue object with concurrency 2\n\nvar q = async.queue(function (task, callback) {\n    console.log('hello ' + task.name);\n    callback();\n}, 2);\n\n\n// assign a callback\nq.drain = function() {\n    console.log('all items have been processed');\n}\n\n// add some items to the queue\n\nq.push({name: 'foo'}, function (err) {\n    console.log('finished processing foo');\n});\nq.push({name: 'bar'}, function (err) {\n    console.log('finished processing bar');\n});\n\n// add some items to the queue (batch-wise)\n\nq.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {\n    console.log('finished processing bar');\n});\n\n// add some items to the front of the queue\n\nq.unshift({name: 'bar'}, function (err) {\n    console.log('finished processing bar');\n});\n```\n\n---------------------------------------\n\n<a name=\"cargo\" />\n### cargo(worker, [payload])\n\nCreates a cargo object with the specified payload. Tasks added to the\ncargo will be processed altogether (up to the payload limit). If the\nworker is in progress, the task is queued until it is available. Once\nthe worker has completed some tasks, each callback of those tasks is called.\n\n__Arguments__\n\n* worker(tasks, callback) - An asynchronous function for processing an array of\n  queued tasks, which must call its callback(err) argument when finished, with \n  an optional error as an argument.\n* payload - An optional integer for determining how many tasks should be\n  processed per round; if omitted, the default is unlimited.\n\n__Cargo objects__\n\nThe cargo object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* payload - an integer for determining how many tasks should be\n  process per round. This property can be changed after a cargo is created to\n  alter the payload on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n  once the worker has finished processing the task.\n  instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n```js\n// create a cargo object with payload 2\n\nvar cargo = async.cargo(function (tasks, callback) {\n    for(var i=0; i<tasks.length; i++){\n      console.log('hello ' + tasks[i].name);\n    }\n    callback();\n}, 2);\n\n\n// add some items\n\ncargo.push({name: 'foo'}, function (err) {\n    console.log('finished processing foo');\n});\ncargo.push({name: 'bar'}, function (err) {\n    console.log('finished processing bar');\n});\ncargo.push({name: 'baz'}, function (err) {\n    console.log('finished processing baz');\n});\n```\n\n---------------------------------------\n\n<a name=\"auto\" />\n### auto(tasks, [callback])\n\nDetermines the best order for running functions based on their requirements.\nEach function can optionally depend on other functions being completed first,\nand each function is run as soon as its requirements are satisfied. If any of\nthe functions pass an error to their callback, that function will not complete\n(so any other functions depending on it will not run) and the main callback\nwill be called immediately with the error. Functions also receive an object\ncontaining the results of functions which have completed so far.\n\nNote, all functions are called with a results object as a second argument, \nso it is unsafe to pass functions in the tasks object which cannot handle the\nextra argument. For example, this snippet of code:\n\n```js\nasync.auto({\n  readData: async.apply(fs.readFile, 'data.txt', 'utf-8');\n}, callback);\n```\n\nwill have the effect of calling readFile with the results object as the last\nargument, which will fail:\n\n```js\nfs.readFile('data.txt', 'utf-8', cb, {});\n```\n\nInstead, wrap the call to readFile in a function which does not forward the \nresults object:\n\n```js\nasync.auto({\n  readData: function(cb, results){\n    fs.readFile('data.txt', 'utf-8', cb);\n  }\n}, callback);\n```\n\n__Arguments__\n\n* tasks - An object literal containing named functions or an array of\n  requirements, with the function itself the last item in the array. The key\n  used for each function or array is used when specifying requirements. The \n  function receives two arguments: (1) a callback(err, result) which must be \n  called when finished, passing an error (which can be null) and the result of \n  the function's execution, and (2) a results object, containing the results of\n  the previously executed functions.\n* callback(err, results) - An optional callback which is called when all the\n  tasks have been completed. The callback will receive an error as an argument\n  if any tasks pass an error to their callback. Results will always be passed\n\tbut if an error occurred, no other tasks will be performed, and the results\n\tobject will only contain partial results.\n  \n\n__Example__\n\n```js\nasync.auto({\n    get_data: function(callback){\n        // async code to get some data\n    },\n    make_folder: function(callback){\n        // async code to create a directory to store a file in\n        // this is run at the same time as getting the data\n    },\n    write_file: ['get_data', 'make_folder', function(callback){\n        // once there is some data and the directory exists,\n        // write the data to a file in the directory\n        callback(null, filename);\n    }],\n    email_link: ['write_file', function(callback, results){\n        // once the file is written let's email a link to it...\n        // results.write_file contains the filename returned by write_file.\n    }]\n});\n```\n\nThis is a fairly trivial example, but to do this using the basic parallel and\nseries functions would look like this:\n\n```js\nasync.parallel([\n    function(callback){\n        // async code to get some data\n    },\n    function(callback){\n        // async code to create a directory to store a file in\n        // this is run at the same time as getting the data\n    }\n],\nfunction(err, results){\n    async.series([\n        function(callback){\n            // once there is some data and the directory exists,\n            // write the data to a file in the directory\n        },\n        function(callback){\n            // once the file is written let's email a link to it...\n        }\n    ]);\n});\n```\n\nFor a complicated series of async tasks using the auto function makes adding\nnew tasks much easier and makes the code more readable.\n\n\n---------------------------------------\n\n<a name=\"iterator\" />\n### iterator(tasks)\n\nCreates an iterator function which calls the next function in the array,\nreturning a continuation to call the next one after that. It's also possible to\n'peek' the next iterator by doing iterator.next().\n\nThis function is used internally by the async module but can be useful when\nyou want to manually control the flow of functions in series.\n\n__Arguments__\n\n* tasks - An array of functions to run.\n\n__Example__\n\n```js\nvar iterator = async.iterator([\n    function(){ sys.p('one'); },\n    function(){ sys.p('two'); },\n    function(){ sys.p('three'); }\n]);\n\nnode> var iterator2 = iterator();\n'one'\nnode> var iterator3 = iterator2();\n'two'\nnode> iterator3();\n'three'\nnode> var nextfn = iterator2.next();\nnode> nextfn();\n'three'\n```\n\n---------------------------------------\n\n<a name=\"apply\" />\n### apply(function, arguments..)\n\nCreates a continuation function with some arguments already applied, a useful\nshorthand when combined with other control flow functions. Any arguments\npassed to the returned function are added to the arguments originally passed\nto apply.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to automatically apply when the\n  continuation is called.\n\n__Example__\n\n```js\n// using apply\n\nasync.parallel([\n    async.apply(fs.writeFile, 'testfile1', 'test1'),\n    async.apply(fs.writeFile, 'testfile2', 'test2'),\n]);\n\n\n// the same process without using apply\n\nasync.parallel([\n    function(callback){\n        fs.writeFile('testfile1', 'test1', callback);\n    },\n    function(callback){\n        fs.writeFile('testfile2', 'test2', callback);\n    }\n]);\n```\n\nIt's possible to pass any number of additional arguments when calling the\ncontinuation:\n\n```js\nnode> var fn = async.apply(sys.puts, 'one');\nnode> fn('two', 'three');\none\ntwo\nthree\n```\n\n---------------------------------------\n\n<a name=\"nextTick\" />\n### nextTick(callback)\n\nCalls the callback on a later loop around the event loop. In node.js this just\ncalls process.nextTick, in the browser it falls back to setImmediate(callback)\nif available, otherwise setTimeout(callback, 0), which means other higher priority\nevents may precede the execution of the callback.\n\nThis is used internally for browser-compatibility purposes.\n\n__Arguments__\n\n* callback - The function to call on a later loop around the event loop.\n\n__Example__\n\n```js\nvar call_order = [];\nasync.nextTick(function(){\n    call_order.push('two');\n    // call_order now equals ['one','two']\n});\ncall_order.push('one')\n```\n\n<a name=\"times\" />\n### times(n, callback)\n\nCalls the callback n times and accumulates results in the same manner\nyou would use with async.map.\n\n__Arguments__\n\n* n - The number of times to run the function.\n* callback - The function to call n times.\n\n__Example__\n\n```js\n// Pretend this is some complicated async factory\nvar createUser = function(id, callback) {\n  callback(null, {\n    id: 'user' + id\n  })\n}\n// generate 5 users\nasync.times(5, function(n, next){\n    createUser(n, function(err, user) {\n      next(err, user)\n    })\n}, function(err, users) {\n  // we should now have 5 users\n});\n```\n\n<a name=\"timesSeries\" />\n### timesSeries(n, callback)\n\nThe same as times only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n## Utils\n\n<a name=\"memoize\" />\n### memoize(fn, [hasher])\n\nCaches the results of an async function. When creating a hash to store function\nresults against, the callback is omitted from the hash and an optional hash\nfunction can be used.\n\nThe cache of results is exposed as the `memo` property of the function returned\nby `memoize`.\n\n__Arguments__\n\n* fn - the function you to proxy and cache results from.\n* hasher - an optional function for generating a custom hash for storing\n  results, it has all the arguments applied to it apart from the callback, and\n  must be synchronous.\n\n__Example__\n\n```js\nvar slow_fn = function (name, callback) {\n    // do something\n    callback(null, result);\n};\nvar fn = async.memoize(slow_fn);\n\n// fn can now be used as if it were slow_fn\nfn('some name', function () {\n    // callback\n});\n```\n\n<a name=\"unmemoize\" />\n### unmemoize(fn)\n\nUndoes a memoized function, reverting it to the original, unmemoized\nform. Comes handy in tests.\n\n__Arguments__\n\n* fn - the memoized function\n\n<a name=\"log\" />\n### log(function, arguments)\n\nLogs the result of an async function to the console. Only works in node.js or\nin browsers that support console.log and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.log is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n```js\nvar hello = function(name, callback){\n    setTimeout(function(){\n        callback(null, 'hello ' + name);\n    }, 1000);\n};\n```\n```js\nnode> async.log(hello, 'world');\n'hello world'\n```\n\n---------------------------------------\n\n<a name=\"dir\" />\n### dir(function, arguments)\n\nLogs the result of an async function to the console using console.dir to\ndisplay the properties of the resulting object. Only works in node.js or\nin browsers that support console.dir and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.dir is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n```js\nvar hello = function(name, callback){\n    setTimeout(function(){\n        callback(null, {hello: name});\n    }, 1000);\n};\n```\n```js\nnode> async.dir(hello, 'world');\n{hello: 'world'}\n```\n\n---------------------------------------\n\n<a name=\"noConflict\" />\n### noConflict()\n\nChanges the value of async back to its original value, returning a reference to the\nasync object.\n",
   "readmeFilename": "README.md",
-  "_id": "async@0.2.8",
+  "_id": "async@0.2.9",
   "_from": "async@~0.2.7"
 }
index 9e7138c..884ec6d 100755 (executable)
@@ -1,11 +1,11 @@
 test:
-       @./node_modules/.bin/lab
+       @node node_modules/lab/bin/lab
 test-cov: 
-       @./node_modules/.bin/lab -r threshold -t 100
+       @node node_modules/lab/bin/lab -r threshold -t 100
 test-cov-html:
-       @./node_modules/.bin/lab -r html -o coverage.html
+       @node node_modules/lab/bin/lab -r html -o coverage.html
 complexity:
-       @./node_modules/.bin/cr -o complexity.md -f markdown lib
+       @node node_modules/complexity-report/src/cli.js -o complexity.md -f markdown lib
 
 .PHONY: test test-cov test-cov-html complexity
 
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/.npmignore b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/.npmignore
new file mode 100644 (file)
index 0000000..9966e5e
--- /dev/null
@@ -0,0 +1,18 @@
+.idea\r
+*.iml\r
+npm-debug.log\r
+dump.rdb\r
+node_modules\r
+results.tap\r
+results.xml\r
+npm-shrinkwrap.json\r
+config.json\r
+.DS_Store\r
+*/.DS_Store\r
+*/*/.DS_Store\r
+._*\r
+*/._*\r
+*/*/._*\r
+coverage.*\r
+lib-cov\r
+complexity.md\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/.travis.yml b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/.travis.yml
new file mode 100755 (executable)
index 0000000..40ca59e
--- /dev/null
@@ -0,0 +1,5 @@
+language: node_js\r
+\r
+node_js:\r
+  - 0.10\r
+\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/LICENSE b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/LICENSE
new file mode 100755 (executable)
index 0000000..394adcf
--- /dev/null
@@ -0,0 +1,33 @@
+Copyright (c) 2011-2013, Walmart.\r
+All rights reserved.\r
+\r
+Redistribution and use in source and binary forms, with or without\r
+modification, are permitted provided that the following conditions are met:\r
+    * Redistributions of source code must retain the above copyright\r
+      notice, this list of conditions and the following disclaimer.\r
+    * Redistributions in binary form must reproduce the above copyright\r
+      notice, this list of conditions and the following disclaimer in the\r
+      documentation and/or other materials provided with the distribution.\r
+    * Neither the name of Walmart nor the\r
+      names of its contributors may be used to endorse or promote products\r
+      derived from this software without specific prior written permission.\r
+\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+DISCLAIMED. IN NO EVENT SHALL WALMART BE LIABLE FOR ANY\r
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+\r
+                                  *   *   *\r
+\r
+\r
+Portions of this project were initially based on Postmile, Copyright (c) 2011, Yahoo Inc.\r
+Postmile is published at https://github.com/yahoo/postmile and its licensing terms are\r
+published at https://github.com/yahoo/postmile/blob/master/LICENSE.\r
+\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/Makefile b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/Makefile
new file mode 100755 (executable)
index 0000000..e605d6c
--- /dev/null
@@ -0,0 +1,10 @@
+test:\r
+       @node node_modules/lab/bin/lab\r
+test-cov: \r
+       @node node_modules/lab/bin/lab -r threshold -t 100\r
+test-cov-html:\r
+       @node node_modules/lab/bin/lab -r html -o coverage.html\r
+complexity:\r
+       @node node_modules/complexity-report/src/cli.js -o complexity.md -f markdown lib\r
+\r
+.PHONY: test test-cov test-cov-html complexity\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/README.md b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/README.md
new file mode 100755 (executable)
index 0000000..ac64e2f
--- /dev/null
@@ -0,0 +1,436 @@
+<a href="https://github.com/spumko"><img src="https://raw.github.com/spumko/spumko/master/images/from.png" align="right" /></a>\r
+![hoek Logo](https://raw.github.com/spumko/hoek/master/images/hoek.png)\r
+\r
+General purpose node utilities\r
+\r
+[![Build Status](https://secure.travis-ci.org/spumko/hoek.png)](http://travis-ci.org/spumko/hoek)\r
+\r
+# Table of Contents\r
+\r
+* [Introduction](#introduction "Introduction")\r
+* [Object](#object "Object")\r
+  * [clone](#cloneobj "clone")\r
+  * [merge](#mergetarget-source-isnulloverride-ismergearrays "merge")\r
+  * [applyToDefaults](#applytodefaultsdefaults-options "applyToDefaults")\r
+  * [unique](#uniquearray-key "unique")\r
+  * [mapToObject](#maptoobjectarray-key "mapToObject")\r
+  * [intersect](#intersectarray1-array2 "intersect")\r
+  * [matchKeys](#matchkeysobj-keys "matchKeys")\r
+  * [flatten](#flattenarray-target "flatten")\r
+  * [removeKeys](#removekeysobject-keys "removeKeys")\r
+  * [reach](#reachobj-chain "reach")\r
+  * [inheritAsync](#inheritasyncself-obj-keys "inheritAsync")\r
+  * [rename](#renameobj-from-to "rename")\r
+* [Timer](#timer "Timer")\r
+* [Binary Encoding/Decoding](#binary "Binary Encoding/Decoding")\r
+  * [base64urlEncode](#binary64urlEncodevalue "binary64urlEncode")\r
+  * [base64urlDecode](#binary64urlDecodevalue "binary64urlDecode")\r
+* [Escaping Characters](#escaped "Escaping Characters")\r
+  * [escapeHtml](#escapeHtmlstring "escapeHtml")\r
+  * [escapeHeaderAttribute](#escapeHeaderAttributeattribute "escapeHeaderAttribute")\r
+  * [escapeRegex](#escapeRegexstring "escapeRegex")\r
+* [Errors](#errors "Errors")\r
+  * [assert](#assertmessage "assert")\r
+  * [abort](#abortmessage "abort")\r
+  * [displayStack](#displayStackslice "displayStack")\r
+  * [callStack](#callStackslice "callStack")\r
+  * [toss](#tosscondition "toss")\r
+* [Load files](#load-files "Load Files")\r
+  * [loadPackage](#loadPackagedir "loadpackage")\r
+  * [loadDirModules](#loadDirModulespath-excludefiles-target "loaddirmodules")\r
+\r
+\r
+\r
+# Introduction\r
+\r
+The *Hoek* general purpose node utilities library is used to aid in a variety of manners. It comes with useful methods for Arrays (clone, merge, applyToDefaults), Objects (removeKeys, copy), Asserting and more. \r
+\r
+For example, to use Hoek to set configuration with default options:\r
+```javascript\r
+var Hoek = require('hoek');\r
+\r
+var default = {url : "www.github.com", port : "8000", debug : true}\r
+\r
+var config = Hoek.applyToDefaults(default, {port : "3000", admin : true});\r
+\r
+// In this case, config would be { url: 'www.github.com', port: '3000', debug: true, admin: true }\r
+```\r
+\r
+Under each of the sections (such as Array), there are subsections which correspond to Hoek methods. Each subsection will explain how to use the corresponding method. In each js excerpt below, the var Hoek = require('hoek') is omitted for brevity.\r
+\r
+## Object\r
+\r
+Hoek provides several helpful methods for objects and arrays.\r
+\r
+### clone(obj)\r
+\r
+This method is used to clone an object or an array. A *deep copy* is made (duplicates everything, including values that are objects). \r
+\r
+```javascript\r
+\r
+var nestedObj = {\r
+        w: /^something$/ig,\r
+        x: {\r
+            a: [1, 2, 3],\r
+            b: 123456,\r
+            c: new Date()\r
+        },\r
+        y: 'y',\r
+        z: new Date()\r
+    };\r
+\r
+var copy = Hoek.clone(nestedObj);\r
+\r
+copy.x.b = 100;\r
+\r
+console.log(copy.y)        // results in 'y'\r
+console.log(nestedObj.x.b) // results in 123456\r
+console.log(copy.x.b)      // results in 100\r
+```\r
+\r
+### merge(target, source, isNullOverride, isMergeArrays)\r
+isNullOverride, isMergeArrays default to true\r
+\r
+Merge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied\r
+\r
+\r
+```javascript\r
+\r
+var target = {a: 1, b : 2}\r
+var source = {a: 0, c: 5}\r
+var source2 = {a: null, c: 5}\r
+\r
+var targetArray = [1, 2, 3];\r
+var sourceArray = [4, 5];\r
+\r
+var newTarget = Hoek.merge(target, source);     // results in {a: 0, b: 2, c: 5}\r
+newTarget = Hoek.merge(target, source2);        // results in {a: null, b: 2, c: 5}\r
+newTarget = Hoek.merge(target, source2, false); // results in {a: 1, b: 2, c: 5}\r
+\r
+newTarget = Hoek.merge(targetArray, sourceArray)              // results in [1, 2, 3, 4, 5]\r
+newTarget = Hoek.merge(targetArray, sourceArray, true, false) // results in [4, 5]\r
+\r
+\r
+\r
+\r
+```\r
+\r
+### applyToDefaults(defaults, options)\r
+\r
+Apply options to a copy of the defaults\r
+\r
+```javascript\r
+\r
+var defaults = {host: "localhost", port: 8000};\r
+var options = {port: 8080};\r
+\r
+var config = Hoek.applyToDefaults(defaults, options); // results in {host: "localhost", port: 8080};\r
+\r
+\r
+```\r
+\r
+### unique(array, key)\r
+\r
+Remove duplicate items from Array\r
+\r
+```javascript\r
+\r
+var array = [1, 2, 2, 3, 3, 4, 5, 6];\r
+\r
+var newArray = Hoek.unique(array); // results in [1,2,3,4,5,6];\r
+\r
+array = [{id: 1}, {id: 1}, {id: 2}];\r
+\r
+newArray = Hoek.unique(array, "id") // results in [{id: 1}, {id: 2}]\r
+\r
+```\r
+\r
+### mapToObject(array, key)\r
+\r
+Convert an Array into an Object\r
+\r
+```javascript\r
+\r
+var array = [1,2,3];\r
+var newObject = Hoek.mapToObject(array); // results in [{"1": true}, {"2": true}, {"3": true}]\r
+\r
+array = [{id: 1}, {id: 2}];\r
+newObject = Hoek.mapToObject(array, "id") // results in [{"id": 1}, {"id": 2}]\r
+\r
+```\r
+### intersect(array1, array2)\r
+\r
+Find the common unique items in two arrays\r
+\r
+```javascript\r
+\r
+var array1 = [1, 2, 3];\r
+var array2 = [1, 4, 5];\r
+\r
+var newArray = Hoek.intersect(array1, array2) // results in [1]\r
+\r
+```\r
+\r
+### matchKeys(obj, keys) \r
+\r
+Find which keys are present\r
+\r
+```javascript\r
+\r
+var obj = {a: 1, b: 2, c: 3};\r
+var keys = ["a", "e"];\r
+\r
+Hoek.matchKeys(obj, keys) // returns ["a"]\r
+\r
+```\r
+\r
+### flatten(array, target)\r
+\r
+Flatten an array\r
+\r
+```javascript\r
+\r
+var array = [1, 2, 3];\r
+var target = [4, 5]; \r
+\r
+var flattenedArray = Hoek.flatten(array, target) // results in [4, 5, 1, 2, 3];\r
+\r
+```\r
+\r
+### removeKeys(object, keys)\r
+\r
+Remove keys\r
+\r
+```javascript\r
+\r
+var object = {a: 1, b: 2, c: 3, d: 4};\r
+\r
+var keys = ["a", "b"];\r
+\r
+Hoek.removeKeys(object, keys) // object is now {c: 3, d: 4}\r
+\r
+```\r
+\r
+### reach(obj, chain)\r
+\r
+Converts an object key chain string to reference\r
+\r
+```javascript\r
+\r
+var chain = 'a.b.c';\r
+var obj = {a : {b : { c : 1}}};\r
+\r
+Hoek.reach(obj, chain) // returns 1\r
+\r
+```\r
+\r
+### inheritAsync(self, obj, keys) \r
+\r
+Inherits a selected set of methods from an object, wrapping functions in asynchronous syntax and catching errors\r
+\r
+```javascript\r
+\r
+var targetFunc = function () { };\r
+\r
+var proto = {\r
+                a: function () {\r
+                    return 'a!';\r
+                },\r
+                b: function () {\r
+                    return 'b!';\r
+                },\r
+                c: function () {\r
+                    throw new Error('c!');\r
+                }\r
+            };\r
+\r
+var keys = ['a', 'c'];\r
+\r
+Hoek.inheritAsync(targetFunc, proto, ['a', 'c']);\r
+\r
+var target = new targetFunc();\r
+\r
+target.a(function(err, result){console.log(result)}         // returns 'a!'       \r
+\r
+target.c(function(err, result){console.log(result)}         // returns undefined\r
+\r
+target.b(function(err, result){console.log(result)}         // gives error: Object [object Object] has no method 'b'\r
+\r
+```\r
+\r
+### rename(obj, from, to)\r
+\r
+Rename a key of an object\r
+\r
+```javascript\r
+\r
+var obj = {a : 1, b : 2};\r
+\r
+Hoek.rename(obj, "a", "c");     // obj is now {c : 1, b : 2}\r
+\r
+```\r
+\r
+\r
+# Timer\r
+\r
+A Timer object. Initializing a new timer object sets the ts to the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.\r
+\r
+```javascript\r
+\r
+\r
+example : \r
+\r
+\r
+var timerObj = new Hoek.Timer();\r
+console.log("Time is now: " + timerObj.ts)\r
+console.log("Elapsed time from initialization: " + timerObj.elapsed() + 'milliseconds')\r
+\r
+```\r
+\r
+# Binary Encoding/Decoding\r
+\r
+### base64urlEncode(value)\r
+\r
+Encodes value in Base64 or URL encoding\r
+\r
+### base64urlDecode(value)\r
+\r
+Decodes data in Base64 or URL encoding.\r
+# Escaping Characters\r
+\r
+Hoek provides convenient methods for escaping html characters. The escaped characters are as followed:\r
+\r
+```javascript\r
+\r
+internals.htmlEscaped = {\r
+    '&': '&amp;',\r
+    '<': '&lt;',\r
+    '>': '&gt;',\r
+    '"': '&quot;',\r
+    "'": '&#x27;',\r
+    '`': '&#x60;'\r
+};\r
+\r
+```\r
+\r
+### escapeHtml(string)\r
+\r
+```javascript\r
+\r
+var string = '<html> hey </html>';\r
+var escapedString = Hoek.escapeHtml(string); // returns &lt;html&gt; hey &lt;/html&gt;\r
+\r
+```\r
+\r
+### escapeHeaderAttribute(attribute)\r
+\r
+Escape attribute value for use in HTTP header\r
+\r
+```javascript\r
+\r
+var a = Hoek.escapeHeaderAttribute('I said "go w\\o me"');  //returns I said \"go w\\o me\"\r
+\r
+\r
+```\r
+\r
+\r
+### escapeRegex(string)\r
+\r
+Escape string for Regex construction\r
+\r
+```javascript\r
+\r
+var a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\/`"(>)[<]d{}s,');  // returns 4\^f\$s\.4\*5\+\-_\?%\=#\!\:@\|~\\\/`"\(>\)\[<\]d\{\}s\,\r
+\r
+\r
+\r
+```\r
+\r
+# Errors\r
+\r
+### assert(message)\r
+\r
+```javascript\r
+\r
+var a = 1, b =2;\r
+\r
+Hoek.assert(a === b, 'a should equal b');  // ABORT: a should equal b\r
+\r
+```\r
+\r
+### abort(message)\r
+\r
+First checks if process.env.NODE_ENV === 'test', and if so, throws error message. Otherwise,\r
+displays most recent stack and then exits process.\r
+\r
+\r
+\r
+### displayStack(slice)\r
+\r
+Displays the trace stack\r
+\r
+```javascript\r
+\r
+var stack = Hoek.displayStack();\r
+console.log(stack) // returns something like:\r
+\r
+[ 'null (/Users/user/Desktop/hoek/test.js:4:18)',\r
+  'Module._compile (module.js:449:26)',\r
+  'Module._extensions..js (module.js:467:10)',\r
+  'Module.load (module.js:356:32)',\r
+  'Module._load (module.js:312:12)',\r
+  'Module.runMain (module.js:492:10)',\r
+  'startup.processNextTick.process._tickCallback (node.js:244:9)' ]\r
+\r
+```\r
+\r
+### callStack(slice)\r
+\r
+Returns a trace stack array.\r
+\r
+```javascript\r
+\r
+var stack = Hoek.callStack();\r
+console.log(stack)  // returns something like:\r
+\r
+[ [ '/Users/user/Desktop/hoek/test.js', 4, 18, null, false ],\r
+  [ 'module.js', 449, 26, 'Module._compile', false ],\r
+  [ 'module.js', 467, 10, 'Module._extensions..js', false ],\r
+  [ 'module.js', 356, 32, 'Module.load', false ],\r
+  [ 'module.js', 312, 12, 'Module._load', false ],\r
+  [ 'module.js', 492, 10, 'Module.runMain', false ],\r
+  [ 'node.js',\r
+    244,\r
+    9,\r
+    'startup.processNextTick.process._tickCallback',\r
+    false ] ]\r
+\r
+\r
+```\r
+\r
+### toss(condition)\r
+\r
+toss(condition /*, [message], callback */)\r
+\r
+Return an error as first argument of a callback\r
+\r
+\r
+# Load Files\r
+\r
+### loadPackage(dir)\r
+\r
+Load and parse package.json process root or given directory\r
+\r
+```javascript\r
+\r
+var pack = Hoek.loadPackage();  // pack.name === 'hoek'\r
+\r
+```\r
+\r
+### loadDirModules(path, excludeFiles, target) \r
+\r
+Loads modules from a given path; option to exclude files (array).\r
+\r
+\r
+\r
+\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/images/hoek.png b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/images/hoek.png
new file mode 100755 (executable)
index 0000000..6ccfcb1
Binary files /dev/null and b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/images/hoek.png differ
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/index.js
new file mode 100755 (executable)
index 0000000..4cc88b3
--- /dev/null
@@ -0,0 +1 @@
+module.exports = require('./lib');
\ No newline at end of file
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/lib/escape.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/lib/escape.js
new file mode 100755 (executable)
index 0000000..666b3dc
--- /dev/null
@@ -0,0 +1,132 @@
+// Declare internals\r
+\r
+var internals = {};\r
+\r
+\r
+exports.escapeJavaScript = function (input) {\r
+\r
+    if (!input) {\r
+        return '';\r
+    }\r
+\r
+    var escaped = '';\r
+\r
+    for (var i = 0, il = input.length; i < il; ++i) {\r
+\r
+        var charCode = input.charCodeAt(i);\r
+\r
+        if (internals.isSafe(charCode)) {\r
+            escaped += input[i];\r
+        }\r
+        else {\r
+            escaped += internals.escapeJavaScriptChar(charCode);\r
+        }\r
+    }\r
+\r
+    return escaped;\r
+};\r
+\r
+\r
+exports.escapeHtml = function (input) {\r
+\r
+    if (!input) {\r
+        return '';\r
+    }\r
+\r
+    var escaped = '';\r
+\r
+    for (var i = 0, il = input.length; i < il; ++i) {\r
+\r
+        var charCode = input.charCodeAt(i);\r
+\r
+        if (internals.isSafe(charCode)) {\r
+            escaped += input[i];\r
+        }\r
+        else {\r
+            escaped += internals.escapeHtmlChar(charCode);\r
+        }\r
+    }\r
+\r
+    return escaped;\r
+};\r
+\r
+\r
+internals.escapeJavaScriptChar = function (charCode) {\r
+\r
+    if (charCode >= 256) {\r
+        return '\\u' + internals.padLeft('' + charCode, 4);\r
+    }\r
+\r
+    var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex');\r
+    return '\\x' + internals.padLeft(hexValue, 2);\r
+};\r
+\r
+\r
+internals.escapeHtmlChar = function (charCode) {\r
+\r
+    var namedEscape = internals.namedHtml[charCode];\r
+    if (typeof namedEscape !== 'undefined') {\r
+        return namedEscape;\r
+    }\r
+\r
+    if (charCode >= 256) {\r
+        return '&#' + charCode + ';';\r
+    }\r
+\r
+    var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex');\r
+    return '&#x' + internals.padLeft(hexValue, 2) + ';';\r
+};\r
+\r
+\r
+internals.padLeft = function (str, len) {\r
+\r
+    while (str.length < len) {\r
+        str = '0' + str;\r
+    }\r
+\r
+    return str;\r
+};\r
+\r
+\r
+internals.isSafe = function (charCode) {\r
+\r
+    return (typeof internals.safeCharCodes[charCode] !== 'undefined');\r
+};\r
+\r
+\r
+internals.namedHtml = {\r
+    '38': '&amp;',\r
+    '60': '&lt;',\r
+    '62': '&gt;',\r
+    '34': '&quot;',\r
+    '160': '&nbsp;',\r
+    '162': '&cent;',\r
+    '163': '&pound;',\r
+    '164': '&curren;',\r
+    '169': '&copy;',\r
+    '174': '&reg;'\r
+};\r
+\r
+\r
+internals.safeCharCodes = (function () {\r
+\r
+    var safe = {};\r
+\r
+    for (var i = 32; i < 123; ++i) {\r
+\r
+        if ((i >= 97 && i <= 122) ||         // a-z\r
+            (i >= 65 && i <= 90) ||          // A-Z\r
+            (i >= 48 && i <= 57) ||          // 0-9\r
+            i === 32 ||                      // space\r
+            i === 46 ||                      // .\r
+            i === 44 ||                      // ,\r
+            i === 45 ||                      // -\r
+            i === 58 ||                      // :\r
+            i === 95) {                      // _\r
+\r
+            safe[i] = null;\r
+        }\r
+    }\r
+\r
+    return safe;\r
+}());
\ No newline at end of file
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/lib/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/lib/index.js
new file mode 100755 (executable)
index 0000000..806260d
--- /dev/null
@@ -0,0 +1,585 @@
+// Load modules\r
+\r
+var Fs = require('fs');\r
+var Escape = require('./escape');\r
+\r
+\r
+// Declare internals\r
+\r
+var internals = {};\r
+\r
+\r
+// Clone object or array\r
+\r
+exports.clone = function (obj, seen) {\r
+\r
+    if (typeof obj !== 'object' ||\r
+        obj === null) {\r
+\r
+        return obj;\r
+    }\r
+\r
+    seen = seen || { orig: [], copy: [] };\r
+\r
+    var lookup = seen.orig.indexOf(obj);\r
+    if (lookup !== -1) {\r
+        return seen.copy[lookup];\r
+    }\r
+\r
+    var newObj = (obj instanceof Array) ? [] : {};\r
+\r
+    seen.orig.push(obj);\r
+    seen.copy.push(newObj);\r
+\r
+    for (var i in obj) {\r
+        if (obj.hasOwnProperty(i)) {\r
+            if (obj[i] instanceof Buffer) {\r
+                newObj[i] = new Buffer(obj[i]);\r
+            }\r
+            else if (obj[i] instanceof Date) {\r
+                newObj[i] = new Date(obj[i].getTime());\r
+            }\r
+            else if (obj[i] instanceof RegExp) {\r
+                var flags = '' + (obj[i].global ? 'g' : '') + (obj[i].ignoreCase ? 'i' : '') + (obj[i].multiline ? 'm' : '');\r
+                newObj[i] = new RegExp(obj[i].source, flags);\r
+            }\r
+            else {\r
+                newObj[i] = exports.clone(obj[i], seen);\r
+            }\r
+        }\r
+    }\r
+\r
+    return newObj;\r
+};\r
+\r
+\r
+// Merge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied\r
+\r
+exports.merge = function (target, source, isNullOverride /* = true */, isMergeArrays /* = true */) {\r
+\r
+    exports.assert(target && typeof target == 'object', 'Invalid target value: must be an object');\r
+    exports.assert(source === null || source === undefined || typeof source === 'object', 'Invalid source value: must be null, undefined, or an object');\r
+\r
+    if (!source) {\r
+        return target;\r
+    }\r
+\r
+    if (source instanceof Array) {\r
+        exports.assert(target instanceof Array, 'Cannot merge array onto an object');\r
+        if (isMergeArrays === false) {                                                  // isMergeArrays defaults to true\r
+            target.length = 0;                                                          // Must not change target assignment\r
+        }\r
+\r
+        for (var i = 0, il = source.length; i < il; ++i) {\r
+            target.push(source[i]);\r
+        }\r
+\r
+        return target;\r
+    }\r
+\r
+    var keys = Object.keys(source);\r
+    for (var k = 0, kl = keys.length; k < kl; ++k) {\r
+        var key = keys[k];\r
+        var value = source[key];\r
+        if (value &&\r
+            typeof value === 'object') {\r
+\r
+            if (!target[key] ||\r
+                typeof target[key] !== 'object') {\r
+\r
+                target[key] = exports.clone(value);\r
+            }\r
+            else {\r
+                exports.merge(target[key], source[key], isNullOverride, isMergeArrays);\r
+            }\r
+        }\r
+        else {\r
+            if (value !== null && value !== undefined) {            // Explicit to preserve empty strings\r
+                target[key] = value;\r
+            }\r
+            else if (isNullOverride !== false) {                    // Defaults to true\r
+                target[key] = value;\r
+            }\r
+        }\r
+    }\r
+\r
+    return target;\r
+};\r
+\r
+\r
+// Apply options to a copy of the defaults\r
+\r
+exports.applyToDefaults = function (defaults, options) {\r
+\r
+    exports.assert(defaults && typeof defaults == 'object', 'Invalid defaults value: must be an object');\r
+    exports.assert(!options || options === true || typeof options === 'object', 'Invalid options value: must be true, falsy or an object');\r
+\r
+    if (!options) {                                                 // If no options, return null\r
+        return null;\r
+    }\r
+\r
+    var copy = exports.clone(defaults);\r
+\r
+    if (options === true) {                                         // If options is set to true, use defaults\r
+        return copy;\r
+    }\r
+\r
+    return exports.merge(copy, options, false, false);\r
+};\r
+\r
+\r
+// Remove duplicate items from array\r
+\r
+exports.unique = function (array, key) {\r
+\r
+    var index = {};\r
+    var result = [];\r
+\r
+    for (var i = 0, il = array.length; i < il; ++i) {\r
+        var id = (key ? array[i][key] : array[i]);\r
+        if (index[id] !== true) {\r
+\r
+            result.push(array[i]);\r
+            index[id] = true;\r
+        }\r
+    }\r
+\r
+    return result;\r
+};\r
+\r
+\r
+// Convert array into object\r
+\r
+exports.mapToObject = function (array, key) {\r
+\r
+    if (!array) {\r
+        return null;\r
+    }\r
+\r
+    var obj = {};\r
+    for (var i = 0, il = array.length; i < il; ++i) {\r
+        if (key) {\r
+            if (array[i][key]) {\r
+                obj[array[i][key]] = true;\r
+            }\r
+        }\r
+        else {\r
+            obj[array[i]] = true;\r
+        }\r
+    }\r
+\r
+    return obj;\r
+};\r
+\r
+\r
+// Find the common unique items in two arrays\r
+\r
+exports.intersect = function (array1, array2, justFirst) {\r
+\r
+    if (!array1 || !array2) {\r
+        return [];\r
+    }\r
+\r
+    var common = [];\r
+    var hash = (array1 instanceof Array ? exports.mapToObject(array1) : array1);\r
+    var found = {};\r
+    for (var i = 0, il = array2.length; i < il; ++i) {\r
+        if (hash[array2[i]] && !found[array2[i]]) {\r
+            if (justFirst) {\r
+                return array2[i];\r
+            }\r
+\r
+            common.push(array2[i]);\r
+            found[array2[i]] = true;\r
+        }\r
+    }\r
+\r
+    return (justFirst ? null : common);\r
+};\r
+\r
+\r
+// Find which keys are present\r
+\r
+exports.matchKeys = function (obj, keys) {\r
+\r
+    var matched = [];\r
+    for (var i = 0, il = keys.length; i < il; ++i) {\r
+        if (obj.hasOwnProperty(keys[i])) {\r
+            matched.push(keys[i]);\r
+        }\r
+    }\r
+    return matched;\r
+};\r
+\r
+\r
+// Flatten array\r
+\r
+exports.flatten = function (array, target) {\r
+\r
+    var result = target || [];\r
+\r
+    for (var i = 0, il = array.length; i < il; ++i) {\r
+        if (Array.isArray(array[i])) {\r
+            exports.flatten(array[i], result);\r
+        }\r
+        else {\r
+            result.push(array[i]);\r
+        }\r
+    }\r
+\r
+    return result;\r
+};\r
+\r
+\r
+// Remove keys\r
+\r
+exports.removeKeys = function (object, keys) {\r
+\r
+    for (var i = 0, il = keys.length; i < il; i++) {\r
+        delete object[keys[i]];\r
+    }\r
+};\r
+\r
+\r
+// Convert an object key chain string ('a.b.c') to reference (object[a][b][c])\r
+\r
+exports.reach = function (obj, chain) {\r
+\r
+    var path = chain.split('.');\r
+    var ref = obj;\r
+    for (var i = 0, il = path.length; i < il; ++i) {\r
+        if (ref) {\r
+            ref = ref[path[i]];\r
+        }\r
+    }\r
+\r
+    return ref;\r
+};\r
+\r
+\r
+// Inherits a selected set of methods from an object, wrapping functions in asynchronous syntax and catching errors\r
+\r
+exports.inheritAsync = function (self, obj, keys) {\r
+\r
+    keys = keys || null;\r
+\r
+    for (var i in obj) {\r
+        if (obj.hasOwnProperty(i)) {\r
+            if (keys instanceof Array &&\r
+                keys.indexOf(i) < 0) {\r
+\r
+                continue;\r
+            }\r
+\r
+            self.prototype[i] = (function (fn) {\r
+\r
+                return function (next) {\r
+\r
+                    var result = null;\r
+                    try {\r
+                        result = fn();\r
+                    }\r
+                    catch (err) {\r
+                        return next(err);\r
+                    }\r
+\r
+                    return next(null, result);\r
+                };\r
+            })(obj[i]);\r
+        }\r
+    }\r
+};\r
+\r
+\r
+exports.formatStack = function (stack) {\r
+\r
+    var trace = [];\r
+    for (var i = 0, il = stack.length; i < il; ++i) {\r
+        var item = stack[i];\r
+        trace.push([item.getFileName(), item.getLineNumber(), item.getColumnNumber(), item.getFunctionName(), item.isConstructor()]);\r
+    }\r
+\r
+    return trace;\r
+};\r
+\r
+\r
+exports.formatTrace = function (trace) {\r
+\r
+    var display = [];\r
+\r
+    for (var i = 0, il = trace.length; i < il; ++i) {\r
+        var row = trace[i];\r
+        display.push((row[4] ? 'new ' : '') + row[3] + ' (' + row[0] + ':' + row[1] + ':' + row[2] + ')');\r
+    }\r
+\r
+    return display;\r
+};\r
+\r
+\r
+exports.callStack = function (slice) {\r
+\r
+    // http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi\r
+\r
+    var v8 = Error.prepareStackTrace;\r
+    Error.prepareStackTrace = function (err, stack) {\r
+\r
+        return stack;\r
+    };\r
+\r
+    var capture = {};\r
+    Error.captureStackTrace(capture, arguments.callee);\r
+    var stack = capture.stack;\r
+\r
+    Error.prepareStackTrace = v8;\r
+\r
+    var trace = exports.formatStack(stack);\r
+\r
+    if (slice) {\r
+        return trace.slice(slice);\r
+    }\r
+\r
+    return trace;\r
+};\r
+\r
+\r
+exports.displayStack = function (slice) {\r
+\r
+    var trace = exports.callStack(slice === undefined ? 1 : slice + 1);\r
+\r
+    return exports.formatTrace(trace);\r
+};\r
+\r
+\r
+exports.abortThrow = false;\r
+\r
+\r
+exports.abort = function (message, hideStack) {\r
+\r
+    if (process.env.NODE_ENV === 'test' || exports.abortThrow === true) {\r
+        throw new Error(message || 'Unknown error');\r
+    }\r
+\r
+    var stack = '';\r
+    if (!hideStack) {\r
+        stack = exports.displayStack(1).join('\n\t');\r
+    }\r
+    console.log('ABORT: ' + message + '\n\t' + stack);\r
+    process.exit(1);\r
+};\r
+\r
+\r
+exports.assert = function (condition /*, msg1, msg2, msg3 */) {\r
+\r
+    if (condition) {\r
+        return;\r
+    }\r
+\r
+    var msgs = Array.prototype.slice.call(arguments, 1);\r
+    msgs = msgs.map(function (msg) {\r
+\r
+        return typeof msg === 'string' ? msg : msg instanceof Error ? msg.message : JSON.stringify(msg);\r
+    });\r
+    throw new Error(msgs.join(' ') || 'Unknown error');\r
+};\r
+\r
+\r
+exports.loadDirModules = function (path, excludeFiles, target) {      // target(filename, name, capName)\r
+\r
+    var exclude = {};\r
+    for (var i = 0, il = excludeFiles.length; i < il; ++i) {\r
+        exclude[excludeFiles[i] + '.js'] = true;\r
+    }\r
+\r
+    var files = Fs.readdirSync(path);\r
+    for (i = 0, il = files.length; i < il; ++i) {\r
+        var filename = files[i];\r
+        if (/\.js$/.test(filename) &&\r
+            !exclude[filename]) {\r
+\r
+            var name = filename.substr(0, filename.lastIndexOf('.'));\r
+            var capName = name.charAt(0).toUpperCase() + name.substr(1).toLowerCase();\r
+\r
+            if (typeof target !== 'function') {\r
+                target[capName] = require(path + '/' + name);\r
+            }\r
+            else {\r
+                target(path + '/' + name, name, capName);\r
+            }\r
+        }\r
+    }\r
+};\r
+\r
+\r
+exports.rename = function (obj, from, to) {\r
+\r
+    obj[to] = obj[from];\r
+    delete obj[from];\r
+};\r
+\r
+\r
+exports.Timer = function () {\r
+\r
+    this.reset();\r
+};\r
+\r
+\r
+exports.Timer.prototype.reset = function () {\r
+\r
+    this.ts = Date.now();\r
+};\r
+\r
+\r
+exports.Timer.prototype.elapsed = function () {\r
+\r
+    return Date.now() - this.ts;\r
+};\r
+\r
+\r
+// Load and parse package.json process root or given directory\r
+\r
+exports.loadPackage = function (dir) {\r
+\r
+    var result = {};\r
+    var filepath = (dir || process.env.PWD) + '/package.json';\r
+    if (Fs.existsSync(filepath)) {\r
+        try {\r
+            result = JSON.parse(Fs.readFileSync(filepath));\r
+        }\r
+        catch (e) { }\r
+    }\r
+\r
+    return result;\r
+};\r
+\r
+\r
+// Escape string for Regex construction\r
+\r
+exports.escapeRegex = function (string) {\r
+\r
+    // Escape ^$.*+-?=!:|\/()[]{},\r
+    return string.replace(/[\^\$\.\*\+\-\?\=\!\:\|\\\/\(\)\[\]\{\}\,]/g, '\\$&');\r
+};\r
+\r
+\r
+// Return an error as first argument of a callback\r
+\r
+exports.toss = function (condition /*, [message], next */) {\r
+\r
+    var message = (arguments.length === 3 ? arguments[1] : '');\r
+    var next = (arguments.length === 3 ? arguments[2] : arguments[1]);\r
+\r
+    var err = (message instanceof Error ? message : (message ? new Error(message) : (condition instanceof Error ? condition : new Error())));\r
+\r
+    if (condition instanceof Error ||\r
+        !condition) {\r
+\r
+        return next(err);\r
+    }\r
+};\r
+\r
+\r
+// Base64url (RFC 4648) encode\r
+\r
+exports.base64urlEncode = function (value) {\r
+\r
+    return (new Buffer(value, 'binary')).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');\r
+};\r
+\r
+\r
+// Base64url (RFC 4648) decode\r
+\r
+exports.base64urlDecode = function (encoded) {\r
+\r
+    if (encoded &&\r
+        !encoded.match(/^[\w\-]*$/)) {\r
+\r
+        return new Error('Invalid character');\r
+    }\r
+\r
+    try {\r
+        return (new Buffer(encoded.replace(/-/g, '+').replace(/:/g, '/'), 'base64')).toString('binary');\r
+    }\r
+    catch (err) {\r
+        return err;\r
+    }\r
+};\r
+\r
+\r
+// Escape attribute value for use in HTTP header\r
+\r
+exports.escapeHeaderAttribute = function (attribute) {\r
+\r
+    // Allowed value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9, \, "\r
+\r
+    exports.assert(attribute.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~\"\\]*$/), 'Bad attribute value (' + attribute + ')');\r
+\r
+    return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"');                             // Escape quotes and slash\r
+};\r
+\r
+\r
+exports.escapeHtml = function (string) {\r
+\r
+    return Escape.escapeHtml(string);\r
+};\r
+\r
+\r
+exports.escapeJavaScript = function (string) {\r
+\r
+    return Escape.escapeJavaScript(string);\r
+};\r
+\r
+\r
+/*\r
+var event = {\r
+    timestamp: now.getTime(),\r
+    tags: ['tag'],\r
+    data: { some: 'data' }\r
+};\r
+*/\r
+\r
+exports.consoleFunc = console.log;\r
+\r
+exports.printEvent = function (event) {\r
+\r
+    var pad = function (value) {\r
+\r
+        return (value < 10 ? '0' : '') + value;\r
+    };\r
+\r
+    var now = new Date(event.timestamp);\r
+    var timestring = (now.getYear() - 100).toString() +\r
+        pad(now.getMonth() + 1) +\r
+        pad(now.getDate()) +\r
+        '/' +\r
+        pad(now.getHours()) +\r
+        pad(now.getMinutes()) +\r
+        pad(now.getSeconds()) +\r
+        '.' +\r
+        now.getMilliseconds();\r
+\r
+    var data = event.data;\r
+    if (typeof event.data !== 'string') {\r
+        try {\r
+            data = JSON.stringify(event.data);\r
+        }\r
+        catch (e) {\r
+            data = 'JSON Error: ' + e.message;\r
+        }\r
+    }\r
+\r
+    var output = timestring + ', ' + event.tags[0] + ', ' + data;\r
+    exports.consoleFunc(output);\r
+};\r
+\r
+\r
+exports.nextTick = function (callback) {\r
+\r
+    return function () {\r
+\r
+        var args = arguments;\r
+        process.nextTick(function () {\r
+\r
+            callback.apply(null, args);\r
+        });\r
+    };\r
+};\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/package.json b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/package.json
new file mode 100755 (executable)
index 0000000..152a5de
--- /dev/null
@@ -0,0 +1,52 @@
+{
+  "name": "hoek",
+  "description": "General purpose node utilities",
+  "version": "0.9.1",
+  "author": {
+    "name": "Eran Hammer",
+    "email": "eran@hueniverse.com",
+    "url": "http://hueniverse.com"
+  },
+  "contributors": [
+    {
+      "name": "Van Nguyen",
+      "email": "the.gol.effect@gmail.com"
+    }
+  ],
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/spumko/hoek"
+  },
+  "main": "index",
+  "keywords": [
+    "utilities"
+  ],
+  "engines": {
+    "node": ">=0.8.0"
+  },
+  "dependencies": {},
+  "devDependencies": {
+    "lab": "0.1.x",
+    "complexity-report": "0.x.x"
+  },
+  "scripts": {
+    "test": "make test-cov"
+  },
+  "licenses": [
+    {
+      "type": "BSD",
+      "url": "http://github.com/spumko/hoek/raw/master/LICENSE"
+    }
+  ],
+  "readme": "<a href=\"https://github.com/spumko\"><img src=\"https://raw.github.com/spumko/spumko/master/images/from.png\" align=\"right\" /></a>\r\n![hoek Logo](https://raw.github.com/spumko/hoek/master/images/hoek.png)\r\n\r\nGeneral purpose node utilities\r\n\r\n[![Build Status](https://secure.travis-ci.org/spumko/hoek.png)](http://travis-ci.org/spumko/hoek)\r\n\r\n# Table of Contents\r\n\r\n* [Introduction](#introduction \"Introduction\")\r\n* [Object](#object \"Object\")\r\n  * [clone](#cloneobj \"clone\")\r\n  * [merge](#mergetarget-source-isnulloverride-ismergearrays \"merge\")\r\n  * [applyToDefaults](#applytodefaultsdefaults-options \"applyToDefaults\")\r\n  * [unique](#uniquearray-key \"unique\")\r\n  * [mapToObject](#maptoobjectarray-key \"mapToObject\")\r\n  * [intersect](#intersectarray1-array2 \"intersect\")\r\n  * [matchKeys](#matchkeysobj-keys \"matchKeys\")\r\n  * [flatten](#flattenarray-target \"flatten\")\r\n  * [removeKeys](#removekeysobject-keys \"removeKeys\")\r\n  * [reach](#reachobj-chain \"reach\")\r\n  * [inheritAsync](#inheritasyncself-obj-keys \"inheritAsync\")\r\n  * [rename](#renameobj-from-to \"rename\")\r\n* [Timer](#timer \"Timer\")\r\n* [Binary Encoding/Decoding](#binary \"Binary Encoding/Decoding\")\r\n  * [base64urlEncode](#binary64urlEncodevalue \"binary64urlEncode\")\r\n  * [base64urlDecode](#binary64urlDecodevalue \"binary64urlDecode\")\r\n* [Escaping Characters](#escaped \"Escaping Characters\")\r\n  * [escapeHtml](#escapeHtmlstring \"escapeHtml\")\r\n  * [escapeHeaderAttribute](#escapeHeaderAttributeattribute \"escapeHeaderAttribute\")\r\n  * [escapeRegex](#escapeRegexstring \"escapeRegex\")\r\n* [Errors](#errors \"Errors\")\r\n  * [assert](#assertmessage \"assert\")\r\n  * [abort](#abortmessage \"abort\")\r\n  * [displayStack](#displayStackslice \"displayStack\")\r\n  * [callStack](#callStackslice \"callStack\")\r\n  * [toss](#tosscondition \"toss\")\r\n* [Load files](#load-files \"Load Files\")\r\n  * [loadPackage](#loadPackagedir \"loadpackage\")\r\n  * [loadDirModules](#loadDirModulespath-excludefiles-target \"loaddirmodules\")\r\n\r\n\r\n\r\n# Introduction\r\n\r\nThe *Hoek* general purpose node utilities library is used to aid in a variety of manners. It comes with useful methods for Arrays (clone, merge, applyToDefaults), Objects (removeKeys, copy), Asserting and more. \r\n\r\nFor example, to use Hoek to set configuration with default options:\r\n```javascript\r\nvar Hoek = require('hoek');\r\n\r\nvar default = {url : \"www.github.com\", port : \"8000\", debug : true}\r\n\r\nvar config = Hoek.applyToDefaults(default, {port : \"3000\", admin : true});\r\n\r\n// In this case, config would be { url: 'www.github.com', port: '3000', debug: true, admin: true }\r\n```\r\n\r\nUnder each of the sections (such as Array), there are subsections which correspond to Hoek methods. Each subsection will explain how to use the corresponding method. In each js excerpt below, the var Hoek = require('hoek') is omitted for brevity.\r\n\r\n## Object\r\n\r\nHoek provides several helpful methods for objects and arrays.\r\n\r\n### clone(obj)\r\n\r\nThis method is used to clone an object or an array. A *deep copy* is made (duplicates everything, including values that are objects). \r\n\r\n```javascript\r\n\r\nvar nestedObj = {\r\n        w: /^something$/ig,\r\n        x: {\r\n            a: [1, 2, 3],\r\n            b: 123456,\r\n            c: new Date()\r\n        },\r\n        y: 'y',\r\n        z: new Date()\r\n    };\r\n\r\nvar copy = Hoek.clone(nestedObj);\r\n\r\ncopy.x.b = 100;\r\n\r\nconsole.log(copy.y)        // results in 'y'\r\nconsole.log(nestedObj.x.b) // results in 123456\r\nconsole.log(copy.x.b)      // results in 100\r\n```\r\n\r\n### merge(target, source, isNullOverride, isMergeArrays)\r\nisNullOverride, isMergeArrays default to true\r\n\r\nMerge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied\r\n\r\n\r\n```javascript\r\n\r\nvar target = {a: 1, b : 2}\r\nvar source = {a: 0, c: 5}\r\nvar source2 = {a: null, c: 5}\r\n\r\nvar targetArray = [1, 2, 3];\r\nvar sourceArray = [4, 5];\r\n\r\nvar newTarget = Hoek.merge(target, source);     // results in {a: 0, b: 2, c: 5}\r\nnewTarget = Hoek.merge(target, source2);        // results in {a: null, b: 2, c: 5}\r\nnewTarget = Hoek.merge(target, source2, false); // results in {a: 1, b: 2, c: 5}\r\n\r\nnewTarget = Hoek.merge(targetArray, sourceArray)              // results in [1, 2, 3, 4, 5]\r\nnewTarget = Hoek.merge(targetArray, sourceArray, true, false) // results in [4, 5]\r\n\r\n\r\n\r\n\r\n```\r\n\r\n### applyToDefaults(defaults, options)\r\n\r\nApply options to a copy of the defaults\r\n\r\n```javascript\r\n\r\nvar defaults = {host: \"localhost\", port: 8000};\r\nvar options = {port: 8080};\r\n\r\nvar config = Hoek.applyToDefaults(defaults, options); // results in {host: \"localhost\", port: 8080};\r\n\r\n\r\n```\r\n\r\n### unique(array, key)\r\n\r\nRemove duplicate items from Array\r\n\r\n```javascript\r\n\r\nvar array = [1, 2, 2, 3, 3, 4, 5, 6];\r\n\r\nvar newArray = Hoek.unique(array); // results in [1,2,3,4,5,6];\r\n\r\narray = [{id: 1}, {id: 1}, {id: 2}];\r\n\r\nnewArray = Hoek.unique(array, \"id\") // results in [{id: 1}, {id: 2}]\r\n\r\n```\r\n\r\n### mapToObject(array, key)\r\n\r\nConvert an Array into an Object\r\n\r\n```javascript\r\n\r\nvar array = [1,2,3];\r\nvar newObject = Hoek.mapToObject(array); // results in [{\"1\": true}, {\"2\": true}, {\"3\": true}]\r\n\r\narray = [{id: 1}, {id: 2}];\r\nnewObject = Hoek.mapToObject(array, \"id\") // results in [{\"id\": 1}, {\"id\": 2}]\r\n\r\n```\r\n### intersect(array1, array2)\r\n\r\nFind the common unique items in two arrays\r\n\r\n```javascript\r\n\r\nvar array1 = [1, 2, 3];\r\nvar array2 = [1, 4, 5];\r\n\r\nvar newArray = Hoek.intersect(array1, array2) // results in [1]\r\n\r\n```\r\n\r\n### matchKeys(obj, keys) \r\n\r\nFind which keys are present\r\n\r\n```javascript\r\n\r\nvar obj = {a: 1, b: 2, c: 3};\r\nvar keys = [\"a\", \"e\"];\r\n\r\nHoek.matchKeys(obj, keys) // returns [\"a\"]\r\n\r\n```\r\n\r\n### flatten(array, target)\r\n\r\nFlatten an array\r\n\r\n```javascript\r\n\r\nvar array = [1, 2, 3];\r\nvar target = [4, 5]; \r\n\r\nvar flattenedArray = Hoek.flatten(array, target) // results in [4, 5, 1, 2, 3];\r\n\r\n```\r\n\r\n### removeKeys(object, keys)\r\n\r\nRemove keys\r\n\r\n```javascript\r\n\r\nvar object = {a: 1, b: 2, c: 3, d: 4};\r\n\r\nvar keys = [\"a\", \"b\"];\r\n\r\nHoek.removeKeys(object, keys) // object is now {c: 3, d: 4}\r\n\r\n```\r\n\r\n### reach(obj, chain)\r\n\r\nConverts an object key chain string to reference\r\n\r\n```javascript\r\n\r\nvar chain = 'a.b.c';\r\nvar obj = {a : {b : { c : 1}}};\r\n\r\nHoek.reach(obj, chain) // returns 1\r\n\r\n```\r\n\r\n### inheritAsync(self, obj, keys) \r\n\r\nInherits a selected set of methods from an object, wrapping functions in asynchronous syntax and catching errors\r\n\r\n```javascript\r\n\r\nvar targetFunc = function () { };\r\n\r\nvar proto = {\r\n                a: function () {\r\n                    return 'a!';\r\n                },\r\n                b: function () {\r\n                    return 'b!';\r\n                },\r\n                c: function () {\r\n                    throw new Error('c!');\r\n                }\r\n            };\r\n\r\nvar keys = ['a', 'c'];\r\n\r\nHoek.inheritAsync(targetFunc, proto, ['a', 'c']);\r\n\r\nvar target = new targetFunc();\r\n\r\ntarget.a(function(err, result){console.log(result)}         // returns 'a!'       \r\n\r\ntarget.c(function(err, result){console.log(result)}         // returns undefined\r\n\r\ntarget.b(function(err, result){console.log(result)}         // gives error: Object [object Object] has no method 'b'\r\n\r\n```\r\n\r\n### rename(obj, from, to)\r\n\r\nRename a key of an object\r\n\r\n```javascript\r\n\r\nvar obj = {a : 1, b : 2};\r\n\r\nHoek.rename(obj, \"a\", \"c\");     // obj is now {c : 1, b : 2}\r\n\r\n```\r\n\r\n\r\n# Timer\r\n\r\nA Timer object. Initializing a new timer object sets the ts to the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.\r\n\r\n```javascript\r\n\r\n\r\nexample : \r\n\r\n\r\nvar timerObj = new Hoek.Timer();\r\nconsole.log(\"Time is now: \" + timerObj.ts)\r\nconsole.log(\"Elapsed time from initialization: \" + timerObj.elapsed() + 'milliseconds')\r\n\r\n```\r\n\r\n# Binary Encoding/Decoding\r\n\r\n### base64urlEncode(value)\r\n\r\nEncodes value in Base64 or URL encoding\r\n\r\n### base64urlDecode(value)\r\n\r\nDecodes data in Base64 or URL encoding.\r\n# Escaping Characters\r\n\r\nHoek provides convenient methods for escaping html characters. The escaped characters are as followed:\r\n\r\n```javascript\r\n\r\ninternals.htmlEscaped = {\r\n    '&': '&amp;',\r\n    '<': '&lt;',\r\n    '>': '&gt;',\r\n    '\"': '&quot;',\r\n    \"'\": '&#x27;',\r\n    '`': '&#x60;'\r\n};\r\n\r\n```\r\n\r\n### escapeHtml(string)\r\n\r\n```javascript\r\n\r\nvar string = '<html> hey </html>';\r\nvar escapedString = Hoek.escapeHtml(string); // returns &lt;html&gt; hey &lt;/html&gt;\r\n\r\n```\r\n\r\n### escapeHeaderAttribute(attribute)\r\n\r\nEscape attribute value for use in HTTP header\r\n\r\n```javascript\r\n\r\nvar a = Hoek.escapeHeaderAttribute('I said \"go w\\\\o me\"');  //returns I said \\\"go w\\\\o me\\\"\r\n\r\n\r\n```\r\n\r\n\r\n### escapeRegex(string)\r\n\r\nEscape string for Regex construction\r\n\r\n```javascript\r\n\r\nvar a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\\\/`\"(>)[<]d{}s,');  // returns 4\\^f\\$s\\.4\\*5\\+\\-_\\?%\\=#\\!\\:@\\|~\\\\\\/`\"\\(>\\)\\[<\\]d\\{\\}s\\,\r\n\r\n\r\n\r\n```\r\n\r\n# Errors\r\n\r\n### assert(message)\r\n\r\n```javascript\r\n\r\nvar a = 1, b =2;\r\n\r\nHoek.assert(a === b, 'a should equal b');  // ABORT: a should equal b\r\n\r\n```\r\n\r\n### abort(message)\r\n\r\nFirst checks if process.env.NODE_ENV === 'test', and if so, throws error message. Otherwise,\r\ndisplays most recent stack and then exits process.\r\n\r\n\r\n\r\n### displayStack(slice)\r\n\r\nDisplays the trace stack\r\n\r\n```javascript\r\n\r\nvar stack = Hoek.displayStack();\r\nconsole.log(stack) // returns something like:\r\n\r\n[ 'null (/Users/user/Desktop/hoek/test.js:4:18)',\r\n  'Module._compile (module.js:449:26)',\r\n  'Module._extensions..js (module.js:467:10)',\r\n  'Module.load (module.js:356:32)',\r\n  'Module._load (module.js:312:12)',\r\n  'Module.runMain (module.js:492:10)',\r\n  'startup.processNextTick.process._tickCallback (node.js:244:9)' ]\r\n\r\n```\r\n\r\n### callStack(slice)\r\n\r\nReturns a trace stack array.\r\n\r\n```javascript\r\n\r\nvar stack = Hoek.callStack();\r\nconsole.log(stack)  // returns something like:\r\n\r\n[ [ '/Users/user/Desktop/hoek/test.js', 4, 18, null, false ],\r\n  [ 'module.js', 449, 26, 'Module._compile', false ],\r\n  [ 'module.js', 467, 10, 'Module._extensions..js', false ],\r\n  [ 'module.js', 356, 32, 'Module.load', false ],\r\n  [ 'module.js', 312, 12, 'Module._load', false ],\r\n  [ 'module.js', 492, 10, 'Module.runMain', false ],\r\n  [ 'node.js',\r\n    244,\r\n    9,\r\n    'startup.processNextTick.process._tickCallback',\r\n    false ] ]\r\n\r\n\r\n```\r\n\r\n### toss(condition)\r\n\r\ntoss(condition /*, [message], callback */)\r\n\r\nReturn an error as first argument of a callback\r\n\r\n\r\n# Load Files\r\n\r\n### loadPackage(dir)\r\n\r\nLoad and parse package.json process root or given directory\r\n\r\n```javascript\r\n\r\nvar pack = Hoek.loadPackage();  // pack.name === 'hoek'\r\n\r\n```\r\n\r\n### loadDirModules(path, excludeFiles, target) \r\n\r\nLoads modules from a given path; option to exclude files (array).\r\n\r\n\r\n\r\n\r\n",
+  "readmeFilename": "README.md",
+  "bugs": {
+    "url": "https://github.com/spumko/hoek/issues"
+  },
+  "_id": "hoek@0.9.1",
+  "dist": {
+    "shasum": "396f2118033eabc93ae5c2cd6ca75f0a89c03592"
+  },
+  "_from": "hoek@0.9.x",
+  "_resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz"
+}
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/escaper.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/escaper.js
new file mode 100644 (file)
index 0000000..4dddd77
--- /dev/null
@@ -0,0 +1,86 @@
+// Load modules\r
+\r
+var Lab = require('lab');\r
+var Hoek = require('../lib');\r
+\r
+\r
+// Declare internals\r
+\r
+var internals = {};\r
+\r
+\r
+// Test shortcuts\r
+\r
+var expect = Lab.expect;\r
+var before = Lab.before;\r
+var after = Lab.after;\r
+var describe = Lab.experiment;\r
+var it = Lab.test;\r
+\r
+\r
+describe('Hoek', function () {\r
+\r
+    describe('#escapeJavaScript', function () {\r
+\r
+        it('encodes / characters', function (done) {\r
+\r
+            var encoded = Hoek.escapeJavaScript('<script>alert(1)</script>');\r
+            expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e');\r
+            done();\r
+        });\r
+\r
+        it('encodes \' characters', function (done) {\r
+\r
+            var encoded = Hoek.escapeJavaScript('something(\'param\')');\r
+            expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29');\r
+            done();\r
+        });\r
+\r
+        it('encodes large unicode characters with the correct padding', function (done) {\r
+\r
+            var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000));\r
+            expect(encoded).to.equal('\\u0500\\u1000');\r
+            done();\r
+        });\r
+\r
+        it('doesn\'t throw an exception when passed null', function (done) {\r
+\r
+            var encoded = Hoek.escapeJavaScript(null);\r
+            expect(encoded).to.equal('');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#escapeHtml', function () {\r
+\r
+        it('encodes / characters', function (done) {\r
+\r
+            var encoded = Hoek.escapeHtml('<script>alert(1)</script>');\r
+            expect(encoded).to.equal('&lt;script&gt;alert&#x28;1&#x29;&lt;&#x2f;script&gt;');\r
+            done();\r
+        });\r
+\r
+        it('encodes < and > as named characters', function (done) {\r
+\r
+            var encoded = Hoek.escapeHtml('<script><>');\r
+            expect(encoded).to.equal('&lt;script&gt;&lt;&gt;');\r
+            done();\r
+        });\r
+\r
+        it('encodes large unicode characters', function (done) {\r
+\r
+            var encoded = Hoek.escapeHtml(String.fromCharCode(500) + String.fromCharCode(1000));\r
+            expect(encoded).to.equal('&#500;&#1000;');\r
+            done();\r
+        });\r
+\r
+        it('doesn\'t throw an exception when passed null', function (done) {\r
+\r
+            var encoded = Hoek.escapeHtml(null);\r
+            expect(encoded).to.equal('');\r
+            done();\r
+        });\r
+    });\r
+});\r
+\r
+\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/index.js
new file mode 100755 (executable)
index 0000000..c40e3ad
--- /dev/null
@@ -0,0 +1,1078 @@
+// Load modules\r
+\r
+var Lab = require('lab');\r
+var Hoek = require('../lib');\r
+\r
+\r
+// Declare internals\r
+\r
+var internals = {};\r
+\r
+\r
+// Test shortcuts\r
+\r
+var expect = Lab.expect;\r
+var before = Lab.before;\r
+var after = Lab.after;\r
+var describe = Lab.experiment;\r
+var it = Lab.test;\r
+\r
+\r
+describe('Hoek', function () {\r
+\r
+    var nestedObj = {\r
+        v: [7,8,9],\r
+        w: /^something$/igm,\r
+        x: {\r
+            a: [1, 2, 3],\r
+            b: 123456,\r
+            c: new Date(),\r
+            d: /hi/igm,\r
+            e: /hello/\r
+        },\r
+        y: 'y',\r
+        z: new Date()\r
+    };\r
+\r
+    var dupsArray = [nestedObj, { z: 'z' }, nestedObj];\r
+    var reducedDupsArray = [nestedObj, { z: 'z' }];\r
+\r
+    describe('#clone', function () {\r
+\r
+        it('should clone a nested object', function (done) {\r
+\r
+            var a = nestedObj;\r
+            var b = Hoek.clone(a);\r
+\r
+            expect(a).to.deep.equal(b);\r
+            expect(a.z.getTime()).to.equal(b.z.getTime());\r
+            done();\r
+        });\r
+\r
+        it('should clone a null object', function (done) {\r
+\r
+            var b = Hoek.clone(null);\r
+\r
+            expect(b).to.equal(null);\r
+            done();\r
+        });\r
+\r
+        it('should not convert undefined properties to null', function (done) {\r
+\r
+            var obj = { something: undefined };\r
+            var b = Hoek.clone(obj);\r
+\r
+            expect(typeof b.something).to.equal('undefined');\r
+            done();\r
+        });\r
+\r
+        it('should not throw on circular reference', function (done) {\r
+\r
+            var a = {};\r
+            a.x = a;\r
+\r
+            var test = (function () {\r
+\r
+                var b = Hoek.clone(a);\r
+            });\r
+\r
+            expect(test).to.not.throw();\r
+            done();\r
+        });\r
+\r
+        it('should properly clone circular reference', function (done) {\r
+\r
+            var x = {\r
+                'z': new Date()\r
+            };\r
+            x.y = x;\r
+\r
+            var b = Hoek.clone(x);\r
+            expect(Object.keys(b.y)).to.deep.equal(Object.keys(x))\r
+            expect(b.z).to.not.equal(x.z);\r
+            expect(b.y).to.not.equal(x.y);\r
+            expect(b.y.z).to.not.equal(x.y.z);\r
+            expect(b.y).to.equal(b);\r
+            expect(b.y.y.y.y).to.equal(b);\r
+            done();\r
+        });\r
+\r
+        it('should properly clone deeply nested object', function (done) {\r
+\r
+            var a = {\r
+                x: {\r
+                    y: {\r
+                        a: [1, 2, 3],\r
+                        b: 123456,\r
+                        c: new Date(),\r
+                        d: /hi/igm,\r
+                        e: /hello/\r
+                    },\r
+                }\r
+            };\r
+\r
+            var b = Hoek.clone(a);\r
+\r
+            expect(a).to.deep.equal(b);\r
+            expect(a.x.y.c.getTime()).to.equal(b.x.y.c.getTime());\r
+            done();\r
+        });\r
+\r
+        it('should properly clone arrays', function (done) {\r
+\r
+            var a = [1,2,3];\r
+\r
+            var b = Hoek.clone(a);\r
+\r
+            expect(a).to.deep.equal(b);\r
+            done();\r
+        });\r
+\r
+        it('should perform actual copy for shallow keys (no pass by reference)', function (done) {\r
+\r
+            var x = Hoek.clone(nestedObj);\r
+            var y = Hoek.clone(nestedObj);\r
+\r
+            // Date\r
+            expect(x.z).to.not.equal(nestedObj.z);\r
+            expect(x.z).to.not.equal(y.z);\r
+\r
+            // Regex\r
+            expect(x.w).to.not.equal(nestedObj.w);\r
+            expect(x.w).to.not.equal(y.w);\r
+\r
+            // Array\r
+            expect(x.v).to.not.equal(nestedObj.v);\r
+            expect(x.v).to.not.equal(y.v);\r
+\r
+            // Immutable(s)\r
+            x.y = 5;\r
+            expect(x.y).to.not.equal(nestedObj.y);\r
+            expect(x.y).to.not.equal(y.y);\r
+\r
+            done();\r
+        });\r
+\r
+        it('should perform actual copy for deep keys (no pass by reference)', function (done) {\r
+\r
+            var x = Hoek.clone(nestedObj);\r
+            var y = Hoek.clone(nestedObj);\r
+\r
+            expect(x.x.c).to.not.equal(nestedObj.x.c);\r
+            expect(x.x.c).to.not.equal(y.x.c);\r
+\r
+            expect(x.x.c.getTime()).to.equal(nestedObj.x.c.getTime());\r
+            expect(x.x.c.getTime()).to.equal(y.x.c.getTime());\r
+            done();\r
+        });\r
+\r
+        it('copies functions with properties', function (done) {\r
+\r
+            var a = {\r
+                x: function () { return 1; },\r
+                y: {}\r
+            };\r
+            a.x.z = 'string in function';\r
+            a.x.v = function () { return 2; };\r
+            a.y.u = a.x;\r
+\r
+            var b = Hoek.clone(a);\r
+            expect(b.x()).to.equal(1);\r
+            expect(b.x.v()).to.equal(2);\r
+            expect(b.y.u).to.equal(b.x);\r
+            expect(b.x.z).to.equal('string in function');\r
+            done();\r
+        });\r
+\r
+        it('should copy a buffer', function(done){\r
+            var tls = {\r
+                key: new Buffer([1,2,3,4,5]),\r
+                cert: new Buffer([1,2,3,4,5,6,10])\r
+            }\r
+\r
+            copiedTls = Hoek.clone(tls);\r
+            expect(Buffer.isBuffer(copiedTls.key)).to.equal(true);\r
+            expect(JSON.stringify(copiedTls.key)).to.equal(JSON.stringify(tls.key))\r
+            expect(Buffer.isBuffer(copiedTls.cert)).to.equal(true);\r
+            expect(JSON.stringify(copiedTls.cert)).to.equal(JSON.stringify(tls.cert))\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#merge', function () {\r
+\r
+        it('does not throw if source is null', function (done) {\r
+\r
+            var a = {};\r
+            var b = null;\r
+            var c = null;\r
+\r
+            expect(function () {\r
+\r
+                c = Hoek.merge(a, b);\r
+            }).to.not.throw();\r
+\r
+            expect(c).to.equal(a);\r
+            done();\r
+        });\r
+\r
+        it('does not throw if source is undefined', function (done) {\r
+\r
+            var a = {};\r
+            var b = undefined;\r
+            var c = null;\r
+\r
+            expect(function () {\r
+\r
+                c = Hoek.merge(a, b);\r
+            }).to.not.throw();\r
+\r
+            expect(c).to.equal(a);\r
+            done();\r
+        });\r
+\r
+        it('throws if source is not an object', function (done) {\r
+\r
+            expect(function () {\r
+\r
+                var a = {};\r
+                var b = 0;\r
+\r
+                Hoek.merge(a, b);\r
+            }).to.throw('Invalid source value: must be null, undefined, or an object');\r
+            done();\r
+        });\r
+\r
+        it('throws if target is not an object', function (done) {\r
+\r
+            expect(function () {\r
+\r
+                var a = 0;\r
+                var b = {};\r
+\r
+                Hoek.merge(a, b);\r
+            }).to.throw('Invalid target value: must be an object');\r
+            done();\r
+        });\r
+\r
+        it('throws if target is not an array and source is', function (done) {\r
+\r
+            expect(function () {\r
+\r
+                var a = {};\r
+                var b = [1, 2];\r
+\r
+                Hoek.merge(a, b);\r
+            }).to.throw('Cannot merge array onto an object');\r
+            done();\r
+        });\r
+\r
+        it('returns the same object when merging arrays', function (done) {\r
+\r
+            var a = [];\r
+            var b = [1, 2];\r
+\r
+            expect(Hoek.merge(a, b)).to.equal(a);\r
+            done();\r
+        });\r
+\r
+        it('should combine an empty object with a non-empty object', function (done) {\r
+\r
+            var a = {};\r
+            var b = nestedObj;\r
+\r
+            var c = Hoek.merge(a, b);\r
+            expect(a).to.deep.equal(b);\r
+            expect(c).to.deep.equal(b);\r
+            done();\r
+        });\r
+\r
+        it('should override values in target', function (done) {\r
+\r
+            var a = { x: 1, y: 2, z: 3, v: 5, t: 'test', m: 'abc' };\r
+            var b = { x: null, z: 4, v: 0, t: { u: 6 }, m: '123' };\r
+\r
+            var c = Hoek.merge(a, b);\r
+            expect(c.x).to.equal(null);\r
+            expect(c.y).to.equal(2);\r
+            expect(c.z).to.equal(4);\r
+            expect(c.v).to.equal(0);\r
+            expect(c.m).to.equal('123');\r
+            expect(c.t).to.deep.equal({ u: 6 });\r
+            done();\r
+        });\r
+\r
+        it('should override values in target (flip)', function (done) {\r
+\r
+            var a = { x: 1, y: 2, z: 3, v: 5, t: 'test', m: 'abc' };\r
+            var b = { x: null, z: 4, v: 0, t: { u: 6 }, m: '123' };\r
+\r
+            var d = Hoek.merge(b, a);\r
+            expect(d.x).to.equal(1);\r
+            expect(d.y).to.equal(2);\r
+            expect(d.z).to.equal(3);\r
+            expect(d.v).to.equal(5);\r
+            expect(d.m).to.equal('abc');\r
+            expect(d.t).to.deep.equal('test');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#applyToDefaults', function () {\r
+\r
+        var defaults = {\r
+            a: 1,\r
+            b: 2,\r
+            c: {\r
+                d: 3,\r
+                e: [5, 6]\r
+            },\r
+            f: 6,\r
+            g: 'test'\r
+        };\r
+\r
+        it('should return null if options is false', function (done) {\r
+\r
+            var result = Hoek.applyToDefaults(defaults, false);\r
+            expect(result).to.equal(null);\r
+            done();\r
+        });\r
+\r
+        it('should return a copy of defaults if options is true', function (done) {\r
+\r
+            var result = Hoek.applyToDefaults(defaults, true);\r
+            expect(result).to.deep.equal(result);\r
+            done();\r
+        });\r
+\r
+        it('should apply object to defaults', function (done) {\r
+\r
+            var obj = {\r
+                a: null,\r
+                c: {\r
+                    e: [4]\r
+                },\r
+                f: 0,\r
+                g: {\r
+                    h: 5\r
+                }\r
+            };\r
+\r
+            var result = Hoek.applyToDefaults(defaults, obj);\r
+            expect(result.c.e).to.deep.equal([4]);\r
+            expect(result.a).to.equal(1);\r
+            expect(result.b).to.equal(2);\r
+            expect(result.f).to.equal(0);\r
+            expect(result.g).to.deep.equal({ h: 5 });\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#unique', function () {\r
+\r
+        it('should ensure uniqueness within array of objects based on subkey', function (done) {\r
+\r
+            var a = Hoek.unique(dupsArray, 'x');\r
+            expect(a).to.deep.equal(reducedDupsArray);\r
+            done();\r
+        });\r
+\r
+        it('removes duplicated without key', function (done) {\r
+\r
+            expect(Hoek.unique([1, 2, 3, 4, 2, 1, 5])).to.deep.equal([1, 2, 3, 4, 5]);\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#mapToObject', function () {\r
+\r
+        it('should return null on null array', function (done) {\r
+\r
+            var a = Hoek.mapToObject(null);\r
+            expect(a).to.equal(null);\r
+            done();\r
+        });\r
+\r
+        it('should convert basic array to existential object', function (done) {\r
+\r
+            var keys = [1, 2, 3, 4];\r
+            var a = Hoek.mapToObject(keys);\r
+            for (var i in keys) {\r
+                expect(a[keys[i]]).to.equal(true);\r
+            }\r
+            done();\r
+        });\r
+\r
+        it('should convert array of objects to existential object', function (done) {\r
+\r
+            var keys = [{ x: 1 }, { x: 2 }, { x: 3 }];\r
+            var subkey = 'x';\r
+            var a = Hoek.mapToObject(keys, subkey);\r
+            for (var i in keys) {\r
+                expect(a[keys[i][subkey]]).to.equal(true);\r
+            }\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#intersect', function () {\r
+\r
+        it('should return the common objects of two arrays', function (done) {\r
+\r
+            var array1 = [1, 2, 3, 4, 4, 5, 5];\r
+            var array2 = [5, 4, 5, 6, 7];\r
+            var common = Hoek.intersect(array1, array2);\r
+            expect(common.length).to.equal(2);\r
+            done();\r
+        });\r
+\r
+        it('should return just the first common object of two arrays', function (done) {\r
+\r
+            var array1 = [1, 2, 3, 4, 4, 5, 5];\r
+            var array2 = [5, 4, 5, 6, 7];\r
+            var common = Hoek.intersect(array1, array2, true);\r
+            expect(common).to.equal(5);\r
+            done();\r
+        });\r
+\r
+        it('should return an empty array if either input is null', function (done) {\r
+\r
+            expect(Hoek.intersect([1], null).length).to.equal(0);\r
+            expect(Hoek.intersect(null, [1]).length).to.equal(0);\r
+            done();\r
+        });\r
+\r
+        it('should return the common objects of object and array', function (done) {\r
+\r
+            var array1 = [1, 2, 3, 4, 4, 5, 5];\r
+            var array2 = [5, 4, 5, 6, 7];\r
+            var common = Hoek.intersect(Hoek.mapToObject(array1), array2);\r
+            expect(common.length).to.equal(2);\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#matchKeys', function () {\r
+\r
+        it('should match the existing object keys', function (done) {\r
+\r
+            var obj = {\r
+                a: 1,\r
+                b: 2,\r
+                c: 3,\r
+                d: null\r
+            };\r
+\r
+            expect(Hoek.matchKeys(obj, ['b', 'c', 'd', 'e'])).to.deep.equal(['b', 'c', 'd']);\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#flatten', function () {\r
+\r
+        it('should return a flat array', function (done) {\r
+\r
+            var result = Hoek.flatten([1, 2, [3, 4, [5, 6], [7], 8], [9], [10, [11, 12]], 13]);\r
+            expect(result.length).to.equal(13);\r
+            expect(result).to.deep.equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#removeKeys', function () {\r
+\r
+        var objWithHiddenKeys = {\r
+            location: {\r
+                name: 'San Bruno'\r
+            },\r
+            company: {\r
+                name: '@WalmartLabs'\r
+            }\r
+        };\r
+\r
+        it('should delete params with definition\'s hide set to true', function (done) {\r
+\r
+            var a = Hoek.removeKeys(objWithHiddenKeys, ['location']);\r
+            expect(objWithHiddenKeys.location).to.not.exist;\r
+            expect(objWithHiddenKeys.company).to.exist;\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#reach', function () {\r
+\r
+        var obj = {\r
+            a: {\r
+                b: {\r
+                    c: {\r
+                        d: 1,\r
+                        e: 2\r
+                    },\r
+                    f: 'hello'\r
+                },\r
+                g: {\r
+                    h: 3\r
+                }\r
+            },\r
+            i: function () { }\r
+        };\r
+\r
+        it('returns a valid member', function (done) {\r
+\r
+            expect(Hoek.reach(obj, 'a.b.c.d')).to.equal(1);\r
+            done();\r
+        });\r
+\r
+        it('returns null on null object', function (done) {\r
+\r
+            expect(Hoek.reach(null, 'a.b.c.d')).to.not.exist;\r
+            done();\r
+        });\r
+\r
+        it('returns null on missing member', function (done) {\r
+\r
+            expect(Hoek.reach(obj, 'a.b.c.d.x')).to.not.exist;\r
+            done();\r
+        });\r
+\r
+        it('returns null on invalid member', function (done) {\r
+\r
+            expect(Hoek.reach(obj, 'a.b.c.d-.x')).to.not.exist;\r
+            done();\r
+        });\r
+\r
+        it('returns function member', function (done) {\r
+\r
+            expect(typeof Hoek.reach(obj, 'i')).to.equal('function');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#inheritAsync', function () {\r
+\r
+        it('should inherit selected methods and wrap in async call', function (done) {\r
+\r
+            var proto = {\r
+                a: function () {\r
+                    return 'a!';\r
+                },\r
+                b: function () {\r
+                    return 'b!';\r
+                },\r
+                c: function () {\r
+                    throw new Error('c!');\r
+                }\r
+            };\r
+\r
+            var targetFunc = function () { };\r
+            targetFunc.prototype.c = function () {\r
+\r
+                return 'oops';\r
+            };\r
+\r
+            Hoek.inheritAsync(targetFunc, proto, ['a', 'c']);\r
+            var target = new targetFunc();\r
+\r
+            expect(typeof target.a).to.equal('function');\r
+            expect(typeof target.c).to.equal('function');\r
+            expect(target.b).to.not.exist;\r
+\r
+            target.a(function (err, result) {\r
+\r
+                expect(err).to.not.exist;\r
+                expect(result).to.equal('a!');\r
+\r
+                target.c(function (err, result) {\r
+\r
+                    expect(result).to.not.exist;\r
+                    expect(err.message).to.equal('c!');\r
+                    done();\r
+                });\r
+            });\r
+        });\r
+    });\r
+\r
+    describe('#callStack', function () {\r
+\r
+        it('should return the full call stack', function (done) {\r
+\r
+            var stack = Hoek.callStack();\r
+            expect(stack[0][0]).to.contain('index.js');\r
+            expect(stack[0][2]).to.equal(30);\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#displayStack ', function () {\r
+\r
+        it('should return the full call stack for display', function (done) {\r
+\r
+            var stack = Hoek.displayStack();\r
+            expect(stack[0]).to.contain('test/index.js:');\r
+            done();\r
+        });\r
+\r
+        it('should include constructor functions correctly', function (done) {\r
+\r
+            var Something = function (next) {\r
+\r
+                next();\r
+            };\r
+\r
+            var something = new Something(function () {\r
+\r
+                var stack = Hoek.displayStack();\r
+                expect(stack[1]).to.contain('new Something');\r
+                done();\r
+            });\r
+        });\r
+    });\r
+\r
+    describe('#abort', function () {\r
+\r
+        it('should exit process when not in test mode', function (done) {\r
+\r
+            var env = process.env.NODE_ENV;\r
+            var write = process.stdout.write;\r
+            var exit = process.exit;\r
+\r
+            process.env.NODE_ENV = 'nottatest';\r
+            process.stdout.write = function () { };\r
+            process.exit = function (state) {\r
+\r
+                process.exit = exit;\r
+                process.env.NODE_ENV = env;\r
+                process.stdout.write = write;\r
+\r
+                expect(state).to.equal(1);\r
+                done();\r
+            };\r
+\r
+            Hoek.abort('Boom');\r
+        });\r
+\r
+        it('should throw when not in test mode and abortThrow is true', function (done) {\r
+\r
+            var env = process.env.NODE_ENV;\r
+            process.env.NODE_ENV = 'nottatest';\r
+            Hoek.abortThrow = true;\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.abort('my error message');\r
+            };\r
+\r
+            expect(fn).to.throw('my error message');\r
+            Hoek.abortThrow = false;\r
+            process.env.NODE_ENV = env;\r
+\r
+            done();\r
+        });\r
+\r
+\r
+        it('should respect hideStack argument', function (done) {\r
+\r
+            var env = process.env.NODE_ENV;\r
+            var write = process.stdout.write;\r
+            var exit = process.exit;\r
+            var output = '';\r
+\r
+            process.exit = function () { };\r
+            process.env.NODE_ENV = '';\r
+            process.stdout.write = function (message) {\r
+\r
+                output = message;\r
+            };\r
+\r
+            Hoek.abort('my error message', true);\r
+\r
+            process.env.NODE_ENV = env;\r
+            process.stdout.write = write;\r
+            process.exit = exit;\r
+\r
+            expect(output).to.equal('ABORT: my error message\n\t\n');\r
+\r
+            done();\r
+        });\r
+\r
+        it('should default to showing stack', function (done) {\r
+\r
+            var env = process.env.NODE_ENV;\r
+            var write = process.stdout.write;\r
+            var exit = process.exit;\r
+            var output = '';\r
+\r
+            process.exit = function () { };\r
+            process.env.NODE_ENV = '';\r
+            process.stdout.write = function (message) {\r
+\r
+                output = message;\r
+            };\r
+\r
+            Hoek.abort('my error message');\r
+\r
+            process.env.NODE_ENV = env;\r
+            process.stdout.write = write;\r
+            process.exit = exit;\r
+\r
+            expect(output).to.contain('index.js');\r
+\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#assert', function () {\r
+\r
+        it('should throw an Error when using assert in a test', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.assert(false, 'my error message');\r
+            };\r
+\r
+            expect(fn).to.throw('my error message');\r
+            done();\r
+        });\r
+\r
+        it('should throw an Error when using assert in a test with no message', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.assert(false);\r
+            };\r
+\r
+            expect(fn).to.throw('Unknown error');\r
+            done();\r
+        });\r
+\r
+        it('should throw an Error when using assert in a test with multipart message', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.assert(false, 'This', 'is', 'my message');\r
+            };\r
+\r
+            expect(fn).to.throw('This is my message');\r
+            done();\r
+        });\r
+\r
+        it('should throw an Error when using assert in a test with object message', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.assert(false, 'This', 'is', { spinal: 'tap' });\r
+            };\r
+\r
+            expect(fn).to.throw('This is {"spinal":"tap"}');\r
+            done();\r
+        });\r
+\r
+        it('should throw an Error when using assert in a test with error object message', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.assert(false, new Error('This is spinal tap'));\r
+            };\r
+\r
+            expect(fn).to.throw('This is spinal tap');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#loadDirModules', function () {\r
+\r
+        it('should load modules from directory', function (done) {\r
+\r
+            var target = {};\r
+            Hoek.loadDirModules(__dirname + '/modules', ['test2'], target);\r
+            expect(target.Test1.x).to.equal(1);\r
+            expect(target.Test2).to.not.exist;\r
+            expect(target.Test3.z).to.equal(3);\r
+            done();\r
+        });\r
+\r
+        it('should list modules from directory into function', function (done) {\r
+\r
+            var target = {};\r
+            Hoek.loadDirModules(__dirname + '/modules', ['test2'], function (path, name, capName) {\r
+\r
+                target[name] = capName;\r
+            });\r
+\r
+            expect(target.test1).to.equal('Test1');\r
+            expect(target.test2).to.not.exist;\r
+            expect(target.test3).to.equal('Test3');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#rename', function () {\r
+\r
+        it('should rename object key', function (done) {\r
+\r
+            var a = { b: 'c' };\r
+            Hoek.rename(a, 'b', 'x');\r
+            expect(a.b).to.not.exist;\r
+            expect(a.x).to.equal('c');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('Timer', function () {\r
+\r
+        it('should return time elapsed', function (done) {\r
+\r
+            var timer = new Hoek.Timer();\r
+            setTimeout(function () {\r
+\r
+                expect(timer.elapsed()).to.be.above(9);\r
+                done();\r
+            }, 12);\r
+        });\r
+    });\r
+\r
+    describe('#loadPackage', function () {\r
+\r
+        it('should', function (done) {\r
+\r
+            var pack = Hoek.loadPackage();\r
+            expect(pack.name).to.equal('hoek');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#escapeRegex', function () {\r
+\r
+        it('should escape all special regular expression characters', function (done) {\r
+\r
+            var a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\/`"(>)[<]d{}s,');\r
+            expect(a).to.equal('4\\^f\\$s\\.4\\*5\\+\\-_\\?%\\=#\\!\\:@\\|~\\\\\\/`"\\(>\\)\\[<\\]d\\{\\}s\\,');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#toss', function () {\r
+\r
+        it('should call callback with new error', function (done) {\r
+\r
+            var callback = function (err) {\r
+\r
+                expect(err).to.exist;\r
+                expect(err.message).to.equal('bug');\r
+                done();\r
+            };\r
+\r
+            Hoek.toss(true, 'feature', callback);\r
+            Hoek.toss(false, 'bug', callback);\r
+        });\r
+\r
+        it('should call callback with new error and no message', function (done) {\r
+\r
+            Hoek.toss(false, function (err) {\r
+\r
+                expect(err).to.exist;\r
+                expect(err.message).to.equal('');\r
+                done();\r
+            });\r
+        });\r
+\r
+        it('should call callback with error condition', function (done) {\r
+\r
+            Hoek.toss(new Error('boom'), function (err) {\r
+\r
+                expect(err).to.exist;\r
+                expect(err.message).to.equal('boom');\r
+                done();\r
+            });\r
+        });\r
+\r
+        it('should call callback with new error using message with error condition', function (done) {\r
+\r
+            Hoek.toss(new Error('ka'), 'boom', function (err) {\r
+\r
+                expect(err).to.exist;\r
+                expect(err.message).to.equal('boom');\r
+                done();\r
+            });\r
+        });\r
+\r
+        it('should call callback with new error using passed error with error condition', function (done) {\r
+\r
+            Hoek.toss(new Error('ka'), new Error('boom'), function (err) {\r
+\r
+                expect(err).to.exist;\r
+                expect(err.message).to.equal('boom');\r
+                done();\r
+            });\r
+        });\r
+    });\r
+\r
+    describe('Base64Url', function () {\r
+\r
+        var base64str = 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0-P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn-AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq-wsbKztLW2t7i5uru8vb6_wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t_g4eLj5OXm5-jp6uvs7e7v8PHy8_T19vf4-fr7_P3-_w';\r
+        var str = unescape('%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28%29*+%2C-./0123456789%3A%3B%3C%3D%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E%7F%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF');\r
+\r
+        describe('#base64urlEncode', function () {\r
+\r
+            it('should base64 URL-safe a string', function (done) {\r
+\r
+                expect(Hoek.base64urlEncode(str)).to.equal(base64str);\r
+                done();\r
+            });\r
+        });\r
+\r
+        describe('#base64urlDecode', function () {\r
+\r
+            it('should un-base64 URL-safe a string', function (done) {\r
+\r
+                expect(Hoek.base64urlDecode(base64str)).to.equal(str);\r
+                done();\r
+            });\r
+\r
+            it('should return error on undefined input', function (done) {\r
+\r
+                expect(Hoek.base64urlDecode().message).to.exist;\r
+                done();\r
+            });\r
+\r
+            it('should return error on invalid input', function (done) {\r
+\r
+                expect(Hoek.base64urlDecode('*').message).to.exist;\r
+                done();\r
+            });\r
+        });\r
+    });\r
+\r
+    describe('#escapeHeaderAttribute', function () {\r
+\r
+        it('should not alter ascii values', function (done) {\r
+\r
+            var a = Hoek.escapeHeaderAttribute('My Value');\r
+            expect(a).to.equal('My Value');\r
+            done();\r
+        });\r
+\r
+        it('should escape all special HTTP header attribute characters', function (done) {\r
+\r
+            var a = Hoek.escapeHeaderAttribute('I said go!!!#"' + String.fromCharCode(92));\r
+            expect(a).to.equal('I said go!!!#\\"\\\\');\r
+            done();\r
+        });\r
+\r
+        it('should throw on large unicode characters', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.escapeHeaderAttribute('this is a test' + String.fromCharCode(500) + String.fromCharCode(300));\r
+            };\r
+\r
+            expect(fn).to.throw(Error);\r
+            done();\r
+        });\r
+\r
+        it('should throw on CRLF to prevent response splitting', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.escapeHeaderAttribute('this is a test\r\n');\r
+            };\r
+\r
+            expect(fn).to.throw(Error);\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#escapeHtml', function () {\r
+\r
+        it('should escape all special HTML characters', function (done) {\r
+\r
+            var a = Hoek.escapeHtml('&<>"\'`');\r
+            expect(a).to.equal('&amp;&lt;&gt;&quot;&#x27;&#x60;');\r
+            done();\r
+        });\r
+\r
+        it('should return empty string on falsy input', function (done) {\r
+\r
+            var a = Hoek.escapeHtml('');\r
+            expect(a).to.equal('');\r
+            done();\r
+        });\r
+\r
+        it('should return unchanged string on no reserved input', function (done) {\r
+\r
+            var a = Hoek.escapeHtml('abc');\r
+            expect(a).to.equal('abc');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#printEvent', function () {\r
+\r
+        it('outputs event as string', function (done) {\r
+\r
+            var event = {\r
+                timestamp: (new Date(2013, 1, 1, 6, 30, 45, 123)).getTime(),\r
+                tags: ['a', 'b', 'c'],\r
+                data: { some: 'data' }\r
+            };\r
+\r
+            Hoek.consoleFunc = function (string) {\r
+\r
+                Hoek.consoleFunc = console.log;\r
+                expect(string).to.equal('130201/063045.123, a, {"some":"data"}');\r
+                done();\r
+            };\r
+\r
+            Hoek.printEvent(event);\r
+        });\r
+\r
+        it('outputs JSON error', function (done) {\r
+\r
+            var event = {\r
+                timestamp: (new Date(2013, 1, 1, 6, 30, 45, 123)).getTime(),\r
+                tags: ['a', 'b', 'c'],\r
+                data: { some: 'data' }\r
+            };\r
+\r
+            event.data.a = event.data;\r
+\r
+            Hoek.consoleFunc = function (string) {\r
+\r
+                Hoek.consoleFunc = console.log;\r
+                expect(string).to.equal('130201/063045.123, a, JSON Error: Converting circular structure to JSON');\r
+                done();\r
+            };\r
+\r
+            Hoek.printEvent(event);\r
+        });\r
+    });\r
+\r
+    describe('#nextTick', function () {\r
+\r
+        it('calls the provided callback on nextTick', function (done) {\r
+\r
+            var a = 0;\r
+\r
+            var inc = function (step, next) {\r
+\r
+                a += step;\r
+                next();\r
+            };\r
+\r
+            var ticked = Hoek.nextTick(inc);\r
+\r
+            ticked(5, function () {\r
+\r
+                expect(a).to.equal(6);\r
+                done();\r
+            });\r
+\r
+            expect(a).to.equal(0);\r
+            inc(1, function () {\r
+\r
+                expect(a).to.equal(1);\r
+            });\r
+        });\r
+    });\r
+});\r
+\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test1.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test1.js
new file mode 100755 (executable)
index 0000000..3f41e60
--- /dev/null
@@ -0,0 +1 @@
+exports.x = 1;\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test2.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test2.js
new file mode 100755 (executable)
index 0000000..38556b2
--- /dev/null
@@ -0,0 +1 @@
+exports.y = 2;\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test3.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test3.js
new file mode 100755 (executable)
index 0000000..436b860
--- /dev/null
@@ -0,0 +1 @@
+exports.z = 3;\r
index 6b8baa7..d9f9e42 100755 (executable)
@@ -1,7 +1,7 @@
 {
   "name": "boom",
   "description": "HTTP-friendly error objects",
-  "version": "0.4.1",
+  "version": "0.4.2",
   "author": {
     "name": "Eran Hammer",
     "email": "eran@hueniverse.com",
@@ -21,7 +21,7 @@
     "node": ">=0.8.0"
   },
   "dependencies": {
-    "hoek": "0.8.x"
+    "hoek": "0.9.x"
   },
   "devDependencies": {
     "lab": "0.1.x",
@@ -41,6 +41,6 @@
   "bugs": {
     "url": "https://github.com/spumko/boom/issues"
   },
-  "_id": "boom@0.4.1",
+  "_id": "boom@0.4.2",
   "_from": "boom@0.4.x"
 }
index 3572b21..98a6e02 100755 (executable)
@@ -1,68 +1,68 @@
-# sntp\r
-\r
-An SNTP v4 client (RFC4330) for node. Simpy connects to the NTP or SNTP server requested and returns the server time\r
-along with the roundtrip duration and clock offset. To adjust the local time to the NTP time, add the returned `t` offset\r
-to the local time.\r
-\r
-[![Build Status](https://secure.travis-ci.org/hueniverse/sntp.png)](http://travis-ci.org/hueniverse/sntp)\r
-\r
-# Usage\r
-\r
-```javascript\r
-var Sntp = require('sntp');\r
-\r
-// All options are optional\r
-\r
-var options = {\r
-    host: 'nist1-sj.ustiming.org',  // Defaults to pool.ntp.org\r
-    port: 123,                      // Defaults to 123 (NTP)\r
-    resolveReference: true,         // Default to false (not resolving)\r
-    timeout: 1000                   // Defaults to zero (no timeout)\r
-};\r
-\r
-// Request server time\r
-\r
-Sntp.time(options, function (err, time) {\r
-\r
-    if (err) {\r
-        console.log('Failed: ' + err.message);\r
-        process.exit(1);\r
-    }\r
-\r
-    console.log('Local clock is off by: ' + time.t + ' milliseconds');\r
-    process.exit(0);\r
-});\r
-```\r
-\r
-If an application needs to maintain continuous time synchronization, the module provides a stateful method for\r
-querying the current offset only when the last one is too old (defaults to daily).\r
-\r
-```javascript\r
-// Request offset once\r
-\r
-Sntp.offset(function (err, offset) {\r
-\r
-    console.log(offset);                    // New (served fresh)\r
-\r
-    // Request offset again\r
-\r
-    Sntp.offset(function (err, offset) {\r
-\r
-        console.log(offset);                // Identical (served from cache)\r
-    });\r
-});\r
-```\r
-\r
-To set a background offset refresh, start the interval and use the provided now() method. If for any reason the\r
-client fails to obtain an up-to-date offset, the current system clock is used.\r
-\r
-```javascript\r
-var before = Sntp.now();                    // System time without offset\r
-\r
-Sntp.start(function () {\r
-\r
-    var now = Sntp.now();                   // With offset\r
-    Sntp.stop();\r
-});\r
-```\r
-\r
+# sntp
+
+An SNTP v4 client (RFC4330) for node. Simpy connects to the NTP or SNTP server requested and returns the server time
+along with the roundtrip duration and clock offset. To adjust the local time to the NTP time, add the returned `t` offset
+to the local time.
+
+[![Build Status](https://secure.travis-ci.org/hueniverse/sntp.png)](http://travis-ci.org/hueniverse/sntp)
+
+# Usage
+
+```javascript
+var Sntp = require('sntp');
+
+// All options are optional
+
+var options = {
+    host: 'nist1-sj.ustiming.org',  // Defaults to pool.ntp.org
+    port: 123,                      // Defaults to 123 (NTP)
+    resolveReference: true,         // Default to false (not resolving)
+    timeout: 1000                   // Defaults to zero (no timeout)
+};
+
+// Request server time
+
+Sntp.time(options, function (err, time) {
+
+    if (err) {
+        console.log('Failed: ' + err.message);
+        process.exit(1);
+    }
+
+    console.log('Local clock is off by: ' + time.t + ' milliseconds');
+    process.exit(0);
+});
+```
+
+If an application needs to maintain continuous time synchronization, the module provides a stateful method for
+querying the current offset only when the last one is too old (defaults to daily).
+
+```javascript
+// Request offset once
+
+Sntp.offset(function (err, offset) {
+
+    console.log(offset);                    // New (served fresh)
+
+    // Request offset again
+
+    Sntp.offset(function (err, offset) {
+
+        console.log(offset);                // Identical (served from cache)
+    });
+});
+```
+
+To set a background offset refresh, start the interval and use the provided now() method. If for any reason the
+client fails to obtain an up-to-date offset, the current system clock is used.
+
+```javascript
+var before = Sntp.now();                    // System time without offset
+
+Sntp.start(function () {
+
+    var now = Sntp.now();                   // With offset
+    Sntp.stop();
+});
+```
+
index c680e2e..e492cd9 100755 (executable)
-// Load modules\r
-\r
-var Dgram = require('dgram');\r
-var Dns = require('dns');\r
-var Hoek = require('hoek');\r
-\r
-\r
-// Declare internals\r
-\r
-var internals = {};\r
-\r
-\r
-exports.time = function (options, callback) {\r
-\r
-    if (arguments.length !== 2) {\r
-        callback = arguments[0];\r
-        options = {};\r
-    }\r
-\r
-    var settings = Hoek.clone(options);\r
-    settings.host = settings.host || 'pool.ntp.org';\r
-    settings.port = settings.port || 123;\r
-    settings.resolveReference = settings.resolveReference || false;\r
-\r
-    // Declare variables used by callback\r
-\r
-    var timeoutId = 0;\r
-    var sent = 0;\r
-\r
-    // Ensure callback is only called once\r
-\r
-    var isFinished = false;\r
-    var finish = function (err, result) {\r
-\r
-        if (timeoutId) {\r
-            clearTimeout(timeoutId);\r
-            timeoutId = 0;\r
-        }\r
-\r
-        if (!isFinished) {\r
-            isFinished = true;\r
-            socket.close();\r
-            return callback(err, result);\r
-        }\r
-    };\r
-\r
-    // Create UDP socket\r
-\r
-    var socket = Dgram.createSocket('udp4');\r
-\r
-    socket.on('error', function (err) {\r
-\r
-        return finish(err);\r
-    });\r
-\r
-    // Listen to incoming messages\r
-\r
-    socket.on('message', function (buffer, rinfo) {\r
-\r
-        var received = Date.now();\r
-\r
-        var message = new internals.NtpMessage(buffer);\r
-        if (!message.isValid) {\r
-            return finish(new Error('Invalid server response'), message);\r
-        }\r
-\r
-        if (message.originateTimestamp !== sent) {\r
-            return finish(new Error('Wrong originate timestamp'), message);\r
-        }\r
-\r
-        // Timestamp Name          ID   When Generated\r
-        // ------------------------------------------------------------\r
-        // Originate Timestamp     T1   time request sent by client\r
-        // Receive Timestamp       T2   time request received by server\r
-        // Transmit Timestamp      T3   time reply sent by server\r
-        // Destination Timestamp   T4   time reply received by client\r
-        //\r
-        // The roundtrip delay d and system clock offset t are defined as:\r
-        //\r
-        // d = (T4 - T1) - (T3 - T2)     t = ((T2 - T1) + (T3 - T4)) / 2\r
-\r
-        var T1 = message.originateTimestamp;\r
-        var T2 = message.receiveTimestamp;\r
-        var T3 = message.transmitTimestamp;\r
-        var T4 = received;\r
-\r
-        message.d = (T4 - T1) - (T3 - T2);\r
-        message.t = ((T2 - T1) + (T3 - T4)) / 2;\r
-        message.receivedLocally = received;\r
-\r
-        if (!settings.resolveReference ||\r
-            message.stratum !== 'secondary') {\r
-\r
-            return finish(null, message);\r
-        }\r
-\r
-        // Resolve reference IP address\r
-\r
-        Dns.reverse(message.referenceId, function (err, domains) {\r
-\r
-            if (!err) {\r
-                message.referenceHost = domains[0];\r
-            }\r
-\r
-            return finish(null, message);\r
-        });\r
-    });\r
-\r
-    // Set timeout\r
-\r
-    if (settings.timeout) {\r
-        timeoutId = setTimeout(function () {\r
-\r
-            timeoutId = 0;\r
-            return finish(new Error('Timeout'));\r
-        }, settings.timeout);\r
-    }\r
-\r
-    // Construct NTP message\r
-\r
-    var message = new Buffer(48);\r
-    for (var i = 0; i < 48; i++) {                      // Zero message\r
-        message[i] = 0;\r
-    }\r
-\r
-    message[0] = (0 << 6) + (4 << 3) + (3 << 0)         // Set version number to 4 and Mode to 3 (client)\r
-    sent = Date.now();\r
-    internals.fromMsecs(sent, message, 40);               // Set transmit timestamp (returns as originate)\r
-\r
-    // Send NTP request\r
-\r
-    socket.send(message, 0, message.length, settings.port, settings.host, function (err, bytes) {\r
-\r
-        if (err ||\r
-            bytes !== 48) {\r
-\r
-            return finish(err || new Error('Could not send entire message'));\r
-        }\r
-    });\r
-};\r
-\r
-\r
-internals.NtpMessage = function (buffer) {\r
-\r
-    this.isValid = false;\r
-\r
-    // Validate\r
-\r
-    if (buffer.length !== 48) {\r
-        return;\r
-    }\r
-\r
-    // Leap indicator\r
-\r
-    var li = (buffer[0] >> 6);\r
-    switch (li) {\r
-        case 0: this.leapIndicator = 'no-warning'; break;\r
-        case 1: this.leapIndicator = 'last-minute-61'; break;\r
-        case 2: this.leapIndicator = 'last-minute-59'; break;\r
-        case 3: this.leapIndicator = 'alarm'; break;\r
-    }\r
-\r
-    // Version\r
-\r
-    var vn = ((buffer[0] & 0x38) >> 3);\r
-    this.version = vn;\r
-\r
-    // Mode\r
-\r
-    var mode = (buffer[0] & 0x7);\r
-    switch (mode) {\r
-        case 1: this.mode = 'symmetric-active'; break;\r
-        case 2: this.mode = 'symmetric-passive'; break;\r
-        case 3: this.mode = 'client'; break;\r
-        case 4: this.mode = 'server'; break;\r
-        case 5: this.mode = 'broadcast'; break;\r
-        case 0:\r
-        case 6:\r
-        case 7: this.mode = 'reserved'; break;\r
-    }\r
-\r
-    // Stratum\r
-\r
-    var stratum = buffer[1];\r
-    if (stratum === 0) {\r
-        this.stratum = 'death';\r
-    }\r
-    else if (stratum === 1) {\r
-        this.stratum = 'primary';\r
-    }\r
-    else if (stratum <= 15) {\r
-        this.stratum = 'secondary';\r
-    }\r
-    else {\r
-        this.stratum = 'reserved';\r
-    }\r
-\r
-    // Poll interval (msec)\r
-\r
-    this.pollInterval = Math.round(Math.pow(2, buffer[2])) * 1000;\r
-\r
-    // Precision (msecs)\r
-\r
-    this.precision = Math.pow(2, buffer[3]) * 1000;\r
-\r
-    // Root delay (msecs)\r
-\r
-    var rootDelay = 256 * (256 * (256 * buffer[4] + buffer[5]) + buffer[6]) + buffer[7];\r
-    this.rootDelay = 1000 * (rootDelay / 0x10000);\r
-\r
-    // Root dispersion (msecs)\r
-\r
-    this.rootDispersion = ((buffer[8] << 8) + buffer[9] + ((buffer[10] << 8) + buffer[11]) / Math.pow(2, 16)) * 1000;\r
-\r
-    // Reference identifier\r
-\r
-    this.referenceId = '';\r
-    switch (this.stratum) {\r
-        case 'death':\r
-        case 'primary':\r
-            this.referenceId = String.fromCharCode(buffer[12]) + String.fromCharCode(buffer[13]) + String.fromCharCode(buffer[14]) + String.fromCharCode(buffer[15]);\r
-            break;\r
-        case 'secondary':\r
-            this.referenceId = '' + buffer[12] + '.' + buffer[13] + '.' + buffer[14] + '.' + buffer[15];\r
-            break;\r
-    }\r
-\r
-    // Reference timestamp\r
-\r
-    this.referenceTimestamp = internals.toMsecs(buffer, 16);\r
-\r
-    // Originate timestamp\r
-\r
-    this.originateTimestamp = internals.toMsecs(buffer, 24);\r
-\r
-    // Receive timestamp\r
-\r
-    this.receiveTimestamp = internals.toMsecs(buffer, 32);\r
-\r
-    // Transmit timestamp\r
-\r
-    this.transmitTimestamp = internals.toMsecs(buffer, 40);\r
-\r
-    // Validate\r
-\r
-    if (this.version === 4 &&\r
-        this.stratum !== 'reserved' &&\r
-        this.mode === 'server' &&\r
-        this.originateTimestamp &&\r
-        this.receiveTimestamp &&\r
-        this.transmitTimestamp) {\r
-\r
-        this.isValid = true;\r
-    }\r
-\r
-    return this;\r
-};\r
-\r
-\r
-internals.toMsecs = function (buffer, offset) {\r
-\r
-    var seconds = 0;\r
-    var fraction = 0;\r
-\r
-    for (var i = 0; i < 4; ++i) {\r
-        seconds = (seconds * 256) + buffer[offset + i];\r
-    }\r
-\r
-    for (i = 4; i < 8; ++i) {\r
-        fraction = (fraction * 256) + buffer[offset + i];\r
-    }\r
-\r
-    return ((seconds - 2208988800 + (fraction / Math.pow(2, 32))) * 1000);\r
-};\r
-\r
-\r
-internals.fromMsecs = function (ts, buffer, offset) {\r
-\r
-    var seconds = Math.floor(ts / 1000) + 2208988800;\r
-    var fraction = Math.round((ts % 1000) / 1000 * Math.pow(2, 32));\r
-\r
-    buffer[offset + 0] = (seconds & 0xFF000000) >> 24;\r
-    buffer[offset + 1] = (seconds & 0x00FF0000) >> 16;\r
-    buffer[offset + 2] = (seconds & 0x0000FF00) >> 8;\r
-    buffer[offset + 3] = (seconds & 0x000000FF);\r
-\r
-    buffer[offset + 4] = (fraction & 0xFF000000) >> 24;\r
-    buffer[offset + 5] = (fraction & 0x00FF0000) >> 16;\r
-    buffer[offset + 6] = (fraction & 0x0000FF00) >> 8;\r
-    buffer[offset + 7] = (fraction & 0x000000FF);\r
-};\r
-\r
-\r
-// Offset singleton\r
-\r
-internals.last = {\r
-    offset: 0,\r
-    expires: 0,\r
-    host: '',\r
-    port: 0\r
-};\r
-\r
-\r
-exports.offset = function (options, callback) {\r
-\r
-    if (arguments.length !== 2) {\r
-        callback = arguments[0];\r
-        options = {};\r
-    }\r
-\r
-    var now = Date.now();\r
-    var clockSyncRefresh = options.clockSyncRefresh || 24 * 60 * 60 * 1000;                    // Daily\r
-\r
-    if (internals.last.offset &&\r
-        internals.last.host === options.host &&\r
-        internals.last.port === options.port &&\r
-        now < internals.last.expires) {\r
-\r
-        process.nextTick(function () {\r
-                \r
-            callback(null, internals.last.offset);\r
-        });\r
-\r
-        return;\r
-    }\r
-\r
-    exports.time(options, function (err, time) {\r
-\r
-        if (err) {\r
-            return callback(err, 0);\r
-        }\r
-\r
-        internals.last = {\r
-            offset: Math.round(time.t),\r
-            expires: now + clockSyncRefresh,\r
-            host: options.host,\r
-            port: options.port\r
-        };\r
-\r
-        return callback(null, internals.last.offset);\r
-    });\r
-};\r
-\r
-\r
-// Now singleton\r
-\r
-internals.now = {\r
-    intervalId: 0\r
-};\r
-\r
-\r
-exports.start = function (options, callback) {\r
-\r
-    if (arguments.length !== 2) {\r
-        callback = arguments[0];\r
-        options = {};\r
-    }\r
-\r
-    if (internals.now.intervalId) {\r
-        process.nextTick(function () {\r
-            \r
-            callback();\r
-        });\r
-        \r
-        return;\r
-    }\r
-\r
-    exports.offset(options, function (err, offset) {\r
-\r
-        internals.now.intervalId = setInterval(function () {\r
-\r
-            exports.offset(options, function () { });\r
-        }, options.clockSyncRefresh || 24 * 60 * 60 * 1000);                                // Daily\r
-\r
-        return callback();\r
-    });\r
-};\r
-\r
-\r
-exports.stop = function () {\r
-\r
-    if (!internals.now.intervalId) {\r
-        return;\r
-    }\r
-\r
-    clearInterval(internals.now.intervalId);\r
-    internals.now.intervalId = 0;\r
-};\r
-\r
-\r
-exports.isLive = function () {\r
-\r
-    return !!internals.now.intervalId;\r
-};\r
-\r
-\r
-exports.now = function () {\r
-\r
-    var now = Date.now();\r
-    if (!exports.isLive() ||\r
-        now >= internals.last.expires) {\r
-\r
-        return now;\r
-    }\r
-\r
-    return now + internals.last.offset;\r
-};\r
-\r
+// Load modules
+
+var Dgram = require('dgram');
+var Dns = require('dns');
+var Hoek = require('hoek');
+
+
+// Declare internals
+
+var internals = {};
+
+
+exports.time = function (options, callback) {
+
+    if (arguments.length !== 2) {
+        callback = arguments[0];
+        options = {};
+    }
+
+    var settings = Hoek.clone(options);
+    settings.host = settings.host || 'pool.ntp.org';
+    settings.port = settings.port || 123;
+    settings.resolveReference = settings.resolveReference || false;
+
+    // Declare variables used by callback
+
+    var timeoutId = 0;
+    var sent = 0;
+
+    // Ensure callback is only called once
+
+    var isFinished = false;
+    var finish = function (err, result) {
+
+        if (timeoutId) {
+            clearTimeout(timeoutId);
+            timeoutId = 0;
+        }
+
+        if (!isFinished) {
+            isFinished = true;
+            socket.removeAllListeners();
+            socket.close();
+            return callback(err, result);
+        }
+    };
+
+    // Create UDP socket
+
+    var socket = Dgram.createSocket('udp4');
+
+    socket.once('error', function (err) {
+
+        return finish(err);
+    });
+
+    // Listen to incoming messages
+
+    socket.on('message', function (buffer, rinfo) {
+
+        var received = Date.now();
+
+        var message = new internals.NtpMessage(buffer);
+        if (!message.isValid) {
+            return finish(new Error('Invalid server response'), message);
+        }
+
+        if (message.originateTimestamp !== sent) {
+            return finish(new Error('Wrong originate timestamp'), message);
+        }
+
+        // Timestamp Name          ID   When Generated
+        // ------------------------------------------------------------
+        // Originate Timestamp     T1   time request sent by client
+        // Receive Timestamp       T2   time request received by server
+        // Transmit Timestamp      T3   time reply sent by server
+        // Destination Timestamp   T4   time reply received by client
+        //
+        // The roundtrip delay d and system clock offset t are defined as:
+        //
+        // d = (T4 - T1) - (T3 - T2)     t = ((T2 - T1) + (T3 - T4)) / 2
+
+        var T1 = message.originateTimestamp;
+        var T2 = message.receiveTimestamp;
+        var T3 = message.transmitTimestamp;
+        var T4 = received;
+
+        message.d = (T4 - T1) - (T3 - T2);
+        message.t = ((T2 - T1) + (T3 - T4)) / 2;
+        message.receivedLocally = received;
+
+        if (!settings.resolveReference ||
+            message.stratum !== 'secondary') {
+
+            return finish(null, message);
+        }
+
+        // Resolve reference IP address
+
+        Dns.reverse(message.referenceId, function (err, domains) {
+
+            if (!err) {
+                message.referenceHost = domains[0];
+            }
+
+            return finish(null, message);
+        });
+    });
+
+    // Set timeout
+
+    if (settings.timeout) {
+        timeoutId = setTimeout(function () {
+
+            timeoutId = 0;
+            return finish(new Error('Timeout'));
+        }, settings.timeout);
+    }
+
+    // Construct NTP message
+
+    var message = new Buffer(48);
+    for (var i = 0; i < 48; i++) {                      // Zero message
+        message[i] = 0;
+    }
+
+    message[0] = (0 << 6) + (4 << 3) + (3 << 0)         // Set version number to 4 and Mode to 3 (client)
+    sent = Date.now();
+    internals.fromMsecs(sent, message, 40);               // Set transmit timestamp (returns as originate)
+
+    // Send NTP request
+
+    socket.send(message, 0, message.length, settings.port, settings.host, function (err, bytes) {
+
+        if (err ||
+            bytes !== 48) {
+
+            return finish(err || new Error('Could not send entire message'));
+        }
+    });
+};
+
+
+internals.NtpMessage = function (buffer) {
+
+    this.isValid = false;
+
+    // Validate
+
+    if (buffer.length !== 48) {
+        return;
+    }
+
+    // Leap indicator
+
+    var li = (buffer[0] >> 6);
+    switch (li) {
+        case 0: this.leapIndicator = 'no-warning'; break;
+        case 1: this.leapIndicator = 'last-minute-61'; break;
+        case 2: this.leapIndicator = 'last-minute-59'; break;
+        case 3: this.leapIndicator = 'alarm'; break;
+    }
+
+    // Version
+
+    var vn = ((buffer[0] & 0x38) >> 3);
+    this.version = vn;
+
+    // Mode
+
+    var mode = (buffer[0] & 0x7);
+    switch (mode) {
+        case 1: this.mode = 'symmetric-active'; break;
+        case 2: this.mode = 'symmetric-passive'; break;
+        case 3: this.mode = 'client'; break;
+        case 4: this.mode = 'server'; break;
+        case 5: this.mode = 'broadcast'; break;
+        case 0:
+        case 6:
+        case 7: this.mode = 'reserved'; break;
+    }
+
+    // Stratum
+
+    var stratum = buffer[1];
+    if (stratum === 0) {
+        this.stratum = 'death';
+    }
+    else if (stratum === 1) {
+        this.stratum = 'primary';
+    }
+    else if (stratum <= 15) {
+        this.stratum = 'secondary';
+    }
+    else {
+        this.stratum = 'reserved';
+    }
+
+    // Poll interval (msec)
+
+    this.pollInterval = Math.round(Math.pow(2, buffer[2])) * 1000;
+
+    // Precision (msecs)
+
+    this.precision = Math.pow(2, buffer[3]) * 1000;
+
+    // Root delay (msecs)
+
+    var rootDelay = 256 * (256 * (256 * buffer[4] + buffer[5]) + buffer[6]) + buffer[7];
+    this.rootDelay = 1000 * (rootDelay / 0x10000);
+
+    // Root dispersion (msecs)
+
+    this.rootDispersion = ((buffer[8] << 8) + buffer[9] + ((buffer[10] << 8) + buffer[11]) / Math.pow(2, 16)) * 1000;
+
+    // Reference identifier
+
+    this.referenceId = '';
+    switch (this.stratum) {
+        case 'death':
+        case 'primary':
+            this.referenceId = String.fromCharCode(buffer[12]) + String.fromCharCode(buffer[13]) + String.fromCharCode(buffer[14]) + String.fromCharCode(buffer[15]);
+            break;
+        case 'secondary':
+            this.referenceId = '' + buffer[12] + '.' + buffer[13] + '.' + buffer[14] + '.' + buffer[15];
+            break;
+    }
+
+    // Reference timestamp
+
+    this.referenceTimestamp = internals.toMsecs(buffer, 16);
+
+    // Originate timestamp
+
+    this.originateTimestamp = internals.toMsecs(buffer, 24);
+
+    // Receive timestamp
+
+    this.receiveTimestamp = internals.toMsecs(buffer, 32);
+
+    // Transmit timestamp
+
+    this.transmitTimestamp = internals.toMsecs(buffer, 40);
+
+    // Validate
+
+    if (this.version === 4 &&
+        this.stratum !== 'reserved' &&
+        this.mode === 'server' &&
+        this.originateTimestamp &&
+        this.receiveTimestamp &&
+        this.transmitTimestamp) {
+
+        this.isValid = true;
+    }
+
+    return this;
+};
+
+
+internals.toMsecs = function (buffer, offset) {
+
+    var seconds = 0;
+    var fraction = 0;
+
+    for (var i = 0; i < 4; ++i) {
+        seconds = (seconds * 256) + buffer[offset + i];
+    }
+
+    for (i = 4; i < 8; ++i) {
+        fraction = (fraction * 256) + buffer[offset + i];
+    }
+
+    return ((seconds - 2208988800 + (fraction / Math.pow(2, 32))) * 1000);
+};
+
+
+internals.fromMsecs = function (ts, buffer, offset) {
+
+    var seconds = Math.floor(ts / 1000) + 2208988800;
+    var fraction = Math.round((ts % 1000) / 1000 * Math.pow(2, 32));
+
+    buffer[offset + 0] = (seconds & 0xFF000000) >> 24;
+    buffer[offset + 1] = (seconds & 0x00FF0000) >> 16;
+    buffer[offset + 2] = (seconds & 0x0000FF00) >> 8;
+    buffer[offset + 3] = (seconds & 0x000000FF);
+
+    buffer[offset + 4] = (fraction & 0xFF000000) >> 24;
+    buffer[offset + 5] = (fraction & 0x00FF0000) >> 16;
+    buffer[offset + 6] = (fraction & 0x0000FF00) >> 8;
+    buffer[offset + 7] = (fraction & 0x000000FF);
+};
+
+
+// Offset singleton
+
+internals.last = {
+    offset: 0,
+    expires: 0,
+    host: '',
+    port: 0
+};
+
+
+exports.offset = function (options, callback) {
+
+    if (arguments.length !== 2) {
+        callback = arguments[0];
+        options = {};
+    }
+
+    var now = Date.now();
+    var clockSyncRefresh = options.clockSyncRefresh || 24 * 60 * 60 * 1000;                    // Daily
+
+    if (internals.last.offset &&
+        internals.last.host === options.host &&
+        internals.last.port === options.port &&
+        now < internals.last.expires) {
+
+        process.nextTick(function () {
+                
+            callback(null, internals.last.offset);
+        });
+
+        return;
+    }
+
+    exports.time(options, function (err, time) {
+
+        if (err) {
+            return callback(err, 0);
+        }
+
+        internals.last = {
+            offset: Math.round(time.t),
+            expires: now + clockSyncRefresh,
+            host: options.host,
+            port: options.port
+        };
+
+        return callback(null, internals.last.offset);
+    });
+};
+
+
+// Now singleton
+
+internals.now = {
+    intervalId: 0
+};
+
+
+exports.start = function (options, callback) {
+
+    if (arguments.length !== 2) {
+        callback = arguments[0];
+        options = {};
+    }
+
+    if (internals.now.intervalId) {
+        process.nextTick(function () {
+            
+            callback();
+        });
+        
+        return;
+    }
+
+    exports.offset(options, function (err, offset) {
+
+        internals.now.intervalId = setInterval(function () {
+
+            exports.offset(options, function () { });
+        }, options.clockSyncRefresh || 24 * 60 * 60 * 1000);                                // Daily
+
+        return callback();
+    });
+};
+
+
+exports.stop = function () {
+
+    if (!internals.now.intervalId) {
+        return;
+    }
+
+    clearInterval(internals.now.intervalId);
+    internals.now.intervalId = 0;
+};
+
+
+exports.isLive = function () {
+
+    return !!internals.now.intervalId;
+};
+
+
+exports.now = function () {
+
+    var now = Date.now();
+    if (!exports.isLive() ||
+        now >= internals.last.expires) {
+
+        return now;
+    }
+
+    return now + internals.last.offset;
+};
+
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/.npmignore b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/.npmignore
new file mode 100644 (file)
index 0000000..9966e5e
--- /dev/null
@@ -0,0 +1,18 @@
+.idea\r
+*.iml\r
+npm-debug.log\r
+dump.rdb\r
+node_modules\r
+results.tap\r
+results.xml\r
+npm-shrinkwrap.json\r
+config.json\r
+.DS_Store\r
+*/.DS_Store\r
+*/*/.DS_Store\r
+._*\r
+*/._*\r
+*/*/._*\r
+coverage.*\r
+lib-cov\r
+complexity.md\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/.travis.yml b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/.travis.yml
new file mode 100755 (executable)
index 0000000..40ca59e
--- /dev/null
@@ -0,0 +1,5 @@
+language: node_js\r
+\r
+node_js:\r
+  - 0.10\r
+\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/LICENSE b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/LICENSE
new file mode 100755 (executable)
index 0000000..394adcf
--- /dev/null
@@ -0,0 +1,33 @@
+Copyright (c) 2011-2013, Walmart.\r
+All rights reserved.\r
+\r
+Redistribution and use in source and binary forms, with or without\r
+modification, are permitted provided that the following conditions are met:\r
+    * Redistributions of source code must retain the above copyright\r
+      notice, this list of conditions and the following disclaimer.\r
+    * Redistributions in binary form must reproduce the above copyright\r
+      notice, this list of conditions and the following disclaimer in the\r
+      documentation and/or other materials provided with the distribution.\r
+    * Neither the name of Walmart nor the\r
+      names of its contributors may be used to endorse or promote products\r
+      derived from this software without specific prior written permission.\r
+\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+DISCLAIMED. IN NO EVENT SHALL WALMART BE LIABLE FOR ANY\r
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+\r
+                                  *   *   *\r
+\r
+\r
+Portions of this project were initially based on Postmile, Copyright (c) 2011, Yahoo Inc.\r
+Postmile is published at https://github.com/yahoo/postmile and its licensing terms are\r
+published at https://github.com/yahoo/postmile/blob/master/LICENSE.\r
+\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/Makefile b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/Makefile
new file mode 100755 (executable)
index 0000000..e605d6c
--- /dev/null
@@ -0,0 +1,10 @@
+test:\r
+       @node node_modules/lab/bin/lab\r
+test-cov: \r
+       @node node_modules/lab/bin/lab -r threshold -t 100\r
+test-cov-html:\r
+       @node node_modules/lab/bin/lab -r html -o coverage.html\r
+complexity:\r
+       @node node_modules/complexity-report/src/cli.js -o complexity.md -f markdown lib\r
+\r
+.PHONY: test test-cov test-cov-html complexity\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/README.md b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/README.md
new file mode 100755 (executable)
index 0000000..ac64e2f
--- /dev/null
@@ -0,0 +1,436 @@
+<a href="https://github.com/spumko"><img src="https://raw.github.com/spumko/spumko/master/images/from.png" align="right" /></a>\r
+![hoek Logo](https://raw.github.com/spumko/hoek/master/images/hoek.png)\r
+\r
+General purpose node utilities\r
+\r
+[![Build Status](https://secure.travis-ci.org/spumko/hoek.png)](http://travis-ci.org/spumko/hoek)\r
+\r
+# Table of Contents\r
+\r
+* [Introduction](#introduction "Introduction")\r
+* [Object](#object "Object")\r
+  * [clone](#cloneobj "clone")\r
+  * [merge](#mergetarget-source-isnulloverride-ismergearrays "merge")\r
+  * [applyToDefaults](#applytodefaultsdefaults-options "applyToDefaults")\r
+  * [unique](#uniquearray-key "unique")\r
+  * [mapToObject](#maptoobjectarray-key "mapToObject")\r
+  * [intersect](#intersectarray1-array2 "intersect")\r
+  * [matchKeys](#matchkeysobj-keys "matchKeys")\r
+  * [flatten](#flattenarray-target "flatten")\r
+  * [removeKeys](#removekeysobject-keys "removeKeys")\r
+  * [reach](#reachobj-chain "reach")\r
+  * [inheritAsync](#inheritasyncself-obj-keys "inheritAsync")\r
+  * [rename](#renameobj-from-to "rename")\r
+* [Timer](#timer "Timer")\r
+* [Binary Encoding/Decoding](#binary "Binary Encoding/Decoding")\r
+  * [base64urlEncode](#binary64urlEncodevalue "binary64urlEncode")\r
+  * [base64urlDecode](#binary64urlDecodevalue "binary64urlDecode")\r
+* [Escaping Characters](#escaped "Escaping Characters")\r
+  * [escapeHtml](#escapeHtmlstring "escapeHtml")\r
+  * [escapeHeaderAttribute](#escapeHeaderAttributeattribute "escapeHeaderAttribute")\r
+  * [escapeRegex](#escapeRegexstring "escapeRegex")\r
+* [Errors](#errors "Errors")\r
+  * [assert](#assertmessage "assert")\r
+  * [abort](#abortmessage "abort")\r
+  * [displayStack](#displayStackslice "displayStack")\r
+  * [callStack](#callStackslice "callStack")\r
+  * [toss](#tosscondition "toss")\r
+* [Load files](#load-files "Load Files")\r
+  * [loadPackage](#loadPackagedir "loadpackage")\r
+  * [loadDirModules](#loadDirModulespath-excludefiles-target "loaddirmodules")\r
+\r
+\r
+\r
+# Introduction\r
+\r
+The *Hoek* general purpose node utilities library is used to aid in a variety of manners. It comes with useful methods for Arrays (clone, merge, applyToDefaults), Objects (removeKeys, copy), Asserting and more. \r
+\r
+For example, to use Hoek to set configuration with default options:\r
+```javascript\r
+var Hoek = require('hoek');\r
+\r
+var default = {url : "www.github.com", port : "8000", debug : true}\r
+\r
+var config = Hoek.applyToDefaults(default, {port : "3000", admin : true});\r
+\r
+// In this case, config would be { url: 'www.github.com', port: '3000', debug: true, admin: true }\r
+```\r
+\r
+Under each of the sections (such as Array), there are subsections which correspond to Hoek methods. Each subsection will explain how to use the corresponding method. In each js excerpt below, the var Hoek = require('hoek') is omitted for brevity.\r
+\r
+## Object\r
+\r
+Hoek provides several helpful methods for objects and arrays.\r
+\r
+### clone(obj)\r
+\r
+This method is used to clone an object or an array. A *deep copy* is made (duplicates everything, including values that are objects). \r
+\r
+```javascript\r
+\r
+var nestedObj = {\r
+        w: /^something$/ig,\r
+        x: {\r
+            a: [1, 2, 3],\r
+            b: 123456,\r
+            c: new Date()\r
+        },\r
+        y: 'y',\r
+        z: new Date()\r
+    };\r
+\r
+var copy = Hoek.clone(nestedObj);\r
+\r
+copy.x.b = 100;\r
+\r
+console.log(copy.y)        // results in 'y'\r
+console.log(nestedObj.x.b) // results in 123456\r
+console.log(copy.x.b)      // results in 100\r
+```\r
+\r
+### merge(target, source, isNullOverride, isMergeArrays)\r
+isNullOverride, isMergeArrays default to true\r
+\r
+Merge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied\r
+\r
+\r
+```javascript\r
+\r
+var target = {a: 1, b : 2}\r
+var source = {a: 0, c: 5}\r
+var source2 = {a: null, c: 5}\r
+\r
+var targetArray = [1, 2, 3];\r
+var sourceArray = [4, 5];\r
+\r
+var newTarget = Hoek.merge(target, source);     // results in {a: 0, b: 2, c: 5}\r
+newTarget = Hoek.merge(target, source2);        // results in {a: null, b: 2, c: 5}\r
+newTarget = Hoek.merge(target, source2, false); // results in {a: 1, b: 2, c: 5}\r
+\r
+newTarget = Hoek.merge(targetArray, sourceArray)              // results in [1, 2, 3, 4, 5]\r
+newTarget = Hoek.merge(targetArray, sourceArray, true, false) // results in [4, 5]\r
+\r
+\r
+\r
+\r
+```\r
+\r
+### applyToDefaults(defaults, options)\r
+\r
+Apply options to a copy of the defaults\r
+\r
+```javascript\r
+\r
+var defaults = {host: "localhost", port: 8000};\r
+var options = {port: 8080};\r
+\r
+var config = Hoek.applyToDefaults(defaults, options); // results in {host: "localhost", port: 8080};\r
+\r
+\r
+```\r
+\r
+### unique(array, key)\r
+\r
+Remove duplicate items from Array\r
+\r
+```javascript\r
+\r
+var array = [1, 2, 2, 3, 3, 4, 5, 6];\r
+\r
+var newArray = Hoek.unique(array); // results in [1,2,3,4,5,6];\r
+\r
+array = [{id: 1}, {id: 1}, {id: 2}];\r
+\r
+newArray = Hoek.unique(array, "id") // results in [{id: 1}, {id: 2}]\r
+\r
+```\r
+\r
+### mapToObject(array, key)\r
+\r
+Convert an Array into an Object\r
+\r
+```javascript\r
+\r
+var array = [1,2,3];\r
+var newObject = Hoek.mapToObject(array); // results in [{"1": true}, {"2": true}, {"3": true}]\r
+\r
+array = [{id: 1}, {id: 2}];\r
+newObject = Hoek.mapToObject(array, "id") // results in [{"id": 1}, {"id": 2}]\r
+\r
+```\r
+### intersect(array1, array2)\r
+\r
+Find the common unique items in two arrays\r
+\r
+```javascript\r
+\r
+var array1 = [1, 2, 3];\r
+var array2 = [1, 4, 5];\r
+\r
+var newArray = Hoek.intersect(array1, array2) // results in [1]\r
+\r
+```\r
+\r
+### matchKeys(obj, keys) \r
+\r
+Find which keys are present\r
+\r
+```javascript\r
+\r
+var obj = {a: 1, b: 2, c: 3};\r
+var keys = ["a", "e"];\r
+\r
+Hoek.matchKeys(obj, keys) // returns ["a"]\r
+\r
+```\r
+\r
+### flatten(array, target)\r
+\r
+Flatten an array\r
+\r
+```javascript\r
+\r
+var array = [1, 2, 3];\r
+var target = [4, 5]; \r
+\r
+var flattenedArray = Hoek.flatten(array, target) // results in [4, 5, 1, 2, 3];\r
+\r
+```\r
+\r
+### removeKeys(object, keys)\r
+\r
+Remove keys\r
+\r
+```javascript\r
+\r
+var object = {a: 1, b: 2, c: 3, d: 4};\r
+\r
+var keys = ["a", "b"];\r
+\r
+Hoek.removeKeys(object, keys) // object is now {c: 3, d: 4}\r
+\r
+```\r
+\r
+### reach(obj, chain)\r
+\r
+Converts an object key chain string to reference\r
+\r
+```javascript\r
+\r
+var chain = 'a.b.c';\r
+var obj = {a : {b : { c : 1}}};\r
+\r
+Hoek.reach(obj, chain) // returns 1\r
+\r
+```\r
+\r
+### inheritAsync(self, obj, keys) \r
+\r
+Inherits a selected set of methods from an object, wrapping functions in asynchronous syntax and catching errors\r
+\r
+```javascript\r
+\r
+var targetFunc = function () { };\r
+\r
+var proto = {\r
+                a: function () {\r
+                    return 'a!';\r
+                },\r
+                b: function () {\r
+                    return 'b!';\r
+                },\r
+                c: function () {\r
+                    throw new Error('c!');\r
+                }\r
+            };\r
+\r
+var keys = ['a', 'c'];\r
+\r
+Hoek.inheritAsync(targetFunc, proto, ['a', 'c']);\r
+\r
+var target = new targetFunc();\r
+\r
+target.a(function(err, result){console.log(result)}         // returns 'a!'       \r
+\r
+target.c(function(err, result){console.log(result)}         // returns undefined\r
+\r
+target.b(function(err, result){console.log(result)}         // gives error: Object [object Object] has no method 'b'\r
+\r
+```\r
+\r
+### rename(obj, from, to)\r
+\r
+Rename a key of an object\r
+\r
+```javascript\r
+\r
+var obj = {a : 1, b : 2};\r
+\r
+Hoek.rename(obj, "a", "c");     // obj is now {c : 1, b : 2}\r
+\r
+```\r
+\r
+\r
+# Timer\r
+\r
+A Timer object. Initializing a new timer object sets the ts to the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.\r
+\r
+```javascript\r
+\r
+\r
+example : \r
+\r
+\r
+var timerObj = new Hoek.Timer();\r
+console.log("Time is now: " + timerObj.ts)\r
+console.log("Elapsed time from initialization: " + timerObj.elapsed() + 'milliseconds')\r
+\r
+```\r
+\r
+# Binary Encoding/Decoding\r
+\r
+### base64urlEncode(value)\r
+\r
+Encodes value in Base64 or URL encoding\r
+\r
+### base64urlDecode(value)\r
+\r
+Decodes data in Base64 or URL encoding.\r
+# Escaping Characters\r
+\r
+Hoek provides convenient methods for escaping html characters. The escaped characters are as followed:\r
+\r
+```javascript\r
+\r
+internals.htmlEscaped = {\r
+    '&': '&amp;',\r
+    '<': '&lt;',\r
+    '>': '&gt;',\r
+    '"': '&quot;',\r
+    "'": '&#x27;',\r
+    '`': '&#x60;'\r
+};\r
+\r
+```\r
+\r
+### escapeHtml(string)\r
+\r
+```javascript\r
+\r
+var string = '<html> hey </html>';\r
+var escapedString = Hoek.escapeHtml(string); // returns &lt;html&gt; hey &lt;/html&gt;\r
+\r
+```\r
+\r
+### escapeHeaderAttribute(attribute)\r
+\r
+Escape attribute value for use in HTTP header\r
+\r
+```javascript\r
+\r
+var a = Hoek.escapeHeaderAttribute('I said "go w\\o me"');  //returns I said \"go w\\o me\"\r
+\r
+\r
+```\r
+\r
+\r
+### escapeRegex(string)\r
+\r
+Escape string for Regex construction\r
+\r
+```javascript\r
+\r
+var a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\/`"(>)[<]d{}s,');  // returns 4\^f\$s\.4\*5\+\-_\?%\=#\!\:@\|~\\\/`"\(>\)\[<\]d\{\}s\,\r
+\r
+\r
+\r
+```\r
+\r
+# Errors\r
+\r
+### assert(message)\r
+\r
+```javascript\r
+\r
+var a = 1, b =2;\r
+\r
+Hoek.assert(a === b, 'a should equal b');  // ABORT: a should equal b\r
+\r
+```\r
+\r
+### abort(message)\r
+\r
+First checks if process.env.NODE_ENV === 'test', and if so, throws error message. Otherwise,\r
+displays most recent stack and then exits process.\r
+\r
+\r
+\r
+### displayStack(slice)\r
+\r
+Displays the trace stack\r
+\r
+```javascript\r
+\r
+var stack = Hoek.displayStack();\r
+console.log(stack) // returns something like:\r
+\r
+[ 'null (/Users/user/Desktop/hoek/test.js:4:18)',\r
+  'Module._compile (module.js:449:26)',\r
+  'Module._extensions..js (module.js:467:10)',\r
+  'Module.load (module.js:356:32)',\r
+  'Module._load (module.js:312:12)',\r
+  'Module.runMain (module.js:492:10)',\r
+  'startup.processNextTick.process._tickCallback (node.js:244:9)' ]\r
+\r
+```\r
+\r
+### callStack(slice)\r
+\r
+Returns a trace stack array.\r
+\r
+```javascript\r
+\r
+var stack = Hoek.callStack();\r
+console.log(stack)  // returns something like:\r
+\r
+[ [ '/Users/user/Desktop/hoek/test.js', 4, 18, null, false ],\r
+  [ 'module.js', 449, 26, 'Module._compile', false ],\r
+  [ 'module.js', 467, 10, 'Module._extensions..js', false ],\r
+  [ 'module.js', 356, 32, 'Module.load', false ],\r
+  [ 'module.js', 312, 12, 'Module._load', false ],\r
+  [ 'module.js', 492, 10, 'Module.runMain', false ],\r
+  [ 'node.js',\r
+    244,\r
+    9,\r
+    'startup.processNextTick.process._tickCallback',\r
+    false ] ]\r
+\r
+\r
+```\r
+\r
+### toss(condition)\r
+\r
+toss(condition /*, [message], callback */)\r
+\r
+Return an error as first argument of a callback\r
+\r
+\r
+# Load Files\r
+\r
+### loadPackage(dir)\r
+\r
+Load and parse package.json process root or given directory\r
+\r
+```javascript\r
+\r
+var pack = Hoek.loadPackage();  // pack.name === 'hoek'\r
+\r
+```\r
+\r
+### loadDirModules(path, excludeFiles, target) \r
+\r
+Loads modules from a given path; option to exclude files (array).\r
+\r
+\r
+\r
+\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/images/hoek.png b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/images/hoek.png
new file mode 100755 (executable)
index 0000000..6ccfcb1
Binary files /dev/null and b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/images/hoek.png differ
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/index.js
new file mode 100755 (executable)
index 0000000..4cc88b3
--- /dev/null
@@ -0,0 +1 @@
+module.exports = require('./lib');
\ No newline at end of file
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/lib/escape.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/lib/escape.js
new file mode 100755 (executable)
index 0000000..666b3dc
--- /dev/null
@@ -0,0 +1,132 @@
+// Declare internals\r
+\r
+var internals = {};\r
+\r
+\r
+exports.escapeJavaScript = function (input) {\r
+\r
+    if (!input) {\r
+        return '';\r
+    }\r
+\r
+    var escaped = '';\r
+\r
+    for (var i = 0, il = input.length; i < il; ++i) {\r
+\r
+        var charCode = input.charCodeAt(i);\r
+\r
+        if (internals.isSafe(charCode)) {\r
+            escaped += input[i];\r
+        }\r
+        else {\r
+            escaped += internals.escapeJavaScriptChar(charCode);\r
+        }\r
+    }\r
+\r
+    return escaped;\r
+};\r
+\r
+\r
+exports.escapeHtml = function (input) {\r
+\r
+    if (!input) {\r
+        return '';\r
+    }\r
+\r
+    var escaped = '';\r
+\r
+    for (var i = 0, il = input.length; i < il; ++i) {\r
+\r
+        var charCode = input.charCodeAt(i);\r
+\r
+        if (internals.isSafe(charCode)) {\r
+            escaped += input[i];\r
+        }\r
+        else {\r
+            escaped += internals.escapeHtmlChar(charCode);\r
+        }\r
+    }\r
+\r
+    return escaped;\r
+};\r
+\r
+\r
+internals.escapeJavaScriptChar = function (charCode) {\r
+\r
+    if (charCode >= 256) {\r
+        return '\\u' + internals.padLeft('' + charCode, 4);\r
+    }\r
+\r
+    var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex');\r
+    return '\\x' + internals.padLeft(hexValue, 2);\r
+};\r
+\r
+\r
+internals.escapeHtmlChar = function (charCode) {\r
+\r
+    var namedEscape = internals.namedHtml[charCode];\r
+    if (typeof namedEscape !== 'undefined') {\r
+        return namedEscape;\r
+    }\r
+\r
+    if (charCode >= 256) {\r
+        return '&#' + charCode + ';';\r
+    }\r
+\r
+    var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex');\r
+    return '&#x' + internals.padLeft(hexValue, 2) + ';';\r
+};\r
+\r
+\r
+internals.padLeft = function (str, len) {\r
+\r
+    while (str.length < len) {\r
+        str = '0' + str;\r
+    }\r
+\r
+    return str;\r
+};\r
+\r
+\r
+internals.isSafe = function (charCode) {\r
+\r
+    return (typeof internals.safeCharCodes[charCode] !== 'undefined');\r
+};\r
+\r
+\r
+internals.namedHtml = {\r
+    '38': '&amp;',\r
+    '60': '&lt;',\r
+    '62': '&gt;',\r
+    '34': '&quot;',\r
+    '160': '&nbsp;',\r
+    '162': '&cent;',\r
+    '163': '&pound;',\r
+    '164': '&curren;',\r
+    '169': '&copy;',\r
+    '174': '&reg;'\r
+};\r
+\r
+\r
+internals.safeCharCodes = (function () {\r
+\r
+    var safe = {};\r
+\r
+    for (var i = 32; i < 123; ++i) {\r
+\r
+        if ((i >= 97 && i <= 122) ||         // a-z\r
+            (i >= 65 && i <= 90) ||          // A-Z\r
+            (i >= 48 && i <= 57) ||          // 0-9\r
+            i === 32 ||                      // space\r
+            i === 46 ||                      // .\r
+            i === 44 ||                      // ,\r
+            i === 45 ||                      // -\r
+            i === 58 ||                      // :\r
+            i === 95) {                      // _\r
+\r
+            safe[i] = null;\r
+        }\r
+    }\r
+\r
+    return safe;\r
+}());
\ No newline at end of file
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/lib/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/lib/index.js
new file mode 100755 (executable)
index 0000000..806260d
--- /dev/null
@@ -0,0 +1,585 @@
+// Load modules\r
+\r
+var Fs = require('fs');\r
+var Escape = require('./escape');\r
+\r
+\r
+// Declare internals\r
+\r
+var internals = {};\r
+\r
+\r
+// Clone object or array\r
+\r
+exports.clone = function (obj, seen) {\r
+\r
+    if (typeof obj !== 'object' ||\r
+        obj === null) {\r
+\r
+        return obj;\r
+    }\r
+\r
+    seen = seen || { orig: [], copy: [] };\r
+\r
+    var lookup = seen.orig.indexOf(obj);\r
+    if (lookup !== -1) {\r
+        return seen.copy[lookup];\r
+    }\r
+\r
+    var newObj = (obj instanceof Array) ? [] : {};\r
+\r
+    seen.orig.push(obj);\r
+    seen.copy.push(newObj);\r
+\r
+    for (var i in obj) {\r
+        if (obj.hasOwnProperty(i)) {\r
+            if (obj[i] instanceof Buffer) {\r
+                newObj[i] = new Buffer(obj[i]);\r
+            }\r
+            else if (obj[i] instanceof Date) {\r
+                newObj[i] = new Date(obj[i].getTime());\r
+            }\r
+            else if (obj[i] instanceof RegExp) {\r
+                var flags = '' + (obj[i].global ? 'g' : '') + (obj[i].ignoreCase ? 'i' : '') + (obj[i].multiline ? 'm' : '');\r
+                newObj[i] = new RegExp(obj[i].source, flags);\r
+            }\r
+            else {\r
+                newObj[i] = exports.clone(obj[i], seen);\r
+            }\r
+        }\r
+    }\r
+\r
+    return newObj;\r
+};\r
+\r
+\r
+// Merge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied\r
+\r
+exports.merge = function (target, source, isNullOverride /* = true */, isMergeArrays /* = true */) {\r
+\r
+    exports.assert(target && typeof target == 'object', 'Invalid target value: must be an object');\r
+    exports.assert(source === null || source === undefined || typeof source === 'object', 'Invalid source value: must be null, undefined, or an object');\r
+\r
+    if (!source) {\r
+        return target;\r
+    }\r
+\r
+    if (source instanceof Array) {\r
+        exports.assert(target instanceof Array, 'Cannot merge array onto an object');\r
+        if (isMergeArrays === false) {                                                  // isMergeArrays defaults to true\r
+            target.length = 0;                                                          // Must not change target assignment\r
+        }\r
+\r
+        for (var i = 0, il = source.length; i < il; ++i) {\r
+            target.push(source[i]);\r
+        }\r
+\r
+        return target;\r
+    }\r
+\r
+    var keys = Object.keys(source);\r
+    for (var k = 0, kl = keys.length; k < kl; ++k) {\r
+        var key = keys[k];\r
+        var value = source[key];\r
+        if (value &&\r
+            typeof value === 'object') {\r
+\r
+            if (!target[key] ||\r
+                typeof target[key] !== 'object') {\r
+\r
+                target[key] = exports.clone(value);\r
+            }\r
+            else {\r
+                exports.merge(target[key], source[key], isNullOverride, isMergeArrays);\r
+            }\r
+        }\r
+        else {\r
+            if (value !== null && value !== undefined) {            // Explicit to preserve empty strings\r
+                target[key] = value;\r
+            }\r
+            else if (isNullOverride !== false) {                    // Defaults to true\r
+                target[key] = value;\r
+            }\r
+        }\r
+    }\r
+\r
+    return target;\r
+};\r
+\r
+\r
+// Apply options to a copy of the defaults\r
+\r
+exports.applyToDefaults = function (defaults, options) {\r
+\r
+    exports.assert(defaults && typeof defaults == 'object', 'Invalid defaults value: must be an object');\r
+    exports.assert(!options || options === true || typeof options === 'object', 'Invalid options value: must be true, falsy or an object');\r
+\r
+    if (!options) {                                                 // If no options, return null\r
+        return null;\r
+    }\r
+\r
+    var copy = exports.clone(defaults);\r
+\r
+    if (options === true) {                                         // If options is set to true, use defaults\r
+        return copy;\r
+    }\r
+\r
+    return exports.merge(copy, options, false, false);\r
+};\r
+\r
+\r
+// Remove duplicate items from array\r
+\r
+exports.unique = function (array, key) {\r
+\r
+    var index = {};\r
+    var result = [];\r
+\r
+    for (var i = 0, il = array.length; i < il; ++i) {\r
+        var id = (key ? array[i][key] : array[i]);\r
+        if (index[id] !== true) {\r
+\r
+            result.push(array[i]);\r
+            index[id] = true;\r
+        }\r
+    }\r
+\r
+    return result;\r
+};\r
+\r
+\r
+// Convert array into object\r
+\r
+exports.mapToObject = function (array, key) {\r
+\r
+    if (!array) {\r
+        return null;\r
+    }\r
+\r
+    var obj = {};\r
+    for (var i = 0, il = array.length; i < il; ++i) {\r
+        if (key) {\r
+            if (array[i][key]) {\r
+                obj[array[i][key]] = true;\r
+            }\r
+        }\r
+        else {\r
+            obj[array[i]] = true;\r
+        }\r
+    }\r
+\r
+    return obj;\r
+};\r
+\r
+\r
+// Find the common unique items in two arrays\r
+\r
+exports.intersect = function (array1, array2, justFirst) {\r
+\r
+    if (!array1 || !array2) {\r
+        return [];\r
+    }\r
+\r
+    var common = [];\r
+    var hash = (array1 instanceof Array ? exports.mapToObject(array1) : array1);\r
+    var found = {};\r
+    for (var i = 0, il = array2.length; i < il; ++i) {\r
+        if (hash[array2[i]] && !found[array2[i]]) {\r
+            if (justFirst) {\r
+                return array2[i];\r
+            }\r
+\r
+            common.push(array2[i]);\r
+            found[array2[i]] = true;\r
+        }\r
+    }\r
+\r
+    return (justFirst ? null : common);\r
+};\r
+\r
+\r
+// Find which keys are present\r
+\r
+exports.matchKeys = function (obj, keys) {\r
+\r
+    var matched = [];\r
+    for (var i = 0, il = keys.length; i < il; ++i) {\r
+        if (obj.hasOwnProperty(keys[i])) {\r
+            matched.push(keys[i]);\r
+        }\r
+    }\r
+    return matched;\r
+};\r
+\r
+\r
+// Flatten array\r
+\r
+exports.flatten = function (array, target) {\r
+\r
+    var result = target || [];\r
+\r
+    for (var i = 0, il = array.length; i < il; ++i) {\r
+        if (Array.isArray(array[i])) {\r
+            exports.flatten(array[i], result);\r
+        }\r
+        else {\r
+            result.push(array[i]);\r
+        }\r
+    }\r
+\r
+    return result;\r
+};\r
+\r
+\r
+// Remove keys\r
+\r
+exports.removeKeys = function (object, keys) {\r
+\r
+    for (var i = 0, il = keys.length; i < il; i++) {\r
+        delete object[keys[i]];\r
+    }\r
+};\r
+\r
+\r
+// Convert an object key chain string ('a.b.c') to reference (object[a][b][c])\r
+\r
+exports.reach = function (obj, chain) {\r
+\r
+    var path = chain.split('.');\r
+    var ref = obj;\r
+    for (var i = 0, il = path.length; i < il; ++i) {\r
+        if (ref) {\r
+            ref = ref[path[i]];\r
+        }\r
+    }\r
+\r
+    return ref;\r
+};\r
+\r
+\r
+// Inherits a selected set of methods from an object, wrapping functions in asynchronous syntax and catching errors\r
+\r
+exports.inheritAsync = function (self, obj, keys) {\r
+\r
+    keys = keys || null;\r
+\r
+    for (var i in obj) {\r
+        if (obj.hasOwnProperty(i)) {\r
+            if (keys instanceof Array &&\r
+                keys.indexOf(i) < 0) {\r
+\r
+                continue;\r
+            }\r
+\r
+            self.prototype[i] = (function (fn) {\r
+\r
+                return function (next) {\r
+\r
+                    var result = null;\r
+                    try {\r
+                        result = fn();\r
+                    }\r
+                    catch (err) {\r
+                        return next(err);\r
+                    }\r
+\r
+                    return next(null, result);\r
+                };\r
+            })(obj[i]);\r
+        }\r
+    }\r
+};\r
+\r
+\r
+exports.formatStack = function (stack) {\r
+\r
+    var trace = [];\r
+    for (var i = 0, il = stack.length; i < il; ++i) {\r
+        var item = stack[i];\r
+        trace.push([item.getFileName(), item.getLineNumber(), item.getColumnNumber(), item.getFunctionName(), item.isConstructor()]);\r
+    }\r
+\r
+    return trace;\r
+};\r
+\r
+\r
+exports.formatTrace = function (trace) {\r
+\r
+    var display = [];\r
+\r
+    for (var i = 0, il = trace.length; i < il; ++i) {\r
+        var row = trace[i];\r
+        display.push((row[4] ? 'new ' : '') + row[3] + ' (' + row[0] + ':' + row[1] + ':' + row[2] + ')');\r
+    }\r
+\r
+    return display;\r
+};\r
+\r
+\r
+exports.callStack = function (slice) {\r
+\r
+    // http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi\r
+\r
+    var v8 = Error.prepareStackTrace;\r
+    Error.prepareStackTrace = function (err, stack) {\r
+\r
+        return stack;\r
+    };\r
+\r
+    var capture = {};\r
+    Error.captureStackTrace(capture, arguments.callee);\r
+    var stack = capture.stack;\r
+\r
+    Error.prepareStackTrace = v8;\r
+\r
+    var trace = exports.formatStack(stack);\r
+\r
+    if (slice) {\r
+        return trace.slice(slice);\r
+    }\r
+\r
+    return trace;\r
+};\r
+\r
+\r
+exports.displayStack = function (slice) {\r
+\r
+    var trace = exports.callStack(slice === undefined ? 1 : slice + 1);\r
+\r
+    return exports.formatTrace(trace);\r
+};\r
+\r
+\r
+exports.abortThrow = false;\r
+\r
+\r
+exports.abort = function (message, hideStack) {\r
+\r
+    if (process.env.NODE_ENV === 'test' || exports.abortThrow === true) {\r
+        throw new Error(message || 'Unknown error');\r
+    }\r
+\r
+    var stack = '';\r
+    if (!hideStack) {\r
+        stack = exports.displayStack(1).join('\n\t');\r
+    }\r
+    console.log('ABORT: ' + message + '\n\t' + stack);\r
+    process.exit(1);\r
+};\r
+\r
+\r
+exports.assert = function (condition /*, msg1, msg2, msg3 */) {\r
+\r
+    if (condition) {\r
+        return;\r
+    }\r
+\r
+    var msgs = Array.prototype.slice.call(arguments, 1);\r
+    msgs = msgs.map(function (msg) {\r
+\r
+        return typeof msg === 'string' ? msg : msg instanceof Error ? msg.message : JSON.stringify(msg);\r
+    });\r
+    throw new Error(msgs.join(' ') || 'Unknown error');\r
+};\r
+\r
+\r
+exports.loadDirModules = function (path, excludeFiles, target) {      // target(filename, name, capName)\r
+\r
+    var exclude = {};\r
+    for (var i = 0, il = excludeFiles.length; i < il; ++i) {\r
+        exclude[excludeFiles[i] + '.js'] = true;\r
+    }\r
+\r
+    var files = Fs.readdirSync(path);\r
+    for (i = 0, il = files.length; i < il; ++i) {\r
+        var filename = files[i];\r
+        if (/\.js$/.test(filename) &&\r
+            !exclude[filename]) {\r
+\r
+            var name = filename.substr(0, filename.lastIndexOf('.'));\r
+            var capName = name.charAt(0).toUpperCase() + name.substr(1).toLowerCase();\r
+\r
+            if (typeof target !== 'function') {\r
+                target[capName] = require(path + '/' + name);\r
+            }\r
+            else {\r
+                target(path + '/' + name, name, capName);\r
+            }\r
+        }\r
+    }\r
+};\r
+\r
+\r
+exports.rename = function (obj, from, to) {\r
+\r
+    obj[to] = obj[from];\r
+    delete obj[from];\r
+};\r
+\r
+\r
+exports.Timer = function () {\r
+\r
+    this.reset();\r
+};\r
+\r
+\r
+exports.Timer.prototype.reset = function () {\r
+\r
+    this.ts = Date.now();\r
+};\r
+\r
+\r
+exports.Timer.prototype.elapsed = function () {\r
+\r
+    return Date.now() - this.ts;\r
+};\r
+\r
+\r
+// Load and parse package.json process root or given directory\r
+\r
+exports.loadPackage = function (dir) {\r
+\r
+    var result = {};\r
+    var filepath = (dir || process.env.PWD) + '/package.json';\r
+    if (Fs.existsSync(filepath)) {\r
+        try {\r
+            result = JSON.parse(Fs.readFileSync(filepath));\r
+        }\r
+        catch (e) { }\r
+    }\r
+\r
+    return result;\r
+};\r
+\r
+\r
+// Escape string for Regex construction\r
+\r
+exports.escapeRegex = function (string) {\r
+\r
+    // Escape ^$.*+-?=!:|\/()[]{},\r
+    return string.replace(/[\^\$\.\*\+\-\?\=\!\:\|\\\/\(\)\[\]\{\}\,]/g, '\\$&');\r
+};\r
+\r
+\r
+// Return an error as first argument of a callback\r
+\r
+exports.toss = function (condition /*, [message], next */) {\r
+\r
+    var message = (arguments.length === 3 ? arguments[1] : '');\r
+    var next = (arguments.length === 3 ? arguments[2] : arguments[1]);\r
+\r
+    var err = (message instanceof Error ? message : (message ? new Error(message) : (condition instanceof Error ? condition : new Error())));\r
+\r
+    if (condition instanceof Error ||\r
+        !condition) {\r
+\r
+        return next(err);\r
+    }\r
+};\r
+\r
+\r
+// Base64url (RFC 4648) encode\r
+\r
+exports.base64urlEncode = function (value) {\r
+\r
+    return (new Buffer(value, 'binary')).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');\r
+};\r
+\r
+\r
+// Base64url (RFC 4648) decode\r
+\r
+exports.base64urlDecode = function (encoded) {\r
+\r
+    if (encoded &&\r
+        !encoded.match(/^[\w\-]*$/)) {\r
+\r
+        return new Error('Invalid character');\r
+    }\r
+\r
+    try {\r
+        return (new Buffer(encoded.replace(/-/g, '+').replace(/:/g, '/'), 'base64')).toString('binary');\r
+    }\r
+    catch (err) {\r
+        return err;\r
+    }\r
+};\r
+\r
+\r
+// Escape attribute value for use in HTTP header\r
+\r
+exports.escapeHeaderAttribute = function (attribute) {\r
+\r
+    // Allowed value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9, \, "\r
+\r
+    exports.assert(attribute.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~\"\\]*$/), 'Bad attribute value (' + attribute + ')');\r
+\r
+    return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"');                             // Escape quotes and slash\r
+};\r
+\r
+\r
+exports.escapeHtml = function (string) {\r
+\r
+    return Escape.escapeHtml(string);\r
+};\r
+\r
+\r
+exports.escapeJavaScript = function (string) {\r
+\r
+    return Escape.escapeJavaScript(string);\r
+};\r
+\r
+\r
+/*\r
+var event = {\r
+    timestamp: now.getTime(),\r
+    tags: ['tag'],\r
+    data: { some: 'data' }\r
+};\r
+*/\r
+\r
+exports.consoleFunc = console.log;\r
+\r
+exports.printEvent = function (event) {\r
+\r
+    var pad = function (value) {\r
+\r
+        return (value < 10 ? '0' : '') + value;\r
+    };\r
+\r
+    var now = new Date(event.timestamp);\r
+    var timestring = (now.getYear() - 100).toString() +\r
+        pad(now.getMonth() + 1) +\r
+        pad(now.getDate()) +\r
+        '/' +\r
+        pad(now.getHours()) +\r
+        pad(now.getMinutes()) +\r
+        pad(now.getSeconds()) +\r
+        '.' +\r
+        now.getMilliseconds();\r
+\r
+    var data = event.data;\r
+    if (typeof event.data !== 'string') {\r
+        try {\r
+            data = JSON.stringify(event.data);\r
+        }\r
+        catch (e) {\r
+            data = 'JSON Error: ' + e.message;\r
+        }\r
+    }\r
+\r
+    var output = timestring + ', ' + event.tags[0] + ', ' + data;\r
+    exports.consoleFunc(output);\r
+};\r
+\r
+\r
+exports.nextTick = function (callback) {\r
+\r
+    return function () {\r
+\r
+        var args = arguments;\r
+        process.nextTick(function () {\r
+\r
+            callback.apply(null, args);\r
+        });\r
+    };\r
+};\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/package.json b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/package.json
new file mode 100755 (executable)
index 0000000..152a5de
--- /dev/null
@@ -0,0 +1,52 @@
+{
+  "name": "hoek",
+  "description": "General purpose node utilities",
+  "version": "0.9.1",
+  "author": {
+    "name": "Eran Hammer",
+    "email": "eran@hueniverse.com",
+    "url": "http://hueniverse.com"
+  },
+  "contributors": [
+    {
+      "name": "Van Nguyen",
+      "email": "the.gol.effect@gmail.com"
+    }
+  ],
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/spumko/hoek"
+  },
+  "main": "index",
+  "keywords": [
+    "utilities"
+  ],
+  "engines": {
+    "node": ">=0.8.0"
+  },
+  "dependencies": {},
+  "devDependencies": {
+    "lab": "0.1.x",
+    "complexity-report": "0.x.x"
+  },
+  "scripts": {
+    "test": "make test-cov"
+  },
+  "licenses": [
+    {
+      "type": "BSD",
+      "url": "http://github.com/spumko/hoek/raw/master/LICENSE"
+    }
+  ],
+  "readme": "<a href=\"https://github.com/spumko\"><img src=\"https://raw.github.com/spumko/spumko/master/images/from.png\" align=\"right\" /></a>\r\n![hoek Logo](https://raw.github.com/spumko/hoek/master/images/hoek.png)\r\n\r\nGeneral purpose node utilities\r\n\r\n[![Build Status](https://secure.travis-ci.org/spumko/hoek.png)](http://travis-ci.org/spumko/hoek)\r\n\r\n# Table of Contents\r\n\r\n* [Introduction](#introduction \"Introduction\")\r\n* [Object](#object \"Object\")\r\n  * [clone](#cloneobj \"clone\")\r\n  * [merge](#mergetarget-source-isnulloverride-ismergearrays \"merge\")\r\n  * [applyToDefaults](#applytodefaultsdefaults-options \"applyToDefaults\")\r\n  * [unique](#uniquearray-key \"unique\")\r\n  * [mapToObject](#maptoobjectarray-key \"mapToObject\")\r\n  * [intersect](#intersectarray1-array2 \"intersect\")\r\n  * [matchKeys](#matchkeysobj-keys \"matchKeys\")\r\n  * [flatten](#flattenarray-target \"flatten\")\r\n  * [removeKeys](#removekeysobject-keys \"removeKeys\")\r\n  * [reach](#reachobj-chain \"reach\")\r\n  * [inheritAsync](#inheritasyncself-obj-keys \"inheritAsync\")\r\n  * [rename](#renameobj-from-to \"rename\")\r\n* [Timer](#timer \"Timer\")\r\n* [Binary Encoding/Decoding](#binary \"Binary Encoding/Decoding\")\r\n  * [base64urlEncode](#binary64urlEncodevalue \"binary64urlEncode\")\r\n  * [base64urlDecode](#binary64urlDecodevalue \"binary64urlDecode\")\r\n* [Escaping Characters](#escaped \"Escaping Characters\")\r\n  * [escapeHtml](#escapeHtmlstring \"escapeHtml\")\r\n  * [escapeHeaderAttribute](#escapeHeaderAttributeattribute \"escapeHeaderAttribute\")\r\n  * [escapeRegex](#escapeRegexstring \"escapeRegex\")\r\n* [Errors](#errors \"Errors\")\r\n  * [assert](#assertmessage \"assert\")\r\n  * [abort](#abortmessage \"abort\")\r\n  * [displayStack](#displayStackslice \"displayStack\")\r\n  * [callStack](#callStackslice \"callStack\")\r\n  * [toss](#tosscondition \"toss\")\r\n* [Load files](#load-files \"Load Files\")\r\n  * [loadPackage](#loadPackagedir \"loadpackage\")\r\n  * [loadDirModules](#loadDirModulespath-excludefiles-target \"loaddirmodules\")\r\n\r\n\r\n\r\n# Introduction\r\n\r\nThe *Hoek* general purpose node utilities library is used to aid in a variety of manners. It comes with useful methods for Arrays (clone, merge, applyToDefaults), Objects (removeKeys, copy), Asserting and more. \r\n\r\nFor example, to use Hoek to set configuration with default options:\r\n```javascript\r\nvar Hoek = require('hoek');\r\n\r\nvar default = {url : \"www.github.com\", port : \"8000\", debug : true}\r\n\r\nvar config = Hoek.applyToDefaults(default, {port : \"3000\", admin : true});\r\n\r\n// In this case, config would be { url: 'www.github.com', port: '3000', debug: true, admin: true }\r\n```\r\n\r\nUnder each of the sections (such as Array), there are subsections which correspond to Hoek methods. Each subsection will explain how to use the corresponding method. In each js excerpt below, the var Hoek = require('hoek') is omitted for brevity.\r\n\r\n## Object\r\n\r\nHoek provides several helpful methods for objects and arrays.\r\n\r\n### clone(obj)\r\n\r\nThis method is used to clone an object or an array. A *deep copy* is made (duplicates everything, including values that are objects). \r\n\r\n```javascript\r\n\r\nvar nestedObj = {\r\n        w: /^something$/ig,\r\n        x: {\r\n            a: [1, 2, 3],\r\n            b: 123456,\r\n            c: new Date()\r\n        },\r\n        y: 'y',\r\n        z: new Date()\r\n    };\r\n\r\nvar copy = Hoek.clone(nestedObj);\r\n\r\ncopy.x.b = 100;\r\n\r\nconsole.log(copy.y)        // results in 'y'\r\nconsole.log(nestedObj.x.b) // results in 123456\r\nconsole.log(copy.x.b)      // results in 100\r\n```\r\n\r\n### merge(target, source, isNullOverride, isMergeArrays)\r\nisNullOverride, isMergeArrays default to true\r\n\r\nMerge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied\r\n\r\n\r\n```javascript\r\n\r\nvar target = {a: 1, b : 2}\r\nvar source = {a: 0, c: 5}\r\nvar source2 = {a: null, c: 5}\r\n\r\nvar targetArray = [1, 2, 3];\r\nvar sourceArray = [4, 5];\r\n\r\nvar newTarget = Hoek.merge(target, source);     // results in {a: 0, b: 2, c: 5}\r\nnewTarget = Hoek.merge(target, source2);        // results in {a: null, b: 2, c: 5}\r\nnewTarget = Hoek.merge(target, source2, false); // results in {a: 1, b: 2, c: 5}\r\n\r\nnewTarget = Hoek.merge(targetArray, sourceArray)              // results in [1, 2, 3, 4, 5]\r\nnewTarget = Hoek.merge(targetArray, sourceArray, true, false) // results in [4, 5]\r\n\r\n\r\n\r\n\r\n```\r\n\r\n### applyToDefaults(defaults, options)\r\n\r\nApply options to a copy of the defaults\r\n\r\n```javascript\r\n\r\nvar defaults = {host: \"localhost\", port: 8000};\r\nvar options = {port: 8080};\r\n\r\nvar config = Hoek.applyToDefaults(defaults, options); // results in {host: \"localhost\", port: 8080};\r\n\r\n\r\n```\r\n\r\n### unique(array, key)\r\n\r\nRemove duplicate items from Array\r\n\r\n```javascript\r\n\r\nvar array = [1, 2, 2, 3, 3, 4, 5, 6];\r\n\r\nvar newArray = Hoek.unique(array); // results in [1,2,3,4,5,6];\r\n\r\narray = [{id: 1}, {id: 1}, {id: 2}];\r\n\r\nnewArray = Hoek.unique(array, \"id\") // results in [{id: 1}, {id: 2}]\r\n\r\n```\r\n\r\n### mapToObject(array, key)\r\n\r\nConvert an Array into an Object\r\n\r\n```javascript\r\n\r\nvar array = [1,2,3];\r\nvar newObject = Hoek.mapToObject(array); // results in [{\"1\": true}, {\"2\": true}, {\"3\": true}]\r\n\r\narray = [{id: 1}, {id: 2}];\r\nnewObject = Hoek.mapToObject(array, \"id\") // results in [{\"id\": 1}, {\"id\": 2}]\r\n\r\n```\r\n### intersect(array1, array2)\r\n\r\nFind the common unique items in two arrays\r\n\r\n```javascript\r\n\r\nvar array1 = [1, 2, 3];\r\nvar array2 = [1, 4, 5];\r\n\r\nvar newArray = Hoek.intersect(array1, array2) // results in [1]\r\n\r\n```\r\n\r\n### matchKeys(obj, keys) \r\n\r\nFind which keys are present\r\n\r\n```javascript\r\n\r\nvar obj = {a: 1, b: 2, c: 3};\r\nvar keys = [\"a\", \"e\"];\r\n\r\nHoek.matchKeys(obj, keys) // returns [\"a\"]\r\n\r\n```\r\n\r\n### flatten(array, target)\r\n\r\nFlatten an array\r\n\r\n```javascript\r\n\r\nvar array = [1, 2, 3];\r\nvar target = [4, 5]; \r\n\r\nvar flattenedArray = Hoek.flatten(array, target) // results in [4, 5, 1, 2, 3];\r\n\r\n```\r\n\r\n### removeKeys(object, keys)\r\n\r\nRemove keys\r\n\r\n```javascript\r\n\r\nvar object = {a: 1, b: 2, c: 3, d: 4};\r\n\r\nvar keys = [\"a\", \"b\"];\r\n\r\nHoek.removeKeys(object, keys) // object is now {c: 3, d: 4}\r\n\r\n```\r\n\r\n### reach(obj, chain)\r\n\r\nConverts an object key chain string to reference\r\n\r\n```javascript\r\n\r\nvar chain = 'a.b.c';\r\nvar obj = {a : {b : { c : 1}}};\r\n\r\nHoek.reach(obj, chain) // returns 1\r\n\r\n```\r\n\r\n### inheritAsync(self, obj, keys) \r\n\r\nInherits a selected set of methods from an object, wrapping functions in asynchronous syntax and catching errors\r\n\r\n```javascript\r\n\r\nvar targetFunc = function () { };\r\n\r\nvar proto = {\r\n                a: function () {\r\n                    return 'a!';\r\n                },\r\n                b: function () {\r\n                    return 'b!';\r\n                },\r\n                c: function () {\r\n                    throw new Error('c!');\r\n                }\r\n            };\r\n\r\nvar keys = ['a', 'c'];\r\n\r\nHoek.inheritAsync(targetFunc, proto, ['a', 'c']);\r\n\r\nvar target = new targetFunc();\r\n\r\ntarget.a(function(err, result){console.log(result)}         // returns 'a!'       \r\n\r\ntarget.c(function(err, result){console.log(result)}         // returns undefined\r\n\r\ntarget.b(function(err, result){console.log(result)}         // gives error: Object [object Object] has no method 'b'\r\n\r\n```\r\n\r\n### rename(obj, from, to)\r\n\r\nRename a key of an object\r\n\r\n```javascript\r\n\r\nvar obj = {a : 1, b : 2};\r\n\r\nHoek.rename(obj, \"a\", \"c\");     // obj is now {c : 1, b : 2}\r\n\r\n```\r\n\r\n\r\n# Timer\r\n\r\nA Timer object. Initializing a new timer object sets the ts to the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.\r\n\r\n```javascript\r\n\r\n\r\nexample : \r\n\r\n\r\nvar timerObj = new Hoek.Timer();\r\nconsole.log(\"Time is now: \" + timerObj.ts)\r\nconsole.log(\"Elapsed time from initialization: \" + timerObj.elapsed() + 'milliseconds')\r\n\r\n```\r\n\r\n# Binary Encoding/Decoding\r\n\r\n### base64urlEncode(value)\r\n\r\nEncodes value in Base64 or URL encoding\r\n\r\n### base64urlDecode(value)\r\n\r\nDecodes data in Base64 or URL encoding.\r\n# Escaping Characters\r\n\r\nHoek provides convenient methods for escaping html characters. The escaped characters are as followed:\r\n\r\n```javascript\r\n\r\ninternals.htmlEscaped = {\r\n    '&': '&amp;',\r\n    '<': '&lt;',\r\n    '>': '&gt;',\r\n    '\"': '&quot;',\r\n    \"'\": '&#x27;',\r\n    '`': '&#x60;'\r\n};\r\n\r\n```\r\n\r\n### escapeHtml(string)\r\n\r\n```javascript\r\n\r\nvar string = '<html> hey </html>';\r\nvar escapedString = Hoek.escapeHtml(string); // returns &lt;html&gt; hey &lt;/html&gt;\r\n\r\n```\r\n\r\n### escapeHeaderAttribute(attribute)\r\n\r\nEscape attribute value for use in HTTP header\r\n\r\n```javascript\r\n\r\nvar a = Hoek.escapeHeaderAttribute('I said \"go w\\\\o me\"');  //returns I said \\\"go w\\\\o me\\\"\r\n\r\n\r\n```\r\n\r\n\r\n### escapeRegex(string)\r\n\r\nEscape string for Regex construction\r\n\r\n```javascript\r\n\r\nvar a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\\\/`\"(>)[<]d{}s,');  // returns 4\\^f\\$s\\.4\\*5\\+\\-_\\?%\\=#\\!\\:@\\|~\\\\\\/`\"\\(>\\)\\[<\\]d\\{\\}s\\,\r\n\r\n\r\n\r\n```\r\n\r\n# Errors\r\n\r\n### assert(message)\r\n\r\n```javascript\r\n\r\nvar a = 1, b =2;\r\n\r\nHoek.assert(a === b, 'a should equal b');  // ABORT: a should equal b\r\n\r\n```\r\n\r\n### abort(message)\r\n\r\nFirst checks if process.env.NODE_ENV === 'test', and if so, throws error message. Otherwise,\r\ndisplays most recent stack and then exits process.\r\n\r\n\r\n\r\n### displayStack(slice)\r\n\r\nDisplays the trace stack\r\n\r\n```javascript\r\n\r\nvar stack = Hoek.displayStack();\r\nconsole.log(stack) // returns something like:\r\n\r\n[ 'null (/Users/user/Desktop/hoek/test.js:4:18)',\r\n  'Module._compile (module.js:449:26)',\r\n  'Module._extensions..js (module.js:467:10)',\r\n  'Module.load (module.js:356:32)',\r\n  'Module._load (module.js:312:12)',\r\n  'Module.runMain (module.js:492:10)',\r\n  'startup.processNextTick.process._tickCallback (node.js:244:9)' ]\r\n\r\n```\r\n\r\n### callStack(slice)\r\n\r\nReturns a trace stack array.\r\n\r\n```javascript\r\n\r\nvar stack = Hoek.callStack();\r\nconsole.log(stack)  // returns something like:\r\n\r\n[ [ '/Users/user/Desktop/hoek/test.js', 4, 18, null, false ],\r\n  [ 'module.js', 449, 26, 'Module._compile', false ],\r\n  [ 'module.js', 467, 10, 'Module._extensions..js', false ],\r\n  [ 'module.js', 356, 32, 'Module.load', false ],\r\n  [ 'module.js', 312, 12, 'Module._load', false ],\r\n  [ 'module.js', 492, 10, 'Module.runMain', false ],\r\n  [ 'node.js',\r\n    244,\r\n    9,\r\n    'startup.processNextTick.process._tickCallback',\r\n    false ] ]\r\n\r\n\r\n```\r\n\r\n### toss(condition)\r\n\r\ntoss(condition /*, [message], callback */)\r\n\r\nReturn an error as first argument of a callback\r\n\r\n\r\n# Load Files\r\n\r\n### loadPackage(dir)\r\n\r\nLoad and parse package.json process root or given directory\r\n\r\n```javascript\r\n\r\nvar pack = Hoek.loadPackage();  // pack.name === 'hoek'\r\n\r\n```\r\n\r\n### loadDirModules(path, excludeFiles, target) \r\n\r\nLoads modules from a given path; option to exclude files (array).\r\n\r\n\r\n\r\n\r\n",
+  "readmeFilename": "README.md",
+  "bugs": {
+    "url": "https://github.com/spumko/hoek/issues"
+  },
+  "_id": "hoek@0.9.1",
+  "dist": {
+    "shasum": "396f2118033eabc93ae5c2cd6ca75f0a89c03592"
+  },
+  "_from": "hoek@0.9.x",
+  "_resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz"
+}
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/escaper.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/escaper.js
new file mode 100644 (file)
index 0000000..4dddd77
--- /dev/null
@@ -0,0 +1,86 @@
+// Load modules\r
+\r
+var Lab = require('lab');\r
+var Hoek = require('../lib');\r
+\r
+\r
+// Declare internals\r
+\r
+var internals = {};\r
+\r
+\r
+// Test shortcuts\r
+\r
+var expect = Lab.expect;\r
+var before = Lab.before;\r
+var after = Lab.after;\r
+var describe = Lab.experiment;\r
+var it = Lab.test;\r
+\r
+\r
+describe('Hoek', function () {\r
+\r
+    describe('#escapeJavaScript', function () {\r
+\r
+        it('encodes / characters', function (done) {\r
+\r
+            var encoded = Hoek.escapeJavaScript('<script>alert(1)</script>');\r
+            expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e');\r
+            done();\r
+        });\r
+\r
+        it('encodes \' characters', function (done) {\r
+\r
+            var encoded = Hoek.escapeJavaScript('something(\'param\')');\r
+            expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29');\r
+            done();\r
+        });\r
+\r
+        it('encodes large unicode characters with the correct padding', function (done) {\r
+\r
+            var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000));\r
+            expect(encoded).to.equal('\\u0500\\u1000');\r
+            done();\r
+        });\r
+\r
+        it('doesn\'t throw an exception when passed null', function (done) {\r
+\r
+            var encoded = Hoek.escapeJavaScript(null);\r
+            expect(encoded).to.equal('');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#escapeHtml', function () {\r
+\r
+        it('encodes / characters', function (done) {\r
+\r
+            var encoded = Hoek.escapeHtml('<script>alert(1)</script>');\r
+            expect(encoded).to.equal('&lt;script&gt;alert&#x28;1&#x29;&lt;&#x2f;script&gt;');\r
+            done();\r
+        });\r
+\r
+        it('encodes < and > as named characters', function (done) {\r
+\r
+            var encoded = Hoek.escapeHtml('<script><>');\r
+            expect(encoded).to.equal('&lt;script&gt;&lt;&gt;');\r
+            done();\r
+        });\r
+\r
+        it('encodes large unicode characters', function (done) {\r
+\r
+            var encoded = Hoek.escapeHtml(String.fromCharCode(500) + String.fromCharCode(1000));\r
+            expect(encoded).to.equal('&#500;&#1000;');\r
+            done();\r
+        });\r
+\r
+        it('doesn\'t throw an exception when passed null', function (done) {\r
+\r
+            var encoded = Hoek.escapeHtml(null);\r
+            expect(encoded).to.equal('');\r
+            done();\r
+        });\r
+    });\r
+});\r
+\r
+\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/index.js
new file mode 100755 (executable)
index 0000000..c40e3ad
--- /dev/null
@@ -0,0 +1,1078 @@
+// Load modules\r
+\r
+var Lab = require('lab');\r
+var Hoek = require('../lib');\r
+\r
+\r
+// Declare internals\r
+\r
+var internals = {};\r
+\r
+\r
+// Test shortcuts\r
+\r
+var expect = Lab.expect;\r
+var before = Lab.before;\r
+var after = Lab.after;\r
+var describe = Lab.experiment;\r
+var it = Lab.test;\r
+\r
+\r
+describe('Hoek', function () {\r
+\r
+    var nestedObj = {\r
+        v: [7,8,9],\r
+        w: /^something$/igm,\r
+        x: {\r
+            a: [1, 2, 3],\r
+            b: 123456,\r
+            c: new Date(),\r
+            d: /hi/igm,\r
+            e: /hello/\r
+        },\r
+        y: 'y',\r
+        z: new Date()\r
+    };\r
+\r
+    var dupsArray = [nestedObj, { z: 'z' }, nestedObj];\r
+    var reducedDupsArray = [nestedObj, { z: 'z' }];\r
+\r
+    describe('#clone', function () {\r
+\r
+        it('should clone a nested object', function (done) {\r
+\r
+            var a = nestedObj;\r
+            var b = Hoek.clone(a);\r
+\r
+            expect(a).to.deep.equal(b);\r
+            expect(a.z.getTime()).to.equal(b.z.getTime());\r
+            done();\r
+        });\r
+\r
+        it('should clone a null object', function (done) {\r
+\r
+            var b = Hoek.clone(null);\r
+\r
+            expect(b).to.equal(null);\r
+            done();\r
+        });\r
+\r
+        it('should not convert undefined properties to null', function (done) {\r
+\r
+            var obj = { something: undefined };\r
+            var b = Hoek.clone(obj);\r
+\r
+            expect(typeof b.something).to.equal('undefined');\r
+            done();\r
+        });\r
+\r
+        it('should not throw on circular reference', function (done) {\r
+\r
+            var a = {};\r
+            a.x = a;\r
+\r
+            var test = (function () {\r
+\r
+                var b = Hoek.clone(a);\r
+            });\r
+\r
+            expect(test).to.not.throw();\r
+            done();\r
+        });\r
+\r
+        it('should properly clone circular reference', function (done) {\r
+\r
+            var x = {\r
+                'z': new Date()\r
+            };\r
+            x.y = x;\r
+\r
+            var b = Hoek.clone(x);\r
+            expect(Object.keys(b.y)).to.deep.equal(Object.keys(x))\r
+            expect(b.z).to.not.equal(x.z);\r
+            expect(b.y).to.not.equal(x.y);\r
+            expect(b.y.z).to.not.equal(x.y.z);\r
+            expect(b.y).to.equal(b);\r
+            expect(b.y.y.y.y).to.equal(b);\r
+            done();\r
+        });\r
+\r
+        it('should properly clone deeply nested object', function (done) {\r
+\r
+            var a = {\r
+                x: {\r
+                    y: {\r
+                        a: [1, 2, 3],\r
+                        b: 123456,\r
+                        c: new Date(),\r
+                        d: /hi/igm,\r
+                        e: /hello/\r
+                    },\r
+                }\r
+            };\r
+\r
+            var b = Hoek.clone(a);\r
+\r
+            expect(a).to.deep.equal(b);\r
+            expect(a.x.y.c.getTime()).to.equal(b.x.y.c.getTime());\r
+            done();\r
+        });\r
+\r
+        it('should properly clone arrays', function (done) {\r
+\r
+            var a = [1,2,3];\r
+\r
+            var b = Hoek.clone(a);\r
+\r
+            expect(a).to.deep.equal(b);\r
+            done();\r
+        });\r
+\r
+        it('should perform actual copy for shallow keys (no pass by reference)', function (done) {\r
+\r
+            var x = Hoek.clone(nestedObj);\r
+            var y = Hoek.clone(nestedObj);\r
+\r
+            // Date\r
+            expect(x.z).to.not.equal(nestedObj.z);\r
+            expect(x.z).to.not.equal(y.z);\r
+\r
+            // Regex\r
+            expect(x.w).to.not.equal(nestedObj.w);\r
+            expect(x.w).to.not.equal(y.w);\r
+\r
+            // Array\r
+            expect(x.v).to.not.equal(nestedObj.v);\r
+            expect(x.v).to.not.equal(y.v);\r
+\r
+            // Immutable(s)\r
+            x.y = 5;\r
+            expect(x.y).to.not.equal(nestedObj.y);\r
+            expect(x.y).to.not.equal(y.y);\r
+\r
+            done();\r
+        });\r
+\r
+        it('should perform actual copy for deep keys (no pass by reference)', function (done) {\r
+\r
+            var x = Hoek.clone(nestedObj);\r
+            var y = Hoek.clone(nestedObj);\r
+\r
+            expect(x.x.c).to.not.equal(nestedObj.x.c);\r
+            expect(x.x.c).to.not.equal(y.x.c);\r
+\r
+            expect(x.x.c.getTime()).to.equal(nestedObj.x.c.getTime());\r
+            expect(x.x.c.getTime()).to.equal(y.x.c.getTime());\r
+            done();\r
+        });\r
+\r
+        it('copies functions with properties', function (done) {\r
+\r
+            var a = {\r
+                x: function () { return 1; },\r
+                y: {}\r
+            };\r
+            a.x.z = 'string in function';\r
+            a.x.v = function () { return 2; };\r
+            a.y.u = a.x;\r
+\r
+            var b = Hoek.clone(a);\r
+            expect(b.x()).to.equal(1);\r
+            expect(b.x.v()).to.equal(2);\r
+            expect(b.y.u).to.equal(b.x);\r
+            expect(b.x.z).to.equal('string in function');\r
+            done();\r
+        });\r
+\r
+        it('should copy a buffer', function(done){\r
+            var tls = {\r
+                key: new Buffer([1,2,3,4,5]),\r
+                cert: new Buffer([1,2,3,4,5,6,10])\r
+            }\r
+\r
+            copiedTls = Hoek.clone(tls);\r
+            expect(Buffer.isBuffer(copiedTls.key)).to.equal(true);\r
+            expect(JSON.stringify(copiedTls.key)).to.equal(JSON.stringify(tls.key))\r
+            expect(Buffer.isBuffer(copiedTls.cert)).to.equal(true);\r
+            expect(JSON.stringify(copiedTls.cert)).to.equal(JSON.stringify(tls.cert))\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#merge', function () {\r
+\r
+        it('does not throw if source is null', function (done) {\r
+\r
+            var a = {};\r
+            var b = null;\r
+            var c = null;\r
+\r
+            expect(function () {\r
+\r
+                c = Hoek.merge(a, b);\r
+            }).to.not.throw();\r
+\r
+            expect(c).to.equal(a);\r
+            done();\r
+        });\r
+\r
+        it('does not throw if source is undefined', function (done) {\r
+\r
+            var a = {};\r
+            var b = undefined;\r
+            var c = null;\r
+\r
+            expect(function () {\r
+\r
+                c = Hoek.merge(a, b);\r
+            }).to.not.throw();\r
+\r
+            expect(c).to.equal(a);\r
+            done();\r
+        });\r
+\r
+        it('throws if source is not an object', function (done) {\r
+\r
+            expect(function () {\r
+\r
+                var a = {};\r
+                var b = 0;\r
+\r
+                Hoek.merge(a, b);\r
+            }).to.throw('Invalid source value: must be null, undefined, or an object');\r
+            done();\r
+        });\r
+\r
+        it('throws if target is not an object', function (done) {\r
+\r
+            expect(function () {\r
+\r
+                var a = 0;\r
+                var b = {};\r
+\r
+                Hoek.merge(a, b);\r
+            }).to.throw('Invalid target value: must be an object');\r
+            done();\r
+        });\r
+\r
+        it('throws if target is not an array and source is', function (done) {\r
+\r
+            expect(function () {\r
+\r
+                var a = {};\r
+                var b = [1, 2];\r
+\r
+                Hoek.merge(a, b);\r
+            }).to.throw('Cannot merge array onto an object');\r
+            done();\r
+        });\r
+\r
+        it('returns the same object when merging arrays', function (done) {\r
+\r
+            var a = [];\r
+            var b = [1, 2];\r
+\r
+            expect(Hoek.merge(a, b)).to.equal(a);\r
+            done();\r
+        });\r
+\r
+        it('should combine an empty object with a non-empty object', function (done) {\r
+\r
+            var a = {};\r
+            var b = nestedObj;\r
+\r
+            var c = Hoek.merge(a, b);\r
+            expect(a).to.deep.equal(b);\r
+            expect(c).to.deep.equal(b);\r
+            done();\r
+        });\r
+\r
+        it('should override values in target', function (done) {\r
+\r
+            var a = { x: 1, y: 2, z: 3, v: 5, t: 'test', m: 'abc' };\r
+            var b = { x: null, z: 4, v: 0, t: { u: 6 }, m: '123' };\r
+\r
+            var c = Hoek.merge(a, b);\r
+            expect(c.x).to.equal(null);\r
+            expect(c.y).to.equal(2);\r
+            expect(c.z).to.equal(4);\r
+            expect(c.v).to.equal(0);\r
+            expect(c.m).to.equal('123');\r
+            expect(c.t).to.deep.equal({ u: 6 });\r
+            done();\r
+        });\r
+\r
+        it('should override values in target (flip)', function (done) {\r
+\r
+            var a = { x: 1, y: 2, z: 3, v: 5, t: 'test', m: 'abc' };\r
+            var b = { x: null, z: 4, v: 0, t: { u: 6 }, m: '123' };\r
+\r
+            var d = Hoek.merge(b, a);\r
+            expect(d.x).to.equal(1);\r
+            expect(d.y).to.equal(2);\r
+            expect(d.z).to.equal(3);\r
+            expect(d.v).to.equal(5);\r
+            expect(d.m).to.equal('abc');\r
+            expect(d.t).to.deep.equal('test');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#applyToDefaults', function () {\r
+\r
+        var defaults = {\r
+            a: 1,\r
+            b: 2,\r
+            c: {\r
+                d: 3,\r
+                e: [5, 6]\r
+            },\r
+            f: 6,\r
+            g: 'test'\r
+        };\r
+\r
+        it('should return null if options is false', function (done) {\r
+\r
+            var result = Hoek.applyToDefaults(defaults, false);\r
+            expect(result).to.equal(null);\r
+            done();\r
+        });\r
+\r
+        it('should return a copy of defaults if options is true', function (done) {\r
+\r
+            var result = Hoek.applyToDefaults(defaults, true);\r
+            expect(result).to.deep.equal(result);\r
+            done();\r
+        });\r
+\r
+        it('should apply object to defaults', function (done) {\r
+\r
+            var obj = {\r
+                a: null,\r
+                c: {\r
+                    e: [4]\r
+                },\r
+                f: 0,\r
+                g: {\r
+                    h: 5\r
+                }\r
+            };\r
+\r
+            var result = Hoek.applyToDefaults(defaults, obj);\r
+            expect(result.c.e).to.deep.equal([4]);\r
+            expect(result.a).to.equal(1);\r
+            expect(result.b).to.equal(2);\r
+            expect(result.f).to.equal(0);\r
+            expect(result.g).to.deep.equal({ h: 5 });\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#unique', function () {\r
+\r
+        it('should ensure uniqueness within array of objects based on subkey', function (done) {\r
+\r
+            var a = Hoek.unique(dupsArray, 'x');\r
+            expect(a).to.deep.equal(reducedDupsArray);\r
+            done();\r
+        });\r
+\r
+        it('removes duplicated without key', function (done) {\r
+\r
+            expect(Hoek.unique([1, 2, 3, 4, 2, 1, 5])).to.deep.equal([1, 2, 3, 4, 5]);\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#mapToObject', function () {\r
+\r
+        it('should return null on null array', function (done) {\r
+\r
+            var a = Hoek.mapToObject(null);\r
+            expect(a).to.equal(null);\r
+            done();\r
+        });\r
+\r
+        it('should convert basic array to existential object', function (done) {\r
+\r
+            var keys = [1, 2, 3, 4];\r
+            var a = Hoek.mapToObject(keys);\r
+            for (var i in keys) {\r
+                expect(a[keys[i]]).to.equal(true);\r
+            }\r
+            done();\r
+        });\r
+\r
+        it('should convert array of objects to existential object', function (done) {\r
+\r
+            var keys = [{ x: 1 }, { x: 2 }, { x: 3 }];\r
+            var subkey = 'x';\r
+            var a = Hoek.mapToObject(keys, subkey);\r
+            for (var i in keys) {\r
+                expect(a[keys[i][subkey]]).to.equal(true);\r
+            }\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#intersect', function () {\r
+\r
+        it('should return the common objects of two arrays', function (done) {\r
+\r
+            var array1 = [1, 2, 3, 4, 4, 5, 5];\r
+            var array2 = [5, 4, 5, 6, 7];\r
+            var common = Hoek.intersect(array1, array2);\r
+            expect(common.length).to.equal(2);\r
+            done();\r
+        });\r
+\r
+        it('should return just the first common object of two arrays', function (done) {\r
+\r
+            var array1 = [1, 2, 3, 4, 4, 5, 5];\r
+            var array2 = [5, 4, 5, 6, 7];\r
+            var common = Hoek.intersect(array1, array2, true);\r
+            expect(common).to.equal(5);\r
+            done();\r
+        });\r
+\r
+        it('should return an empty array if either input is null', function (done) {\r
+\r
+            expect(Hoek.intersect([1], null).length).to.equal(0);\r
+            expect(Hoek.intersect(null, [1]).length).to.equal(0);\r
+            done();\r
+        });\r
+\r
+        it('should return the common objects of object and array', function (done) {\r
+\r
+            var array1 = [1, 2, 3, 4, 4, 5, 5];\r
+            var array2 = [5, 4, 5, 6, 7];\r
+            var common = Hoek.intersect(Hoek.mapToObject(array1), array2);\r
+            expect(common.length).to.equal(2);\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#matchKeys', function () {\r
+\r
+        it('should match the existing object keys', function (done) {\r
+\r
+            var obj = {\r
+                a: 1,\r
+                b: 2,\r
+                c: 3,\r
+                d: null\r
+            };\r
+\r
+            expect(Hoek.matchKeys(obj, ['b', 'c', 'd', 'e'])).to.deep.equal(['b', 'c', 'd']);\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#flatten', function () {\r
+\r
+        it('should return a flat array', function (done) {\r
+\r
+            var result = Hoek.flatten([1, 2, [3, 4, [5, 6], [7], 8], [9], [10, [11, 12]], 13]);\r
+            expect(result.length).to.equal(13);\r
+            expect(result).to.deep.equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#removeKeys', function () {\r
+\r
+        var objWithHiddenKeys = {\r
+            location: {\r
+                name: 'San Bruno'\r
+            },\r
+            company: {\r
+                name: '@WalmartLabs'\r
+            }\r
+        };\r
+\r
+        it('should delete params with definition\'s hide set to true', function (done) {\r
+\r
+            var a = Hoek.removeKeys(objWithHiddenKeys, ['location']);\r
+            expect(objWithHiddenKeys.location).to.not.exist;\r
+            expect(objWithHiddenKeys.company).to.exist;\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#reach', function () {\r
+\r
+        var obj = {\r
+            a: {\r
+                b: {\r
+                    c: {\r
+                        d: 1,\r
+                        e: 2\r
+                    },\r
+                    f: 'hello'\r
+                },\r
+                g: {\r
+                    h: 3\r
+                }\r
+            },\r
+            i: function () { }\r
+        };\r
+\r
+        it('returns a valid member', function (done) {\r
+\r
+            expect(Hoek.reach(obj, 'a.b.c.d')).to.equal(1);\r
+            done();\r
+        });\r
+\r
+        it('returns null on null object', function (done) {\r
+\r
+            expect(Hoek.reach(null, 'a.b.c.d')).to.not.exist;\r
+            done();\r
+        });\r
+\r
+        it('returns null on missing member', function (done) {\r
+\r
+            expect(Hoek.reach(obj, 'a.b.c.d.x')).to.not.exist;\r
+            done();\r
+        });\r
+\r
+        it('returns null on invalid member', function (done) {\r
+\r
+            expect(Hoek.reach(obj, 'a.b.c.d-.x')).to.not.exist;\r
+            done();\r
+        });\r
+\r
+        it('returns function member', function (done) {\r
+\r
+            expect(typeof Hoek.reach(obj, 'i')).to.equal('function');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#inheritAsync', function () {\r
+\r
+        it('should inherit selected methods and wrap in async call', function (done) {\r
+\r
+            var proto = {\r
+                a: function () {\r
+                    return 'a!';\r
+                },\r
+                b: function () {\r
+                    return 'b!';\r
+                },\r
+                c: function () {\r
+                    throw new Error('c!');\r
+                }\r
+            };\r
+\r
+            var targetFunc = function () { };\r
+            targetFunc.prototype.c = function () {\r
+\r
+                return 'oops';\r
+            };\r
+\r
+            Hoek.inheritAsync(targetFunc, proto, ['a', 'c']);\r
+            var target = new targetFunc();\r
+\r
+            expect(typeof target.a).to.equal('function');\r
+            expect(typeof target.c).to.equal('function');\r
+            expect(target.b).to.not.exist;\r
+\r
+            target.a(function (err, result) {\r
+\r
+                expect(err).to.not.exist;\r
+                expect(result).to.equal('a!');\r
+\r
+                target.c(function (err, result) {\r
+\r
+                    expect(result).to.not.exist;\r
+                    expect(err.message).to.equal('c!');\r
+                    done();\r
+                });\r
+            });\r
+        });\r
+    });\r
+\r
+    describe('#callStack', function () {\r
+\r
+        it('should return the full call stack', function (done) {\r
+\r
+            var stack = Hoek.callStack();\r
+            expect(stack[0][0]).to.contain('index.js');\r
+            expect(stack[0][2]).to.equal(30);\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#displayStack ', function () {\r
+\r
+        it('should return the full call stack for display', function (done) {\r
+\r
+            var stack = Hoek.displayStack();\r
+            expect(stack[0]).to.contain('test/index.js:');\r
+            done();\r
+        });\r
+\r
+        it('should include constructor functions correctly', function (done) {\r
+\r
+            var Something = function (next) {\r
+\r
+                next();\r
+            };\r
+\r
+            var something = new Something(function () {\r
+\r
+                var stack = Hoek.displayStack();\r
+                expect(stack[1]).to.contain('new Something');\r
+                done();\r
+            });\r
+        });\r
+    });\r
+\r
+    describe('#abort', function () {\r
+\r
+        it('should exit process when not in test mode', function (done) {\r
+\r
+            var env = process.env.NODE_ENV;\r
+            var write = process.stdout.write;\r
+            var exit = process.exit;\r
+\r
+            process.env.NODE_ENV = 'nottatest';\r
+            process.stdout.write = function () { };\r
+            process.exit = function (state) {\r
+\r
+                process.exit = exit;\r
+                process.env.NODE_ENV = env;\r
+                process.stdout.write = write;\r
+\r
+                expect(state).to.equal(1);\r
+                done();\r
+            };\r
+\r
+            Hoek.abort('Boom');\r
+        });\r
+\r
+        it('should throw when not in test mode and abortThrow is true', function (done) {\r
+\r
+            var env = process.env.NODE_ENV;\r
+            process.env.NODE_ENV = 'nottatest';\r
+            Hoek.abortThrow = true;\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.abort('my error message');\r
+            };\r
+\r
+            expect(fn).to.throw('my error message');\r
+            Hoek.abortThrow = false;\r
+            process.env.NODE_ENV = env;\r
+\r
+            done();\r
+        });\r
+\r
+\r
+        it('should respect hideStack argument', function (done) {\r
+\r
+            var env = process.env.NODE_ENV;\r
+            var write = process.stdout.write;\r
+            var exit = process.exit;\r
+            var output = '';\r
+\r
+            process.exit = function () { };\r
+            process.env.NODE_ENV = '';\r
+            process.stdout.write = function (message) {\r
+\r
+                output = message;\r
+            };\r
+\r
+            Hoek.abort('my error message', true);\r
+\r
+            process.env.NODE_ENV = env;\r
+            process.stdout.write = write;\r
+            process.exit = exit;\r
+\r
+            expect(output).to.equal('ABORT: my error message\n\t\n');\r
+\r
+            done();\r
+        });\r
+\r
+        it('should default to showing stack', function (done) {\r
+\r
+            var env = process.env.NODE_ENV;\r
+            var write = process.stdout.write;\r
+            var exit = process.exit;\r
+            var output = '';\r
+\r
+            process.exit = function () { };\r
+            process.env.NODE_ENV = '';\r
+            process.stdout.write = function (message) {\r
+\r
+                output = message;\r
+            };\r
+\r
+            Hoek.abort('my error message');\r
+\r
+            process.env.NODE_ENV = env;\r
+            process.stdout.write = write;\r
+            process.exit = exit;\r
+\r
+            expect(output).to.contain('index.js');\r
+\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#assert', function () {\r
+\r
+        it('should throw an Error when using assert in a test', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.assert(false, 'my error message');\r
+            };\r
+\r
+            expect(fn).to.throw('my error message');\r
+            done();\r
+        });\r
+\r
+        it('should throw an Error when using assert in a test with no message', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.assert(false);\r
+            };\r
+\r
+            expect(fn).to.throw('Unknown error');\r
+            done();\r
+        });\r
+\r
+        it('should throw an Error when using assert in a test with multipart message', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.assert(false, 'This', 'is', 'my message');\r
+            };\r
+\r
+            expect(fn).to.throw('This is my message');\r
+            done();\r
+        });\r
+\r
+        it('should throw an Error when using assert in a test with object message', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.assert(false, 'This', 'is', { spinal: 'tap' });\r
+            };\r
+\r
+            expect(fn).to.throw('This is {"spinal":"tap"}');\r
+            done();\r
+        });\r
+\r
+        it('should throw an Error when using assert in a test with error object message', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.assert(false, new Error('This is spinal tap'));\r
+            };\r
+\r
+            expect(fn).to.throw('This is spinal tap');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#loadDirModules', function () {\r
+\r
+        it('should load modules from directory', function (done) {\r
+\r
+            var target = {};\r
+            Hoek.loadDirModules(__dirname + '/modules', ['test2'], target);\r
+            expect(target.Test1.x).to.equal(1);\r
+            expect(target.Test2).to.not.exist;\r
+            expect(target.Test3.z).to.equal(3);\r
+            done();\r
+        });\r
+\r
+        it('should list modules from directory into function', function (done) {\r
+\r
+            var target = {};\r
+            Hoek.loadDirModules(__dirname + '/modules', ['test2'], function (path, name, capName) {\r
+\r
+                target[name] = capName;\r
+            });\r
+\r
+            expect(target.test1).to.equal('Test1');\r
+            expect(target.test2).to.not.exist;\r
+            expect(target.test3).to.equal('Test3');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#rename', function () {\r
+\r
+        it('should rename object key', function (done) {\r
+\r
+            var a = { b: 'c' };\r
+            Hoek.rename(a, 'b', 'x');\r
+            expect(a.b).to.not.exist;\r
+            expect(a.x).to.equal('c');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('Timer', function () {\r
+\r
+        it('should return time elapsed', function (done) {\r
+\r
+            var timer = new Hoek.Timer();\r
+            setTimeout(function () {\r
+\r
+                expect(timer.elapsed()).to.be.above(9);\r
+                done();\r
+            }, 12);\r
+        });\r
+    });\r
+\r
+    describe('#loadPackage', function () {\r
+\r
+        it('should', function (done) {\r
+\r
+            var pack = Hoek.loadPackage();\r
+            expect(pack.name).to.equal('hoek');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#escapeRegex', function () {\r
+\r
+        it('should escape all special regular expression characters', function (done) {\r
+\r
+            var a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\/`"(>)[<]d{}s,');\r
+            expect(a).to.equal('4\\^f\\$s\\.4\\*5\\+\\-_\\?%\\=#\\!\\:@\\|~\\\\\\/`"\\(>\\)\\[<\\]d\\{\\}s\\,');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#toss', function () {\r
+\r
+        it('should call callback with new error', function (done) {\r
+\r
+            var callback = function (err) {\r
+\r
+                expect(err).to.exist;\r
+                expect(err.message).to.equal('bug');\r
+                done();\r
+            };\r
+\r
+            Hoek.toss(true, 'feature', callback);\r
+            Hoek.toss(false, 'bug', callback);\r
+        });\r
+\r
+        it('should call callback with new error and no message', function (done) {\r
+\r
+            Hoek.toss(false, function (err) {\r
+\r
+                expect(err).to.exist;\r
+                expect(err.message).to.equal('');\r
+                done();\r
+            });\r
+        });\r
+\r
+        it('should call callback with error condition', function (done) {\r
+\r
+            Hoek.toss(new Error('boom'), function (err) {\r
+\r
+                expect(err).to.exist;\r
+                expect(err.message).to.equal('boom');\r
+                done();\r
+            });\r
+        });\r
+\r
+        it('should call callback with new error using message with error condition', function (done) {\r
+\r
+            Hoek.toss(new Error('ka'), 'boom', function (err) {\r
+\r
+                expect(err).to.exist;\r
+                expect(err.message).to.equal('boom');\r
+                done();\r
+            });\r
+        });\r
+\r
+        it('should call callback with new error using passed error with error condition', function (done) {\r
+\r
+            Hoek.toss(new Error('ka'), new Error('boom'), function (err) {\r
+\r
+                expect(err).to.exist;\r
+                expect(err.message).to.equal('boom');\r
+                done();\r
+            });\r
+        });\r
+    });\r
+\r
+    describe('Base64Url', function () {\r
+\r
+        var base64str = 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0-P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn-AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq-wsbKztLW2t7i5uru8vb6_wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t_g4eLj5OXm5-jp6uvs7e7v8PHy8_T19vf4-fr7_P3-_w';\r
+        var str = unescape('%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28%29*+%2C-./0123456789%3A%3B%3C%3D%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E%7F%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF');\r
+\r
+        describe('#base64urlEncode', function () {\r
+\r
+            it('should base64 URL-safe a string', function (done) {\r
+\r
+                expect(Hoek.base64urlEncode(str)).to.equal(base64str);\r
+                done();\r
+            });\r
+        });\r
+\r
+        describe('#base64urlDecode', function () {\r
+\r
+            it('should un-base64 URL-safe a string', function (done) {\r
+\r
+                expect(Hoek.base64urlDecode(base64str)).to.equal(str);\r
+                done();\r
+            });\r
+\r
+            it('should return error on undefined input', function (done) {\r
+\r
+                expect(Hoek.base64urlDecode().message).to.exist;\r
+                done();\r
+            });\r
+\r
+            it('should return error on invalid input', function (done) {\r
+\r
+                expect(Hoek.base64urlDecode('*').message).to.exist;\r
+                done();\r
+            });\r
+        });\r
+    });\r
+\r
+    describe('#escapeHeaderAttribute', function () {\r
+\r
+        it('should not alter ascii values', function (done) {\r
+\r
+            var a = Hoek.escapeHeaderAttribute('My Value');\r
+            expect(a).to.equal('My Value');\r
+            done();\r
+        });\r
+\r
+        it('should escape all special HTTP header attribute characters', function (done) {\r
+\r
+            var a = Hoek.escapeHeaderAttribute('I said go!!!#"' + String.fromCharCode(92));\r
+            expect(a).to.equal('I said go!!!#\\"\\\\');\r
+            done();\r
+        });\r
+\r
+        it('should throw on large unicode characters', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.escapeHeaderAttribute('this is a test' + String.fromCharCode(500) + String.fromCharCode(300));\r
+            };\r
+\r
+            expect(fn).to.throw(Error);\r
+            done();\r
+        });\r
+\r
+        it('should throw on CRLF to prevent response splitting', function (done) {\r
+\r
+            var fn = function () {\r
+\r
+                Hoek.escapeHeaderAttribute('this is a test\r\n');\r
+            };\r
+\r
+            expect(fn).to.throw(Error);\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#escapeHtml', function () {\r
+\r
+        it('should escape all special HTML characters', function (done) {\r
+\r
+            var a = Hoek.escapeHtml('&<>"\'`');\r
+            expect(a).to.equal('&amp;&lt;&gt;&quot;&#x27;&#x60;');\r
+            done();\r
+        });\r
+\r
+        it('should return empty string on falsy input', function (done) {\r
+\r
+            var a = Hoek.escapeHtml('');\r
+            expect(a).to.equal('');\r
+            done();\r
+        });\r
+\r
+        it('should return unchanged string on no reserved input', function (done) {\r
+\r
+            var a = Hoek.escapeHtml('abc');\r
+            expect(a).to.equal('abc');\r
+            done();\r
+        });\r
+    });\r
+\r
+    describe('#printEvent', function () {\r
+\r
+        it('outputs event as string', function (done) {\r
+\r
+            var event = {\r
+                timestamp: (new Date(2013, 1, 1, 6, 30, 45, 123)).getTime(),\r
+                tags: ['a', 'b', 'c'],\r
+                data: { some: 'data' }\r
+            };\r
+\r
+            Hoek.consoleFunc = function (string) {\r
+\r
+                Hoek.consoleFunc = console.log;\r
+                expect(string).to.equal('130201/063045.123, a, {"some":"data"}');\r
+                done();\r
+            };\r
+\r
+            Hoek.printEvent(event);\r
+        });\r
+\r
+        it('outputs JSON error', function (done) {\r
+\r
+            var event = {\r
+                timestamp: (new Date(2013, 1, 1, 6, 30, 45, 123)).getTime(),\r
+                tags: ['a', 'b', 'c'],\r
+                data: { some: 'data' }\r
+            };\r
+\r
+            event.data.a = event.data;\r
+\r
+            Hoek.consoleFunc = function (string) {\r
+\r
+                Hoek.consoleFunc = console.log;\r
+                expect(string).to.equal('130201/063045.123, a, JSON Error: Converting circular structure to JSON');\r
+                done();\r
+            };\r
+\r
+            Hoek.printEvent(event);\r
+        });\r
+    });\r
+\r
+    describe('#nextTick', function () {\r
+\r
+        it('calls the provided callback on nextTick', function (done) {\r
+\r
+            var a = 0;\r
+\r
+            var inc = function (step, next) {\r
+\r
+                a += step;\r
+                next();\r
+            };\r
+\r
+            var ticked = Hoek.nextTick(inc);\r
+\r
+            ticked(5, function () {\r
+\r
+                expect(a).to.equal(6);\r
+                done();\r
+            });\r
+\r
+            expect(a).to.equal(0);\r
+            inc(1, function () {\r
+\r
+                expect(a).to.equal(1);\r
+            });\r
+        });\r
+    });\r
+});\r
+\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test1.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test1.js
new file mode 100755 (executable)
index 0000000..3f41e60
--- /dev/null
@@ -0,0 +1 @@
+exports.x = 1;\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test2.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test2.js
new file mode 100755 (executable)
index 0000000..38556b2
--- /dev/null
@@ -0,0 +1 @@
+exports.y = 2;\r
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test3.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test3.js
new file mode 100755 (executable)
index 0000000..436b860
--- /dev/null
@@ -0,0 +1 @@
+exports.z = 3;\r
index 60f327b..baacddc 100755 (executable)
@@ -1,7 +1,7 @@
 {
   "name": "sntp",
   "description": "SNTP Client",
-  "version": "0.2.2",
+  "version": "0.2.4",
   "author": {
     "name": "Eran Hammer",
     "email": "eran@hueniverse.com",
@@ -22,7 +22,7 @@
     "node": ">=0.8.0"
   },
   "dependencies": {
-    "hoek": "0.8.x"
+    "hoek": "0.9.x"
   },
   "devDependencies": {
     "lab": "0.1.x",
       "url": "http://github.com/hueniverse/sntp/raw/master/LICENSE"
     }
   ],
-  "readme": "# sntp\r\n\r\nAn SNTP v4 client (RFC4330) for node. Simpy connects to the NTP or SNTP server requested and returns the server time\r\nalong with the roundtrip duration and clock offset. To adjust the local time to the NTP time, add the returned `t` offset\r\nto the local time.\r\n\r\n[![Build Status](https://secure.travis-ci.org/hueniverse/sntp.png)](http://travis-ci.org/hueniverse/sntp)\r\n\r\n# Usage\r\n\r\n```javascript\r\nvar Sntp = require('sntp');\r\n\r\n// All options are optional\r\n\r\nvar options = {\r\n    host: 'nist1-sj.ustiming.org',  // Defaults to pool.ntp.org\r\n    port: 123,                      // Defaults to 123 (NTP)\r\n    resolveReference: true,         // Default to false (not resolving)\r\n    timeout: 1000                   // Defaults to zero (no timeout)\r\n};\r\n\r\n// Request server time\r\n\r\nSntp.time(options, function (err, time) {\r\n\r\n    if (err) {\r\n        console.log('Failed: ' + err.message);\r\n        process.exit(1);\r\n    }\r\n\r\n    console.log('Local clock is off by: ' + time.t + ' milliseconds');\r\n    process.exit(0);\r\n});\r\n```\r\n\r\nIf an application needs to maintain continuous time synchronization, the module provides a stateful method for\r\nquerying the current offset only when the last one is too old (defaults to daily).\r\n\r\n```javascript\r\n// Request offset once\r\n\r\nSntp.offset(function (err, offset) {\r\n\r\n    console.log(offset);                    // New (served fresh)\r\n\r\n    // Request offset again\r\n\r\n    Sntp.offset(function (err, offset) {\r\n\r\n        console.log(offset);                // Identical (served from cache)\r\n    });\r\n});\r\n```\r\n\r\nTo set a background offset refresh, start the interval and use the provided now() method. If for any reason the\r\nclient fails to obtain an up-to-date offset, the current system clock is used.\r\n\r\n```javascript\r\nvar before = Sntp.now();                    // System time without offset\r\n\r\nSntp.start(function () {\r\n\r\n    var now = Sntp.now();                   // With offset\r\n    Sntp.stop();\r\n});\r\n```\r\n\r\n",
+  "readme": "# sntp\n\nAn SNTP v4 client (RFC4330) for node. Simpy connects to the NTP or SNTP server requested and returns the server time\nalong with the roundtrip duration and clock offset. To adjust the local time to the NTP time, add the returned `t` offset\nto the local time.\n\n[![Build Status](https://secure.travis-ci.org/hueniverse/sntp.png)](http://travis-ci.org/hueniverse/sntp)\n\n# Usage\n\n```javascript\nvar Sntp = require('sntp');\n\n// All options are optional\n\nvar options = {\n    host: 'nist1-sj.ustiming.org',  // Defaults to pool.ntp.org\n    port: 123,                      // Defaults to 123 (NTP)\n    resolveReference: true,         // Default to false (not resolving)\n    timeout: 1000                   // Defaults to zero (no timeout)\n};\n\n// Request server time\n\nSntp.time(options, function (err, time) {\n\n    if (err) {\n        console.log('Failed: ' + err.message);\n        process.exit(1);\n    }\n\n    console.log('Local clock is off by: ' + time.t + ' milliseconds');\n    process.exit(0);\n});\n```\n\nIf an application needs to maintain continuous time synchronization, the module provides a stateful method for\nquerying the current offset only when the last one is too old (defaults to daily).\n\n```javascript\n// Request offset once\n\nSntp.offset(function (err, offset) {\n\n    console.log(offset);                    // New (served fresh)\n\n    // Request offset again\n\n    Sntp.offset(function (err, offset) {\n\n        console.log(offset);                // Identical (served from cache)\n    });\n});\n```\n\nTo set a background offset refresh, start the interval and use the provided now() method. If for any reason the\nclient fails to obtain an up-to-date offset, the current system clock is used.\n\n```javascript\nvar before = Sntp.now();                    // System time without offset\n\nSntp.start(function () {\n\n    var now = Sntp.now();                   // With offset\n    Sntp.stop();\n});\n```\n\n",
   "readmeFilename": "README.md",
   "bugs": {
     "url": "https://github.com/hueniverse/sntp/issues"
   },
-  "_id": "sntp@0.2.2",
+  "_id": "sntp@0.2.4",
   "_from": "sntp@0.2.x"
 }
index 13bdb31..38a5534 100755 (executable)
@@ -64,7 +64,27 @@ describe('SNTP', function () {
             });
         });
 
-        it('times out on no response', function (done) {
+        it('errors on error event', function (done) {
+
+            var orig = Dgram.createSocket;
+            Dgram.createSocket = function (type) {
+
+                Dgram.createSocket = orig;
+                var socket = Dgram.createSocket(type);
+                process.nextTick(function () { socket.emit('error', new Error('Fake')) });
+                return socket;
+            };
+
+            Sntp.time(function (err, time) {
+
+                expect(err).to.exist;
+                expect(time).to.not.exist;
+                expect(err.message).to.equal('Fake');
+                done();
+            });
+        });
+
+        it('times out on invalid host', function (done) {
 
             Sntp.time({ host: 'error', timeout: 10000 }, function (err, time) {
 
index 8480bf6..590491e 100644 (file)
@@ -81,7 +81,11 @@ var isint = /^[0-9]+$/;
 function promote(parent, key) {
   if (parent[key].length == 0) return parent[key] = createObject();
   var t = createObject();
-  for (var i in parent[key]) t[i] = parent[key][i];
+  for (var i in parent[key]) {
+    if (hasOwnProperty.call(parent[key], i)) {
+      t[i] = parent[key][i];
+    }
+  }
   parent[key] = t;
   return t;
 }
@@ -155,7 +159,13 @@ function compact(obj) {
 
   if (isArray(obj)) {
     var ret = [];
-    for (var i in obj) ret.push(obj[i]);
+
+    for (var i in obj) {
+      if (hasOwnProperty.call(obj, i)) {
+        ret.push(obj[i]);
+      }
+    }
+
     return ret;
   }
 
index b23c424..d1475f9 100644 (file)
@@ -1,7 +1,7 @@
 {
   "name": "qs",
   "description": "querystring parser",
-  "version": "0.6.4",
+  "version": "0.6.5",
   "keywords": [
     "query string",
     "parser",
@@ -32,6 +32,6 @@
   "bugs": {
     "url": "https://github.com/visionmedia/node-querystring/issues"
   },
-  "_id": "qs@0.6.4",
+  "_id": "qs@0.6.5",
   "_from": "qs@~0.6.0"
 }
index 0befcd0..bab2bc4 100644 (file)
@@ -1,5 +1,5 @@
 {
-  "version": "1.2.23",
+  "version": "1.2.24",
   "name": "npm",
   "publishConfig": {
     "proprietary-attribs": false
@@ -51,7 +51,7 @@
     "mkdirp": "~0.3.3",
     "read": "~1.0.4",
     "lru-cache": "~2.3.0",
-    "node-gyp": "~0.9.5",
+    "node-gyp": "~0.9.6",
     "fstream-npm": "~0.1.3",
     "uid-number": "0",
     "archy": "0",
@@ -67,7 +67,7 @@
     "lockfile": "~0.3.2",
     "retry": "~0.6.0",
     "once": "~1.1.1",
-    "npmconf": "0",
+    "npmconf": "0.0.25",
     "opener": "~1.3.0",
     "chmodr": "~0.1.0",
     "cmd-shim": "~1.1.0",